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 / hif.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-23  |  28.4 KB  |  1,101 lines

  1. static char _[] = "@(#)hif.c    5.19 93/10/26 11:33:19, 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 part of the HIF kernel implemented using the
  30.  * host computer's operating system. This is invoked when a HIF_CALL message
  31.  * is received by MONTIP. This module uses the Debugger/Monitor on the 29K
  32.  * target for certain HIF services.
  33.  * The results are sent back to the 29K Target using a HIF_CALL_RTN message.
  34.  * If the Debugger is invoked, a GO message is sent first to switch the
  35.  * context from the Debugger to the HIF kernel, and then the HIF_CALL_RTN
  36.  * message is sent. 
  37.  *****************************************************************************
  38.  */
  39.  
  40. #include <stdio.h>
  41. #include <fcntl.h>
  42. #include <time.h>
  43. #include <errno.h>
  44. #include <memory.h>
  45. #include "types.h"
  46. #include "udiproc.h"
  47.  
  48. #include "hif.h"
  49.  
  50. #ifdef HAVE_STDLIB_H
  51. # include <stdlib.h>
  52. #endif 
  53. #ifdef HAVE_STRING_H
  54. # include <string.h>
  55. #else
  56. # include <strings.h>
  57. #endif
  58. #ifdef HAVE_UNISTD_H
  59. # include <unistd.h>
  60. #endif
  61.  
  62. #ifdef    MSDOS
  63. #include <io.h>
  64. #include <sys\types.h>
  65. #include <sys\timeb.h>
  66. #else
  67. #include <sys/types.h>
  68. #include <sys/file.h>
  69. #include <sys/timeb.h>
  70. #endif
  71.  
  72. #include "mtip.h"    /* access to version numbers, etc. */
  73. #include "messages.h"
  74.  
  75. INT32   UDI_write_string PARAMS((INT32, ADDR32, INT32, char *));
  76. INT32   UDI_read_string PARAMS((INT32, ADDR32, INT32, char *));
  77.  
  78. INT32   hif_exit PARAMS((UINT32 lr2));
  79. INT32   hif_open PARAMS((UINT32 lr2, UINT32 lr3, UINT32 lr4, UINT32 *gr96));
  80. INT32   hif_close PARAMS((UINT32 lr2, UINT32 *gr96));
  81. INT32   hif_read PARAMS((UINT32 lr2, UINT32 lr3, UINT32 lr4, UINT32 *gr96));
  82. INT32   hif_write PARAMS((UINT32 lr2, UINT32 lr3, UINT32 lr4, UINT32 *gr96));
  83. INT32   hif_lseek PARAMS((UINT32 lr2, UINT32 lr3, UINT32 lr4, UINT32 *gr96));
  84. INT32   hif_remove PARAMS((UINT32 lr2, UINT32 *gr96));
  85. INT32   hif_rename PARAMS((UINT32 lr2, UINT32 lr3, UINT32 *gr96));
  86. INT32   hif_ioctl PARAMS((UINT32 lr2, UINT32 lr3));
  87. INT32   hif_iowait PARAMS((UINT32 lr2, UINT32 lr3));
  88. INT32   hif_iostat PARAMS((UINT32 lr2, UINT32 *gr96));
  89. INT32   hif_tmpnam PARAMS((UINT32 lr2, UINT32 *gr96));
  90. INT32   hif_time PARAMS((UINT32 *gr96));
  91. INT32   hif_getenv PARAMS((UINT32 lr2, UINT32  lr3, UINT32 *gr96));
  92. INT32   hif_gettz PARAMS((UINT32 *gr96, UINT32 *gr97));
  93.  
  94.  
  95. #ifdef    MSDOS
  96. /* Stub out functions not available in MS-DOS */
  97. int   ioctl(int x, int y);
  98. int   ioctl(x, y) int x; int y; {return(0);}
  99. void  kbd_raw()     {return;}
  100. void  kbd_restore() {return;}
  101. #endif
  102.  
  103. /*
  104. ** Globals
  105. */
  106.  
  107. #define    TMP_BUF_SIZE    1024
  108.  
  109. static    char tmp_buffer[TMP_BUF_SIZE];
  110.  
  111. static    int    com_error;
  112.  
  113.  
  114. /*
  115. ** This function is the HIF service handler on the host. It receives
  116. ** the HIF system call message as its only parameter.  When
  117. ** complete, GR96, GR97 and GR121 should be set to appropriate
  118. ** values.  
  119. **
  120. */
  121.  
  122. INT32
  123. service_HIF(service_number, lr2, lr3, lr4, gr96, gr97, gr121)
  124. UINT32        service_number;
  125. UINT32        lr2, lr3, lr4;
  126. UINT32        *gr96, *gr97, *gr121;
  127.    {
  128.    INT32  result;
  129.  
  130.    com_error  = 0;    /* reset */
  131.    *gr121 = (UINT32) 0x80000000; /* success unless... */
  132.  
  133.    switch ((int) service_number) {
  134.       case HIF_exit:   result = hif_exit(lr2);
  135.                        break;
  136.       case HIF_open:   result = hif_open(lr2, lr3, lr4, gr96);
  137.                        break;
  138.       case HIF_close:  result = hif_close(lr2, gr96);
  139.                        break;
  140.       case HIF_read:   result = hif_read(lr2, lr3, lr4, gr96);
  141.                        break;
  142.       case HIF_write:  result = hif_write(lr2, lr3, lr4, gr96);
  143.                        break;
  144.       case HIF_remove: result = hif_remove(lr2, gr96);
  145.                        break;
  146.       case HIF_lseek:  result = hif_lseek(lr2, lr3, lr4, gr96);
  147.                        break;
  148.       case HIF_rename: result = hif_rename(lr2, lr3, gr96);
  149.                        break;
  150.       case HIF_ioctl:  result = hif_ioctl(lr2, lr3);
  151.                        break;
  152.       case HIF_iowait: result = hif_iowait(lr2, lr3);
  153.                        break;
  154.       case HIF_iostat: result = hif_iostat(lr2, gr96);
  155.                        break;
  156.       case HIF_tmpnam: result = hif_tmpnam(lr2, gr96);
  157.                        break;
  158.       case HIF_time:   result = hif_time(gr96);
  159.                        break;
  160.       case HIF_getenv: result = hif_getenv(lr2, lr3, gr96);
  161.                        break;
  162.       case HIF_gettz:  result = hif_gettz(gr96, gr97);
  163.                        break;
  164.       default:         *gr121 = (UINT32) HIF_EHIFUNDEF;
  165.             return (SUCCESS);
  166.       }
  167.  
  168.    /* Set gr121 if HIF error received */
  169.    if (result != (INT32) 0)
  170.       *gr121 = (UINT32) result;
  171.  
  172.    if (com_error) 
  173.      return ((INT32) -1);    /* FAILURE */
  174.    return(SUCCESS);
  175.  
  176.    }  /* end service_HIF() */
  177.  
  178.  
  179.  
  180.  
  181. /*
  182. ** HIF Services
  183. */
  184.  
  185.  
  186. /*
  187. ** Service 1 - exit
  188. **
  189. ** Type         Regs    Contents    Description
  190. ** ----         ----    --------    -----------
  191. ** Calling:    gr121    1 (0x01)    Service number
  192. **             lr2      exitcode    User-supplied exit code
  193. **
  194. ** Returns:    gr96     undefined   Service does not return
  195. **             gr121    undefined   Service does not return
  196. **
  197. */
  198.  
  199. /* ARGSUSED */
  200. INT32
  201. hif_exit(lr2)
  202. UINT32    lr2;
  203.    {
  204.    return (0);
  205.    }  /* end hif_exit() */
  206.  
  207.  
  208. /*
  209. ** Service 17 - open
  210. **
  211. ** Type         Regs    Contents    Description
  212. ** ----         ----    --------    -----------
  213. ** Calling:    gr121    17 (0x11)   Service number
  214. **             lr2      pathname    Pointer to a filename
  215. **             lr3      mode        See HIF Specification
  216. **             lr4      pflag       See HIF Specification
  217. **
  218. ** Returns:    gr96     fileno      Success >= 0 (file descriptor)
  219. **                                  Failure <0
  220. **             gr121    0x80000000  Logical TRUE, service successful
  221. **                      errcode     error number, service not
  222. **                                  successful
  223. **
  224. */
  225.  
  226. INT32
  227. hif_open(lr2, lr3, lr4, gr96)
  228. UINT32    lr2, lr3, lr4;
  229. UINT32    *gr96;
  230.    {
  231.    INT32      result;
  232.    int      hif_mode;
  233.    int      host_mode;
  234.    int      hif_pflag;
  235.    int      fd;
  236.    ADDR32   pathptr;
  237.  
  238.  
  239.    pathptr = (ADDR32) lr2;
  240.    hif_pflag = (int) lr4;
  241.    hif_mode = (int) lr3;
  242.  
  243.    /*
  244.    ** Note:  The pflag is the same in BSD and MS-DOS.
  245.    ** Unfortunately, the O_* flags for HIF, UNIX and MS-DOS
  246.    ** are not the same.  So we have to do the folowing:
  247.    */
  248.  
  249.    host_mode = 0;
  250.    if ((hif_mode & HIF_RDONLY) != 0)
  251.       host_mode = host_mode | O_RDONLY;
  252.    if ((hif_mode & HIF_WRONLY) != 0)
  253.       host_mode = host_mode | O_WRONLY;
  254.    if ((hif_mode & HIF_RDWR) != 0)
  255.       host_mode = host_mode | O_RDWR;
  256.    if ((hif_mode & HIF_APPEND) != 0)
  257.       host_mode = host_mode | O_APPEND;
  258.    if ((hif_mode & HIF_NDELAY) != 0)
  259.       host_mode = host_mode | O_NDELAY;
  260.    if ((hif_mode & HIF_CREAT) != 0)
  261.       host_mode = host_mode | O_CREAT;
  262.    if ((hif_mode & HIF_TRUNC) != 0)
  263.       host_mode = host_mode | O_TRUNC;
  264.    if ((hif_mode & HIF_EXCL) != 0)
  265.       host_mode = host_mode | O_EXCL;
  266.    if ((hif_mode & HIF_FORM) != 0)
  267.       host_mode = host_mode | O_TEXT;
  268.       else
  269.          host_mode = host_mode | O_BINARY;
  270.  
  271.  
  272.    result = UDI_read_string((INT32) UDI29KDRAMSpace, 
  273.                         pathptr,
  274.                         (INT32) MAX_FILENAME,
  275.                         tmp_buffer);
  276.  
  277.    if (result != (INT32) 0) {
  278.       *gr96 = (UINT32) -1;
  279.       return((INT32) result);
  280.    }
  281.  
  282.    fd = open(tmp_buffer, host_mode, hif_pflag);
  283.  
  284.    *gr96 = (UINT32) fd;
  285.  
  286.    if (fd < 0)  /* open failed on host */
  287.       return((INT32) errno);
  288.  
  289.    return (0);
  290.    }  /* end hif_open() */
  291.  
  292.  
  293.  
  294. /*
  295. ** Service 18 - close
  296. **
  297. ** Type         Regs    Contents    Description
  298. ** ----         ----    --------    -----------
  299. ** Calling:    gr121    18 (0x12)   Service number
  300. **             lr2      fileno      File descriptor
  301. **
  302. ** Returns:    gr96     retval      Success = 0
  303. **                                  Failure < 0
  304. **             gr121    0x80000000  Logical TRUE, service successful
  305. **                      errcode     error number, service not
  306. **                                  successful
  307. */
  308.  
  309. INT32
  310. hif_close(lr2, gr96)
  311. UINT32    lr2;
  312. UINT32    *gr96;
  313.    {
  314.    int  file_no;
  315.    int  retval;
  316.  
  317.    file_no = (int) lr2;
  318.  
  319.  
  320.    /* Don't close stdin, stdout or stderr */
  321.    if (file_no == 0 ||
  322.        file_no == 1 ||
  323.        file_no == 2)
  324.       retval = 0;  /* Pretend we closed it */
  325.       else
  326.          retval = close(file_no);
  327.  
  328.    *gr96 = (UINT32) retval;
  329.  
  330.    if (retval < 0) 
  331.       return((INT32) errno);
  332.  
  333.    return (0);
  334.    }  /* end hif_close() */
  335.  
  336.  
  337.  
  338.  
  339. /*
  340. ** Service 19 - read
  341. **
  342. ** Type         Regs    Contents    Description
  343. ** ----         ----    --------    -----------
  344. ** Calling:    gr121    19 (0x13)   Service number
  345. **             lr2      fileno      File descriptor
  346. **             lr3      buffptr     A pointer to buffer area
  347. **             lr4      nbytes      Number of bytes to be read
  348. **
  349. ** Returns:    gr96     count       * See HIF spec
  350. **             gr121    0x80000000  Logical TRUE, service successful
  351. **                      errcode     error number, service not
  352. **                                  successful
  353. */
  354.  
  355. INT32
  356. hif_read(lr2, lr3, lr4, gr96)
  357. UINT32    lr2, lr3, lr4;
  358. UINT32    *gr96;
  359.    {
  360.    int     bytes_read;
  361.    int       file_no;
  362.    ADDR32    buffptr;
  363.    UINT32     nbytes;
  364.    UINT32     copy_count;
  365.    UINT32     total_bytes;
  366.    INT32       result;
  367.  
  368.    file_no = (int) lr2;
  369.    buffptr = (ADDR32) lr3;
  370.    nbytes = (UINT32) lr4;
  371.    total_bytes = (UINT32) 0;
  372.  
  373.  
  374.    while (nbytes > 0) {
  375.  
  376.       copy_count = (nbytes < (UINT32) TMP_BUF_SIZE) ? nbytes : (UINT32) TMP_BUF_SIZE;
  377.  
  378.       bytes_read = (int) read(file_no,
  379.                         (char *) tmp_buffer,
  380.                         (int) copy_count);
  381.  
  382.       if (bytes_read == (int) -1) {
  383.         *gr96 = total_bytes;
  384.          return((INT32) errno);
  385.       }
  386.  
  387.       /* Write data to target buffer */
  388.       result = UDI_write_string((INT32) UDI29KDRAMSpace,
  389.                             buffptr,
  390.                             (INT32) bytes_read,
  391.                             tmp_buffer);
  392.  
  393.       if (result != (INT32) 0) {
  394.         *gr96 = total_bytes;
  395.          return((INT32) result);
  396.       }
  397.  
  398.       total_bytes = total_bytes + (UINT32) bytes_read;
  399.       buffptr = buffptr + (UINT32) bytes_read;
  400.  
  401.       /* If bytes_read is the same a copy_count, keep reading */
  402.       if ((UINT32) bytes_read == copy_count)
  403.          nbytes = nbytes - (UINT32) bytes_read;
  404.          else
  405.             nbytes = 0;
  406.  
  407.    }  /* end while loop */
  408.  
  409.    *gr96 = total_bytes;
  410.    return (0);
  411.  
  412.    }  /* end hif_read() */
  413.  
  414.  
  415.  
  416. /*
  417. ** Service 20 - write
  418. **
  419. ** Type         Regs    Contents    Description
  420. ** ----         ----    --------    -----------
  421. ** Calling:    gr121    20 (0x14)   Service number
  422. **             lr2      fileno      File descriptor
  423. **             lr3      buffptr     A pointer to buffer area
  424. **             lr4      nbytes      Number of bytes to be read
  425. **
  426. ** Returns:    gr96     count       * See HIF spec
  427. **             gr121    0x80000000  Logical TRUE, service successful
  428. **                      errcode     error number, service not
  429. **                                  successful
  430. */
  431.  
  432. INT32
  433. hif_write(lr2, lr3, lr4, gr96)
  434. UINT32    lr2, lr3, lr4;
  435. UINT32    *gr96;
  436.     {
  437.     int     file_no;
  438.     ADDR32  buffptr;
  439.     UINT32   nbytes;
  440.     UINT32   copy_count;
  441.     UINT32   total_bytes;
  442.     int     bytes_written;
  443.     INT32     result;
  444.  
  445.    file_no = (int) lr2;
  446.    buffptr = (ADDR32) lr3;
  447.    nbytes = (UINT32) lr4;
  448.    total_bytes = (UINT32) 0;
  449.  
  450.  
  451.    /*   If we are writing channel 0, which is stdin
  452.     this is an error  */
  453.  
  454.    while (nbytes > (UINT32) 0) {
  455.  
  456.       copy_count = (nbytes < (UINT32) TMP_BUF_SIZE) ? nbytes : (UINT32) TMP_BUF_SIZE;
  457.  
  458.       result = UDI_read_string((UINT32) UDI29KDRAMSpace,
  459.                             buffptr,
  460.                             copy_count,
  461.                             tmp_buffer);
  462.  
  463.       if (result != (INT32) 0) {
  464.         *gr96 = total_bytes;
  465.          return(result);
  466.       }
  467.  
  468.       /* Write copy_count bytes to file_no */
  469.       bytes_written = write(file_no, tmp_buffer, (int) copy_count);
  470.  
  471.       if (bytes_written < 0) {
  472.         *gr96 = total_bytes;
  473.          return(errno);
  474.       }
  475.  
  476.       total_bytes = total_bytes + bytes_written;
  477.       buffptr = buffptr + bytes_written;
  478.       nbytes = nbytes - bytes_written;
  479.  
  480.    }  /* end while loop */
  481.  
  482.  
  483.    *gr96 = total_bytes;
  484.  
  485.    return (0);
  486.    }  /* end hif_write() */
  487.  
  488.  
  489.  
  490. /*
  491. ** Service 21 - lseek
  492. **
  493. ** Type         Regs    Contents    Description
  494. ** ----         ----    --------    -----------
  495. ** Calling:    gr121    21 (0x15)   Service number
  496. **             lr2      file_no      File descriptor
  497. **             lr3      offset      Number of bytes offset from orig
  498. **             lr4      orig        A code number indication the point
  499. **                                  within the file from which the
  500. **                                  offset is measured
  501. **
  502. ** Returns:    gr96     where       * See HIF spec
  503. **             gr121    0x80000000  Logical TRUE, service successful
  504. **                      errcode     error number, service not
  505. **                                  successful
  506. **
  507. ** Notes:  The defined constants for orig are different in MS-DOS
  508. **         and UNIX, but there is a 1-1 correspondence as follows:
  509. **
  510. **       Code  UNIX    MS-DOS    Meaning
  511. **       ----  ----    ------    -------
  512. **         0   L_SET   SEEK_SET  Beginning of file
  513. **         1   L_INCR  SEEK_CUR  Current file position
  514. **         2   L_XTNX  SEEK_END  End of file
  515. **
  516. */
  517.  
  518. INT32
  519. hif_lseek(lr2, lr3, lr4, gr96)
  520. UINT32    lr2, lr3, lr4;
  521. UINT32    *gr96;
  522.    {
  523.    int    file_no;
  524.    off_t  offset;
  525.    int    orig;
  526.    long   new_offset;
  527.  
  528.    file_no = (int) lr2;
  529.    offset = (off_t) lr3;
  530. #ifdef HAVE_UNISTD_H
  531.    if (lr4 == (UINT32) 0)
  532.      orig = SEEK_SET;
  533.    else if (lr4 == (UINT32) 1)
  534.      orig = SEEK_CUR;
  535.    else if (lr4 == (UINT32) 2)
  536.      orig = SEEK_END;
  537. #else
  538.    if (lr4 == (UINT32) 0)
  539.      orig = L_SET;
  540.    else if (lr4 == (UINT32) 1)
  541.      orig = L_INCR;
  542.    else if (lr4 == (UINT32) 2)
  543.      orig = L_XTND;
  544. #endif
  545.  
  546.    new_offset = lseek(file_no, offset, orig);
  547.  
  548.    *gr96 = (UINT32) new_offset;
  549.  
  550.    if (new_offset == (UINT32) -1)  /* failed */
  551.       return(errno);
  552.  
  553.    return (0);
  554.    }  /* end hif_lseek() */
  555.  
  556.  
  557.  
  558.  
  559. /*
  560. ** Service 22 - remove
  561. **
  562. ** Type         Regs    Contents    Description
  563. ** ----         ----    --------    -----------
  564. ** Calling:    gr121    22 (0x16)   Service number
  565. **             lr2      pathname    A pointer to string that contains
  566. **                                  the pathname of the file
  567. **
  568. ** Returns:    gr96     retval      Success = 0
  569. **                                  Failure < 0
  570. **             gr121    0x80000000  Logical TRUE, service successful
  571. **                      errcode     error number, service not
  572. **                                  successful
  573. */
  574.  
  575. INT32
  576. hif_remove(lr2, gr96)
  577. UINT32    lr2;
  578. UINT32    *gr96;
  579.    {
  580.    int      retval;
  581.    INT32      result;
  582.  
  583.  
  584.    result = UDI_read_string((INT32) UDI29KDRAMSpace,
  585.                         (ADDR32) lr2,
  586.                         (INT32) MAX_FILENAME,
  587.                         tmp_buffer);
  588.  
  589.    if (result != (INT32) 0) {
  590.      *gr96 = (UINT32) -1;
  591.       return(result);
  592.    }
  593.  
  594.    retval = unlink(tmp_buffer);
  595.  
  596.    if (retval != 0) {
  597.      *gr96 = (UINT32) -1;
  598.       return(errno);
  599.    }
  600.  
  601.    *gr96 = (UINT32) 0;
  602.    return (0);
  603.  
  604.    }  /* end hif_remove() */
  605.  
  606.  
  607.  
  608. /*
  609. ** Service 23 - rename
  610. **
  611. ** Type         Regs    Contents    Description
  612. ** ----         ----    --------    -----------
  613. ** Calling:    gr121    23 (0x17)   Service number
  614. **             lr2      oldfile     A pointer to string containing
  615. **                                  the old pathname of the file
  616. **             lr3      newfile     A pointer to string containing
  617. **                                  the new pathname of the file
  618. **
  619. ** Returns:    gr96     retval      Success = 0
  620. **                                  Failure < 0
  621. **             gr121    0x80000000  Logical TRUE, service successful
  622. **                      errcode     error number, service not
  623. **                                  successful
  624. */
  625.  
  626. INT32
  627. hif_rename(lr2, lr3, gr96)
  628. UINT32    lr2, lr3;
  629. UINT32    *gr96;
  630.    {
  631.    char     oldname[MAX_FILENAME];
  632.    int      retval;
  633.    INT32      result;
  634.  
  635.  
  636.    /* Get old filename */
  637.    result = UDI_read_string((INT32) UDI29KDRAMSpace,
  638.                         (ADDR32) lr2,
  639.                         (INT32) MAX_FILENAME,
  640.                         oldname);
  641.  
  642.    if (result != (INT32) 0) {
  643.       *gr96 = (UINT32) -1;
  644.       return(result);
  645.    }
  646.  
  647.    /* Get new filename */
  648.    result = UDI_read_string((INT32) UDI29KDRAMSpace,
  649.                         (ADDR32) lr3,
  650.                         (INT32) MAX_FILENAME,
  651.                         tmp_buffer);
  652.  
  653.    if (result != (INT32) 0) {
  654.       *gr96 = (UINT32) -1;
  655.       return(result);
  656.    }
  657.  
  658.    retval = rename(oldname, tmp_buffer);
  659.  
  660.    *gr96 = (UINT32) retval;
  661.  
  662.    if (retval < 0) {
  663.       return(errno);
  664.    }
  665.  
  666.  
  667.    return (0);
  668.  
  669.    }  /* end hif_rename() */
  670.  
  671.  
  672.  
  673. /*
  674. ** Service 24 - ioctl
  675. **
  676. ** Type         Regs    Contents    Description
  677. ** ----         ----    --------    -----------
  678. ** Calling:    gr121    24 (0x18)   Service number
  679. **             lr2      fileno      File descriptor number to be tested
  680. **             lr3      mode        Operating mode
  681. **
  682. ** Returns:    gr96     retval      Success = 0
  683. **                                  Failure < 0
  684. **             gr121    0x80000000  Logical TRUE, service successful
  685. **                      errcode     error number, service not
  686. **                                  successful
  687. **
  688. ** Note:  There is no equivalent to ioctl() in MS-DOS.  It is
  689. **        stubbed to return a zero.
  690. */
  691.  
  692. INT32
  693. hif_ioctl(lr2, lr3)
  694. UINT32    lr2, lr3;
  695.    {
  696.    int   des;
  697.    int   request;
  698.    int   result;
  699.  
  700.  
  701.    des = (int) lr2;
  702.    request = (int) lr3;
  703.  
  704.    result = ioctl(des, request);
  705.  
  706.    if (result == -1)
  707.       return(errno);
  708.  
  709.    return (0);
  710.  
  711.    }  /* end hif_ioctl() */
  712.  
  713.  
  714.  
  715. /*
  716. ** Service 25 - iowait
  717. **
  718. ** Type         Regs    Contents    Description
  719. ** ----         ----    --------    -----------
  720. ** Calling:    gr121    25 (0x19)   Service number
  721. **             lr2      fileno      File descriptor number to be tested
  722. **             lr3      mode        1 = non-blocking completion test
  723. **                                  2 = wait until read operation complete
  724. **
  725. ** Returns:    gr96     count       * see HIF spec
  726. **             gr121    0x80000000  Logical TRUE, service successful
  727. **                      errcode     error number, service not
  728. **                                  successful
  729. **
  730. ** Note:  As with ioctl(), there is no equivalent to iowait() in
  731. **        MS-DOS.  It is stubbed to return a zero.
  732. */
  733.  
  734. /* ARGSUSED */
  735. INT32
  736. hif_iowait(lr2, lr3)
  737. UINT32    lr2, lr3;
  738.    {
  739.    return (HIF_EHIFNOTAVAIL);
  740.    }  /* end hif_iowait() */
  741.  
  742.  
  743.  
  744. /*
  745. ** Service 26 - iostat
  746. **
  747. ** Type         Regs    Contents    Description
  748. ** ----         ----    --------    -----------
  749. ** Calling:    gr121    26 (0x20)   Service number
  750. **             lr2      fileno      File descriptor number to be tested
  751. **
  752. ** Returns:    gr96     iostat      input status
  753. **                                  0x0001 = RDREADY
  754. **                                  0x0002 = ISATTY
  755. **             gr121    0x80000000  Logical TRUE, service successful
  756. **                      errcode     error number, service not
  757. **                                  successful
  758. **
  759. ** Note:  Currently RDREADY is always returned as set.  This is
  760. **        ok for MS-DOS, but may cause problems in BSD UNIX.
  761. **
  762. */
  763.  
  764. /* ARGSUSED */
  765. INT32
  766. hif_iostat(lr2, gr96)
  767. UINT32    lr2;
  768. UINT32    *gr96;
  769.    {
  770.    UDIError  result;
  771.    UINT32  file_no;
  772.  
  773.  
  774.    *gr96 = (UINT32) RDREADY;
  775.  
  776.    file_no = lr2;
  777.  
  778.    result = (UDIError) isatty((int) file_no);
  779.  
  780.    if (result == (UDIError) 0)
  781.       *gr96 = (UINT32) (*gr96 | ISATTY);
  782.  
  783.    return (0);
  784.  
  785.    }  /* end hif_iostat() */
  786.  
  787.  
  788. /*
  789. ** Service 33 - tmpnam
  790. **
  791. ** Type         Regs    Contents    Description
  792. ** ----         ----    --------    -----------
  793. ** Calling:    gr121    33 (0x21)   Service number
  794. **             lr2      addrptr     Pointer into which filename is
  795. **                                  to be stored
  796. **
  797. ** Returns:    gr96     filename    Success: pointer to temporary
  798. **                                  filename string.  This will be
  799. **                                  the same as lr2 on entry unless
  800. **                                  an error occurred
  801. **                                  Failure: = 0 (NULL pointer)
  802. **             gr121    0x80000000  Logical TRUE, service successful
  803. **                      errcode     error number, service not
  804. **                                  successful
  805. **
  806. ** Warnings:  This function does not check environment variables
  807. **            such as TMP when creating a temporary filename.
  808. **
  809. **            Also, an input parameter of NULL is not accepted.  This
  810. **            would require allocation of a temporary buffer on the
  811. **            target for storage of the temporary file name.  The
  812. **            target must necessarily specify a buffer address for the
  813. **            temporary filename.
  814. **
  815. */
  816.  
  817. INT32
  818. hif_tmpnam(lr2, gr96)
  819. UINT32    lr2;
  820. UINT32    *gr96;
  821.    {
  822.    ADDR32  addrptr;
  823.    char   *filename;
  824.    INT32     result;
  825.  
  826.  
  827.    /*
  828.    ** If addrptr is zero, there is supposed to be a temporary
  829.    ** buffer allocated on the target.  Since we can't allocate
  830.    ** memory on the target we have to return an error.  This
  831.    ** should be fixed.
  832.    */
  833.  
  834.    addrptr = lr2;
  835.  
  836.    if (addrptr == (UINT32) 0) {
  837.      *gr96 = (UINT32) 0;
  838.       return(HIF_EACCESS);
  839.    }
  840.  
  841.    filename = tmpnam(tmp_buffer);
  842.  
  843.    if (filename == NULL) {
  844.      *gr96 = (UINT32) 0;
  845.       return(HIF_EACCESS);
  846.    }
  847.  
  848.    result = UDI_write_string((INT32) UDI29KDRAMSpace,
  849.                          addrptr,
  850.                          (INT32) (strlen(filename) + 1),
  851.                          filename);
  852.    if (result != (INT32) 0) {
  853.       *gr96 = (UINT32) 0;
  854.       return(result);
  855.    }
  856.  
  857.    *gr96 = (UINT32) addrptr;
  858.  
  859.    return (0);
  860.  
  861.    }  /* end hif_tmpnam() */
  862.  
  863.  
  864.  
  865. /*
  866. ** Service 49 - time
  867. **
  868. ** Type         Regs    Contents    Description
  869. ** ----         ----    --------    -----------
  870. ** Calling:    gr121    49 (0x31)   Service number
  871. **
  872. ** Returns:    gr96     secs        Success != 0 (time in seconds)
  873. **                                  Failure = 0
  874. **             gr121    0x80000000  Logical TRUE, service successful
  875. **                      errcode     error number, service not
  876. **                                  successful
  877. */
  878.  
  879. /* ARGSUSED */
  880. INT32
  881. hif_time(gr96)
  882. UINT32    *gr96;
  883.    {
  884.    time_t  secs;
  885.  
  886.  
  887.    secs = time((time_t *) 0);
  888.  
  889.    *gr96 = (UINT32) secs;
  890.  
  891.    return (0);
  892.  
  893.    }  /* end hif_time() */
  894.  
  895.  
  896.  
  897. /*
  898. ** Service 65 - getenv
  899. **
  900. ** Type         Regs    Contents    Description
  901. ** ----         ----    --------    -----------
  902. ** Calling:    gr121    65 (0x41)   Service number
  903. **             lr2      name        A pointer to symbol name
  904. **        lr3    destination - given by OS.
  905. **
  906. ** Returns:    gr96     addrptr     Success: pointer to symbol name string
  907. **                                  Failure = 0 (NULL pointer)
  908. **             gr121    0x80000000  Logical TRUE, service successful
  909. **                      errcode     error number, service not
  910. **                                  successful
  911. **
  912. ** Note:  Since this service requires writing to a buffer on the
  913. **        target, an extra parameter has been passed in lr3.
  914. **        This parameter points to a buffer which can be used
  915. **        by getenv.
  916. */
  917.  
  918. INT32
  919. hif_getenv(lr2, lr3, gr96)
  920. UINT32    lr2;
  921. UINT32    lr3;
  922. UINT32    *gr96;
  923.    {
  924.    char   *varval;
  925.    INT32     result;
  926.  
  927.    result = UDI_read_string((INT32) UDI29KDRAMSpace,
  928.                         (ADDR32) lr2,
  929.                         (INT32) MAX_ENV,
  930.                         tmp_buffer);
  931.  
  932.    if (result != (INT32) 0) {
  933.       *gr96 = (UINT32) 0;
  934.       return(result);
  935.    }
  936.  
  937.    varval = (char *) getenv(tmp_buffer);
  938.  
  939.    if (varval == NULL)
  940.      result = UDI_write_string((INT32) UDI29KDRAMSpace,
  941.                          (ADDR32) lr3,
  942.                          (INT32) 4,
  943.                          "\0\0\0\0");
  944.    else
  945.      result = UDI_write_string((INT32) UDI29KDRAMSpace,
  946.                          (ADDR32) lr3,
  947.                          (INT32) (strlen(varval) + 1),
  948.                          varval);
  949.  
  950.    if (result != (INT32) 0) {
  951.       *gr96 = (UINT32) 0;
  952.       return(result);
  953.    }
  954.  
  955.    *gr96 = lr3;
  956.  
  957.    return (0);
  958.  
  959.    }  /* end hif_getenv() */
  960.  
  961.  
  962.  
  963.  
  964. /*
  965. ** Service 66 - gettz
  966. **
  967. ** Type         Regs    Contents    Description
  968. ** ----         ----    --------    -----------
  969. ** Calling:    gr121    66 (0x42)   Service number
  970. **
  971. ** Returns:    gr96     zonecode    Success >= 0 (minutes west of GMT)
  972. **                                  Failure < 0 (or information
  973. **                                               unavailable)
  974. **             gr97     dstcode     Success = 1 (Daylight Savings Time
  975. **                                               in effect)
  976. **                                          = 0 (Daylight Savings Time
  977. **                                               not in effect)
  978. **             gr121    0x80000000  Logical TRUE, service successful
  979. **                      errcode     error number, service not
  980. **                                  successful
  981. **
  982. */
  983.  
  984. /* ARGSUSED */
  985. INT32
  986. hif_gettz(gr96, gr97)
  987. UINT32    *gr96;
  988. UINT32    *gr97;
  989.    {
  990.    struct timeb timeptr;
  991.  
  992.  
  993.    (void) ftime(&timeptr);
  994.  
  995.    *gr96 = (UINT32) timeptr.timezone;
  996.    *gr97 = (UINT32) timeptr.dstflag;
  997.  
  998.    return (0);
  999.  
  1000.    }  /* end hif_gettz() */
  1001.  
  1002.  
  1003.  
  1004. /*
  1005. ** This function is used to read data from the target.
  1006. ** This function returns zero if successful, and an
  1007. ** error code otherwise.
  1008. **
  1009. ** Note that this function permits reading any
  1010. ** arbitrary sized buffer on the target into a
  1011. ** buffer on the host.
  1012. */
  1013.  
  1014. INT32
  1015. UDI_read_string(memory_space, address, byte_count, data)
  1016.    INT32   memory_space;
  1017.    ADDR32  address;
  1018.    INT32   byte_count;
  1019.    char   *data;
  1020.    {
  1021.    UDIResource    from;
  1022.    UDICount    count_done;
  1023.    UDIError    UDIretval;
  1024.  
  1025.    from.Offset = address;
  1026.    from.Space = (CPUSpace) memory_space;
  1027.  
  1028.    if ((UDIretval = UDIRead (from,
  1029.                  (UDIHostMemPtr) data,
  1030.                  (UDICount) byte_count,
  1031.                  (size_t) 1,
  1032.                  &count_done,
  1033.                  (UDIBool) 0)) != UDINoError) {
  1034.       com_error = 1;
  1035.       return (UDIretval);
  1036.    };
  1037.    if ((tip_target_config.os_version & 0xf) > 4) { /* new HIF kernel */
  1038.      /* 
  1039.       * Examine UDIretval and send a GO to switch the Debugger context
  1040.       * back to HIF kernel.
  1041.       */
  1042.       Mini_build_go_msg();
  1043.       if (Mini_msg_send() != SUCCESS) {
  1044.     com_error = 1;
  1045.         return (-1);    /* FAILURE */
  1046.       }
  1047.    } else { /* old HIF kernel */
  1048.    }
  1049.     return(0); /* SUCCESS */
  1050.    }  /* end read_string() */
  1051.  
  1052.  
  1053. /*
  1054. ** This function is used to write a buffer of data to
  1055. ** the target.  This function returns zero if successful,
  1056. ** and an error code otherwise.
  1057. **
  1058. ** Note that this function permits writing any
  1059. ** arbitrary sized buffer on the target from a
  1060. ** buffer on the host.
  1061. */
  1062.  
  1063. INT32
  1064. UDI_write_string(memory_space, address, byte_count, data)
  1065.    INT32   memory_space;
  1066.    ADDR32  address;
  1067.    INT32   byte_count;
  1068.    char   *data;
  1069.    {
  1070.    UDIResource    to;
  1071.    UDICount    count_done;
  1072.    UDIError    UDIretval;
  1073.  
  1074.    to.Offset = address;
  1075.    to.Space = (CPUSpace) memory_space;
  1076.  
  1077.    if ((UDIretval = UDIWrite ((UDIHostMemPtr) data,
  1078.                   to,
  1079.                   (UDICount) byte_count,
  1080.                   (size_t) 1,
  1081.                   &count_done,
  1082.                   (UDIBool) 0)) != UDINoError) {
  1083.       com_error = 1;
  1084.       return (UDIretval);
  1085.    }
  1086.    if ((tip_target_config.os_version & 0xf) > 4) { /* new HIF kernel */
  1087.      /* 
  1088.       * Examine UDIretval and send a GO to switch the Debugger context
  1089.       * back to HIF kernel.
  1090.       */
  1091.       Mini_build_go_msg();
  1092.       if (Mini_msg_send() != SUCCESS) {
  1093.     com_error = 1;
  1094.         return (-1);    /* FAILURE */
  1095.       }
  1096.    } else { /* old HIF kernel */
  1097.    }
  1098.     return(0); /* SUCCESS */
  1099.    }  /* end UDI_write_string() */
  1100.  
  1101.