home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / ctcoll95.zip / BASTELST / PAPI020.ZIP / PRINTF.C < prev    next >
C/C++ Source or Header  |  1993-10-06  |  3KB  |  197 lines

  1. #include <dos.h>
  2. #include <stdarg.h>
  3. #include <mem.h>
  4. #include "types.h"
  5.  
  6. static void kprintn(dword, int);
  7. int putchar(char c);
  8. static void cursor(dword pos);
  9. static void sput(byte c);
  10.  
  11. void
  12. printf(const char *fmt, ...)
  13. {
  14.     char *p;
  15.     int ch;
  16.     dword ul;
  17.     int lflag;
  18.     va_list ap;
  19.  
  20.     va_start(ap, fmt);
  21.     for (;;) {
  22.         while ((ch = *fmt++) != '%') {
  23.             if (ch == '\0')
  24.                 return;
  25.             putchar(ch);
  26.         }
  27.         lflag = 0;
  28. reswitch:    switch (ch = *fmt++) {
  29.         case 'l':
  30.             lflag = 1;
  31.             goto reswitch;
  32.         case 'c':
  33.             ch = va_arg(ap, int);
  34.                 putchar(ch & 0x7f);
  35.             break;
  36.         case 's':
  37.             p = va_arg(ap, char *);
  38.             while ((ch = *p++)!= 0)
  39.                 putchar(ch);
  40.             break;
  41.         case 'd':
  42.             ul = lflag ?
  43.                 va_arg(ap, long) : va_arg(ap, int);
  44.             if ((long)ul < 0) {
  45.                 putchar('-');
  46.                 ul = -(long)ul;
  47.             }
  48.             kprintn(ul, 10);
  49.             break;
  50.         case 'o':
  51.             ul = lflag ?
  52.                 va_arg(ap, dword) : va_arg(ap, word);
  53.             kprintn(ul, 8);
  54.             break;
  55.         case 'u':
  56.             ul = lflag ?
  57.                 va_arg(ap, dword) : va_arg(ap, word);
  58.             kprintn(ul, 10);
  59.             break;
  60.         case 'x':
  61.             ul = lflag ?
  62.                 va_arg(ap, dword) : va_arg(ap, word);
  63.             kprintn(ul, 16);
  64.             break;
  65.         default:
  66.             putchar('%');
  67.             if (lflag)
  68.                 putchar('l');
  69.             putchar(ch);
  70.         }
  71.     }
  72. /*    va_end(ap);*/
  73. }
  74.  
  75. static void
  76. kprintn(dword ul, int base)
  77. {
  78.                     /* hold a long in base 8 */
  79.     char *p, buf[16];
  80.  
  81.     p = buf;
  82.     do {
  83.         *p++ = (char) "0123456789abcdef"[(word) ul % base];
  84.     } while (ul /= base);
  85.     do {
  86.         putchar(*--p);
  87.     } while (p > buf);
  88. }
  89.  
  90. int
  91. putchar(char c)
  92. {
  93.         if (c == '\n')
  94.         sput('\r');
  95.     sput(c);
  96.     return(0);
  97. }
  98.  
  99. #define    COL        80
  100. #define    ROW        25
  101. #define    CHR        2
  102. #define MONO_BASE    0x3B4
  103. #define MONO_BUF    0xB0000000
  104. #define CGA_BASE    0x3D4
  105. #define CGA_BUF        0xB8000000
  106.  
  107. static byte    att = 0x7 ;
  108. byte far *Crtat = (byte far *)CGA_BUF;
  109.  
  110. static unsigned int addr_6845 = CGA_BASE;
  111.  
  112. static void
  113. cursor(dword pos)
  114. {
  115.     outportb(addr_6845,14);
  116.     outportb(addr_6845+1,(pos >> 8)&0xff);
  117.     outportb(addr_6845,15);
  118.     outportb(addr_6845+1,pos&0xff);
  119. }
  120.  
  121. static void
  122. sput(byte c)
  123. {
  124.  
  125.     static byte far *crtat = 0;
  126.     unsigned cursorat;
  127.     byte *cp;
  128.  
  129.         /* Extract cursor location */
  130.     outportb(addr_6845,14);
  131.     cursorat = inportb(addr_6845+1)<<8 ;
  132.     outportb(addr_6845,15);
  133.     cursorat |= inportb(addr_6845+1);
  134.  
  135.     if(cursorat <= COL*ROW) {
  136.         crtat = Crtat + cursorat*CHR;
  137.         /* att = crtat[1];    /* use current attribute present */
  138.     } else    crtat = Crtat;
  139.  
  140.     switch (c) {
  141.  
  142.     case '\t':
  143.         do
  144.             sput(' ');
  145.         while ((int)crtat % (8*CHR));
  146.         break;
  147.  
  148.     case '\010':
  149.         crtat -= CHR;
  150.         break;
  151.  
  152.     case '\r':
  153.         crtat -= (word) ((crtat - Crtat) % (COL*CHR));
  154.         break;
  155.  
  156.     case '\n':
  157.         crtat += COL*CHR ;
  158.         break;
  159.  
  160.     default:
  161.         crtat[0] = c;
  162.         crtat[1] = att;
  163.         crtat += CHR;
  164.         break ;
  165.     }
  166.  
  167.     /* implement a scroll */
  168.     if (crtat >= Crtat+COL*ROW*CHR) {
  169.         /* move text up */
  170.         memcpy(Crtat, Crtat+COL*CHR, COL*(ROW-1)*CHR);
  171.  
  172.         /* clear line */
  173.         for (cp = Crtat+ COL*(ROW-1)*CHR;
  174.             cp < Crtat + COL*ROW*CHR ; cp += 2)
  175.             cp[0] = ' ';
  176.  
  177.         crtat -= COL*CHR ;
  178.     }
  179.  
  180.     cursor((crtat-Crtat)/CHR);
  181. }
  182.  
  183. void
  184. init_printf(void)
  185. {
  186.     word was;
  187.  
  188.     /* probe to find if a color or monochrome display */
  189.     was = *(word *)Crtat;
  190.     *(word *)Crtat = 0xA55A;
  191.     if (*(word *)Crtat != 0xA55A) {
  192.         Crtat = (byte far *) MONO_BUF;
  193.         addr_6845 = MONO_BASE;
  194.     }
  195.     *(word *)Crtat = was;
  196. }
  197.