home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_200 / 208_01 / cpm68k.c < prev    next >
Text File  |  1987-10-13  |  8KB  |  371 lines

  1. /*
  2. HEADER:        CUG208;
  3. TITLE:        'e' for CP/M68K
  4. VERSION:    1.48b
  5.  
  6. DESCRIPTION:    "a screen editor";
  7.  
  8. KEYWORDS:    editor;
  9. SYSTEM:        CP/M68K, V1.2;
  10. FILENAME:    e/cpm68k.c
  11. WARNINGS:    "the default value is for systems with 128K bytes
  12.          of memory or more";
  13. SEE-ALSO:    e68k.doc, CUG VOL 133;
  14. AUTHORS:    G.N.Gilbert('e'), J.W.Haefner(for DeSmet C on MSDOS and UNIX)
  15. CODER:        Yoshimasa Tsuji
  16. COMPILERS:    DRI C(Alcyon C) for CP/M68K;
  17. */
  18. /*
  19.     FUNCTIONS: dskcheck, chdir, getwd, format, readdir, getfree
  20.         _inkey, _conin, _conout, raw(), noraw()
  21.     PURPOSE: os dependent functions.
  22. */
  23.  
  24.  
  25.  
  26. # include <ctype.h>
  27. # include <sgtty.h>
  28. # include "e.h"
  29.  
  30. /* CP/M bdos function codes */
  31.  
  32. #define RESET 0
  33. #define CONIN 0x01
  34. #define CONOUT 0x02
  35. #define LSTOUT 0x05
  36. /* in CP/M68K DIRIO differs */
  37. #define DIRIO 0x06
  38. #define IOBYTE 0x07
  39. #define SETIOBYTE 0x08
  40. #define PRINTS 0x09
  41. #define READBUF 0x0A
  42. #define CONSTAT 0x0B
  43. #define VERNO 0x0C
  44. #define RESETDSK 0x0D
  45. #define SELDSK 0x0E
  46. #define OPEN 0x0F
  47. #define CLOSEF 0x10
  48. #define SEARCH1 0x11
  49. #define SEARCHN 0x12
  50. #define DELETEF 0x13
  51. #define READ 0x14
  52. #define WRITE 0x15
  53. #define MAKE 0x16
  54. #define RENAME 0x17
  55. #define LOGINV 0x18
  56. #define CURDSK 0x19
  57. #define SETDMA 0x1A
  58. #define PROTECT 0x1C
  59. #define GETROV 0x1d
  60. /* in CP/M68K DSKPARAMS requires a different argument */
  61. #define DSKPARAMS 0x1F
  62. #define USERCODE 0x20
  63. #define READR 0x21
  64. #define WRITER 0x22
  65. #define FSIZE 0x23
  66. #define SETRR 0x24
  67. #define RESETDRV 0x25
  68.  
  69.  
  70. #define CPM3ERRORMODE 45    /*set error mode to return and display
  71. (specific to CP/M Plus) */
  72. # if MSDOS
  73.  
  74. #define DOSINT 0x21
  75. #define FREESP  0x36
  76. #define SETDIR  0x3b
  77. #define GETDIR  0x47
  78. #define FIND1   0x4e
  79. #define FINDN   0x4f
  80.  
  81. # endif
  82.  
  83. extern char *__BDOS();
  84. /* long __BDOS(fn, param)
  85.  * int fn; long param; {
  86.  *    asm("move.l 10(R14),R1");
  87.  *    asm("move.l 8(R14),R0");
  88.  *    asm("trap #2");
  89.  * }
  90.  */
  91.  
  92. /* _os is an integer version of __BDOS */
  93. static
  94. _os(n, x)
  95. {
  96.  
  97.     return ((int)__BDOS(n, (long)x )) ;
  98. }
  99.  
  100. static char *
  101. bios ( fn, p)
  102. {
  103.     struct {
  104.         short bdosn;
  105.         long d1, d2;
  106.     }
  107.     bpb;
  108.  
  109.     bpb.bdosn = fn;
  110.     bpb.d1 = (long)p;
  111.     return(__BDOS(50, &bpb));
  112. }
  113.  
  114. /* the argument to dskcheck is altered */
  115. dskcheck(drive)
  116. {
  117.     return((drive >15 || drive < 0)? FAIL: 0);
  118. }
  119.  
  120. /* return tty status
  121.  * this is heavily system dependent
  122.  * does read(0,buff,1) returns 0 if a char is not
  123.  * ready in your system?
  124.  */
  125. _inkey()
  126. {
  127.     return(_os(CONSTAT));
  128. }
  129.  
  130. raw()        /* set tty in raw mode */
  131. {
  132.     struct sgttyb obuf;
  133.     if(gtty(0, &obuf) == -1)
  134.         putstr("tty input only"),exit(1);
  135.     obuf.sg_flags |= RAW;
  136.     stty(0, &obuf);
  137.     if(gtty(1, &obuf) == -1)
  138.         putstr("tty output only"), exit(1);
  139.     obuf.sg_flags |= RAW;
  140.     stty(1, &obuf);
  141. }
  142.  
  143. noraw()        /* restore tty to cooked mode */
  144. {
  145.     struct sgttyb obuf;
  146.  
  147.     gtty(0, &obuf);
  148.     obuf.sg_flags &= ~RAW;
  149.     stty(0, &obuf);
  150.     gtty(1, &obuf);
  151.     obuf.sg_flags &= ~RAW;
  152.     stty(1, &obuf);
  153. }
  154.  
  155.  
  156. /* get a byte RAW from tty
  157.  */
  158. _conin()
  159. {
  160.     char c[2];
  161.     read(0,c,1);
  162.     return(c[0]);
  163. }
  164. /* put a byte RAW to tty. */
  165. _conout(c)
  166. {
  167.     char ch[2];
  168.     ch[0] = c;
  169.     write(1, ch, 1);
  170.     return(c);
  171. }
  172.  
  173. format(name)    /*expands filename 'name' to full pathname*/
  174.         /*in cp/m68k Output format is uud:ffffffff.xxx\0   */
  175. char *name;
  176. {
  177.     char tempname[FILELEN];
  178.  
  179.     if (!*name) return;
  180.     if(index(name,':'))
  181.         return;
  182.     strcpy(tempname,curdir);
  183.     strcpy(tempname,":");
  184.     strcpy(tempname,name);
  185.     strcpy(name, tempname);
  186. }
  187.  
  188. /* change login directory to s[]= "15b"    */
  189. /* no slash between user number and drive number
  190.  * in CPM68K. This routine calls SELDSK in BIOS.
  191.  */
  192. chdir(s)
  193. char *s;
  194. {
  195.     short user = 0;
  196.     register char drive;
  197.  
  198.     if(*s == 0)
  199.         return(FAIL);
  200.     while(isdigit(*s)){
  201.         user = 10*user + *s - '0';
  202.         s++;
  203.         if(user >15)return(FAIL);
  204.     }
  205.     drive = tolower(*s);
  206.     if(isalpha(drive))
  207.         if(drive < 'a' || drive > 'p' || bios(9, drive - 'a')== 0)
  208.             return(FAIL);
  209.         else
  210.             _os(SELDSK,drive-'a');
  211.     /* allow 0: or 10a:    */
  212.     _os(USERCODE, user);
  213.     return(0);
  214. }
  215.  
  216. /* return the name of the working directory.
  217.  * in CPM68K it is  a string like "15c" without slashes.
  218.  * you will need a colon to form a full-pathed name.
  219.  */
  220. char *
  221. getwd(dir)
  222. char *dir;
  223. {
  224.     register char *p;
  225.     short user;
  226.     p = dir;
  227.     if(user = _os(USERCODE, 0xff)){
  228.         if(user >9)*p++ = '1';
  229.         *p++ = (user % 10) + '0';
  230.     }
  231.     *p++ = _os(CURDSK) + 'a';
  232.     *p = 0;
  233.     return dir;
  234. }
  235.  
  236. /* readdir returns a stream of filenames delimited by a NEWLINE
  237.  * and terminated by a NULL.
  238.  * the present implementation uses a fixed sized buffer
  239.  * to contain 256 filenames.
  240.  * In other systems, directory entries are not consecutive and
  241.  * readdir() returns a pointer to the next directory entry or
  242.  * NULL. The buffer is usually obtained via calloc(), you will
  243.  * also need to cfree() via closedir().
  244.  */
  245.  
  246. #define EXTENT 12
  247. #define DIRSIZ 3330
  248.  
  249. char *
  250. readdir(s)
  251. char *s;
  252. {
  253.     char olddir[5];        /* save old directory */
  254.     static char dmabuf[128];
  255.     static char dirbuf[DIRSIZ];
  256.     static char fcb[36]= "?????????????";
  257.     register int pos, i;
  258.     register char *p, *entri;
  259.     /* my compiler does not complain about '*entry', though */
  260.     char c;
  261.  
  262.     getwd(olddir);
  263.     if(chdir(s) == FAIL){
  264.         dirbuf[0] = 0;
  265.         return dirbuf;
  266.     }
  267.     fcb[0] = 0;    /* search default drive only */
  268.     p = dirbuf;
  269.     __BDOS(SETDMA, dmabuf);
  270.     pos= (int)__BDOS(SEARCH1,fcb);
  271.     while (pos != 0xff) {
  272.         entri= &dmabuf[pos << 5];
  273.         for (i=1; i < 12; i++) {
  274.             c= *(entri+i) & 0x7f;
  275.             if (i == 9 && c != ' ')
  276.                 *p++ = '.';
  277.             if (c != ' ')
  278.                 *p++ = tolower(c);
  279.         }
  280.         *p++ = '\n';
  281.         pos=(int)__BDOS(SEARCHN,fcb);
  282.     }
  283.     if(p >= dirbuf + DIRSIZ){
  284.         putstr("dir too big\n");
  285.         exit(1);
  286.     }
  287.     *p = 0;
  288.     chdir(olddir);
  289.     return dirbuf;
  290. }
  291.  
  292. /* return available storage of directory in kilobytes
  293.  * in CP/M80 Plus
  294.  *     the most significant byte must be masked.
  295.  * in CP/M80 2.2 and CP/M86
  296.  *    bdos function 27 return a pointer(in HL or BX+ES)
  297.  *    to the allocation bit map of the logged in drive.
  298.  *    The bit on shows that the block is used.
  299.  *    The length of the bit map is to be calculated from
  300.  *    infomation given in a DPB structure,
  301.  *    the pointer to which is again obtained by the bdos
  302.  *    function 31. The DPB structure also contains a value
  303.  *    to mask the first two bytes of the bit map( al0, al1)
  304.  */
  305.  
  306. getfree(path)
  307. char *path;
  308. {
  309.     register long *free;
  310.     register char *p;
  311.     char dmabuff[128];
  312.     register int drive;
  313.     p = path;
  314.     if(*p == 0)
  315.         return 0;
  316.     while(*p)
  317.         p++;
  318.     --p;
  319.     drive = tolower(*p) - 'a';
  320.     if(dskcheck(drive) == FAIL)
  321.         return 0;
  322.     __BDOS(SETDMA,dmabuff);
  323.     _os(46, drive);
  324.     free = (long *)dmabuff;
  325.     return (int)(*free >> 3);
  326. }
  327.  
  328. /*    ----- bug fix of CP/M68K -------
  329.  *    read/write in RAW mode.
  330.  *    tuned for RAW only.
  331.  *    My own version is much more complicated than what you
  332.  *    will see; it handles tty info correctly ( RAW, CBREAK, ECHO
  333.  *    XTABS, erase, kill). That is why I used stty() and gtty()
  334.  *    elsewhere.
  335.  */
  336. int nofloat();
  337. int nofilesz();
  338. int nobinary(); /* see option.h supplied by DRI    */
  339.  
  340. /* _ttyin() is eventually called by read()
  341.  */
  342. _ttyin(fp,buffer,nbytes)
  343. char *fp, *buffer;    /* fp is a struct, to be exact */
  344. {
  345.     if(nbytes == 0)
  346.         return(0);
  347.     if(nbytes != 1)
  348.         return(-1);
  349.     *buffer = _os(DIRIO, 0xff);
  350.     return(1);
  351. }
  352.  
  353. /* if you want a real fix, you must fix _wrtchr()
  354.  * so that RAW mode can be set on/off
  355.  * it would also enable you to set XTABS on/off
  356.  * so that tab be processed before listing
  357.  
  358.  */
  359.  /* _ttyout() is eventually called by write()
  360.   */
  361. _ttyout(buf)
  362. register char *buf;
  363. {
  364.     register int count, ii;
  365.     ii= count = *buf++;
  366.     while(ii--)
  367.         _os(DIRIO, *buf++);
  368.     return(count);
  369. }
  370.  
  371.