home *** CD-ROM | disk | FTP | other *** search
/ Turbo Toolbox / Turbo_Toolbox.iso / dtx9202 / dbase / loader.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-12-10  |  12.7 KB  |  357 lines

  1. /* ------------------------------------------------------ */
  2. /*                      LOADER.C                          */
  3. /*       (c) 1991 Helmut Guttenberg & DMV-Verlag          */
  4. /* ------------------------------------------------------ */
  5. #include <process.h>
  6. #include <string.h>
  7. #include <stdlib.h>
  8. #include <conio.h>
  9. #include <dos.h>
  10. #include <io.h>
  11. #include <fcntl.h>
  12. #include "serv.h"
  13.  
  14. #define SSCD  300    /* Initialwert für Screensaver:
  15.                         300 Ticks = 16.4 s           */
  16.  
  17. /* Puffer für Interrupt pointer: */
  18. void interrupt (*oldclock) (void); /* int 1Ch */
  19. void interrupt (*oldkeyb) (void);  /* int 09h */
  20. void interrupt (*oldcons) (void);  /* int 10h */
  21.  
  22. /* und die neuen Funktionen */
  23. void interrupt newclock (void);
  24. void interrupt newkeyb (void);
  25. void interrupt newcons (unsigned bp, unsigned di,
  26.                         unsigned si, unsigned ds,
  27.                         unsigned es, unsigned dx,
  28.                         unsigned cx, unsigned bx,
  29.                         unsigned ax);
  30.  
  31. static void interrupt u_interf (unsigned bp, unsigned di,
  32.                                 unsigned si, unsigned ds,
  33.                                 unsigned es, unsigned dx,
  34.                                 unsigned cx, unsigned bx,
  35.                                 unsigned ax);
  36.     /* Userinterrupt der von UTILITY.BIN
  37.        (von dBASE mit load geladen) bedient wird */
  38.  
  39. void service (unsigned ds, unsigned bx, unsigned ax);
  40.     /* Die eigentliche Schnittstelle zu den verschiedenen
  41.        implementierten Funktionen */
  42.  
  43. extern int errno;
  44. extern int *videoseg;
  45.  
  46. int clock_active = 0;    /* Flag für newclock(), verhindert
  47.                             Mehrfachaufruf                 */
  48. int clock_on     = 0;    /* Flag: Uhrzeit anzeigen oder
  49.                             nicht */
  50. int minutes      = -1;
  51.  
  52. int cl_pos_x     = 66;   /* Default Position Uhrzeit und
  53.                             Farbe */
  54. int cl_pos_y     = 0;
  55. int cl_col       = 0x0F;
  56.  
  57. unsigned long *CntPtr=
  58.        (char *) MK_FP(0x0040,0x006C);
  59.                /* Pointer auf DOS UhrzeitZähler */
  60. unsigned long CntVal;  /* Puffer für Uhrzeit-Zähler */
  61. int tempminutes,hours,secs,osecs;
  62. static char cl_line[9]="  .  .  "; /* Maske für Uhrzeit */
  63.  
  64. struct text_info ti;               /* siehe Reference guide
  65.                                       von TURBO C */
  66. int save_screen_buffer[80*25];    /* Puffer für Bildschirm */
  67. int countdown=SSCD,cdinit=SSCD;   /* Zählervariable und Ini-
  68.                                      tialwert dafür*/
  69. int screen_saved = 0;             /* Flag für Screen Saver */
  70. int saver_on=0;                   /* Screen Saver on/off */
  71. int cp_xy,cp_f;                   /* Cursor Position und Form */
  72. int sscx=1;                       /* Laufvariable Screen
  73.                                      Saver für Symbol '■' */
  74.  
  75. int temphandle=0;        /* Temporäre Swapdatei für
  76.                             Window Puffer und */
  77. char tempname[50];       /* von DOS ermittelter Name
  78.                             dafür. */
  79.  
  80. /* dstr : Display string
  81.    Schreibt an der Stelle px,py mit der Farbe attr den
  82.    String str */
  83. void dstr(char *str, int px, int py, int attr)
  84. {
  85.   int i;
  86.   for (i = 0; *(str+i) != 0; i++)
  87.   dispchar(*(str+i), px+i, py, attr);
  88. }
  89.  
  90. /* ClrScr : Clear Screen
  91.    löscht Bildschirm, ohne weitere Funktionen wie im einge-
  92.    bauten clrscr() */
  93. void ClrScr (void)
  94. {
  95.   memset(videoseg,0,4000);
  96. }
  97.  
  98. /* save_screen : --
  99.    sichert Bildschirminhalt, Cursorposition und -form */
  100. void save_screen (void)
  101. {
  102.  gettext(1,1,80,25,save_screen_buffer);
  103.        /* speichere ganzen Bildschirm */
  104.  _AX=0x0300;
  105.  _BX=0x0000;
  106.  geninterrupt(0x10);  /* Hole Cursorposition und -form */
  107.  cp_xy=_DX;
  108.  cp_f=_CX;
  109.  _AX=0x0100;
  110.  _CX=0x0E0F;
  111.  geninterrupt(0x10);   /* Lösche Cursor weg */
  112.  ClrScr();             /* Lösche Bildschirminhalt weg */
  113.  screen_saved=1;
  114. }
  115.  
  116. /* rest_screen : Restore Screen
  117.    stellt den vorher mit save_screen() abgespeicherten
  118.    Bildschirminhalt wieder her, einschl. des Cursors */
  119. void rest_screen (void)
  120. {
  121.  screen_saved=0;
  122.  puttext(1,1,80,25,save_screen_buffer); /* restore screen*/
  123.  _AX=0x0200;
  124.  _BX=0;
  125.  _DX=cp_xy;
  126.  geninterrupt(0x10);      /* restore cursor position */
  127.  _AX=0x0100;
  128.  _CX=cp_f;
  129.  geninterrupt(0x10);      /* restore cursor form */
  130. }
  131.  
  132. /* newkeyb : New keyboard interrupt
  133.    flickt an den alten int 09h eine Routine an, die den
  134.    Countdown für den Screen saver wieder auf den Initial-
  135.    wert setzt und falls der Bildschirm schon gesichert
  136.    worden ist, wird er durch rest_screen() wiederherge-
  137.    stellt. */
  138. void interrupt newkeyb (void)
  139. {
  140.  (*oldkeyb)();         /* Bearbeite erstmal den alten
  141.                           int 09h */
  142.  countdown=cdinit;     /* setzt countdown wieder hoch */
  143.  if (screen_saved)     /* falls Bildschirm gesichert
  144.                           wurde ... */
  145.   rest_screen();       /* ... stelle Bildschirm wieder
  146.                           her */
  147. }
  148.  
  149. /* newcons : New console interrupt
  150.    arbeitet genauso wie newbeyb(), mit dem Unterschied,
  151.    daß der Bildschirm wiederhergestellt werden muß
  152.    bevor (!) der schreibende Zugriff auf den Bildschirm
  153.    stattfindet. Die Parameter müssen angegeben werden, da
  154.    der Softwareinterrupt 0x10 in den Registern Werte über-
  155.    nimmt und zurückliefert, die durch die eingeschobene
  156.    Routine zerstört werden. Auf diese Weise können die
  157.    Register zum Eintritt in die alte Interruptroutine auf
  158.    die richtigen Funktionswerte und bei der Rückkehr auf
  159.    die richtigen Ergebniswerte gesetzt werden. Siehe auch
  160.    Reference guide TURBO C.*/
  161. void interrupt newcons (unsigned bp, unsigned di,
  162.                         unsigned si, unsigned ds,
  163.                         unsigned es, unsigned dx,
  164.                         unsigned cx, unsigned bx,
  165.                         unsigned ax)
  166.  
  167. {
  168.  countdown=cdinit;
  169.  if (screen_saved)
  170.   rest_screen();
  171.  _DX=dx;
  172.  _CX=cx;
  173.  _BX=bx;
  174.  _AX=ax;
  175.  (*oldcons)();          /* Aufruf alter int 10h */
  176.  ax=_AX;
  177.  bx=_BX;
  178.  cx=_CX;
  179.  dx=_DX;
  180. }
  181.  
  182. /* newclock : New clock interrupt
  183.    wird per Hardware 18.2 mal pro Sekunde aufgerufen und
  184.    dient der Anzeige der Uhrzeit, dem Countdown für den
  185.    Screen saver und der Darstellung des Laufpunktes, wenn
  186.    der Screen Saver aktiv ist. */
  187. void interrupt newclock (void)
  188. {
  189.  (*oldclock)();   /* Ruf' alten int 1Ch auf, falls
  190.                      andere residente Programme die-
  191.                      sen benötigen */
  192.  disable();        /* Laß keine weiteren Interr. zu */
  193.  if (clock_active) /* falls diese Routine bereits
  194.                       aktiv ... */
  195.  {
  196.   enable();        /* ... lasse Interrupts wieder
  197.                           zu ... */
  198.   return;          /* ... und kehre zurück */
  199.  }
  200.  clock_active = 1;   /* sonst vermerke, daß diese Rou-
  201.                         tine aktiv ist ... */
  202.  enable();           /* ... und lasse Interrupts wieder
  203.                          zu */
  204.  if (!screen_saved)  /* falls Bildschirm noch nicht
  205.                          gesichert ... */
  206.  {
  207.   if (countdown<0)   /* ... und falls countdown auf 0
  208.                         runtergeszählt wurde */
  209.    save_screen();    /* ... sichere Bildschirm */
  210.   else
  211.    if (saver_on)     /* sonst falls Screen saver
  212.                          aktiv ... */
  213.     countdown--;     /* count down */
  214.  }
  215.  else               /* Bildschirm gesichert, zeige
  216.                        laufendes '■' */
  217.  {
  218.   dispchar(' ', sscx, 24, 0x07);
  219.   sscx = (sscx + 1) % 80 + 1;
  220.   dispchar('■', sscx, 24, 0x07);
  221.  }
  222.  if (clock_on && !screen_saved)  /* falls Uhr eingeschaltet
  223.                                     und Bildschirm nicht
  224.                                     gesichert */
  225.  {
  226.   disable();
  227.   clock_active=1;
  228.   CntVal=*CntPtr;               /* Kopiere den Uhrzeitwert
  229.                                    von DOS */
  230.   enable();                     /* ansonsten: */
  231.   minutes=(int)(CntVal/1092);   /* 60 s * 18.2 Ticks/s =
  232.                                    1092 Ticks */
  233.   hours=minutes/60;
  234.   tempminutes=minutes%60;       /* = Minuten der angefange-
  235.                                    nen Stunde */
  236.   secs=(int)((CntVal*10-(unsigned long)minutes*10920)/182);
  237.                                 /* = volle Sekunden */
  238.   if (secs!=osecs)              /* falls die Sekundenbe-
  239.                                    rechnung das selbe Er-
  240.                                    gebnis bringt, wie das
  241.                                    letzte Mal braucht die
  242.                                    ausgegebene Uhrzeit
  243.                                    nicht korrigiert zu wer-
  244.                                    den, sonst ... */
  245.   {
  246.    osecs=secs;
  247.    if (hours>9)                 /* Hier wird  "X .  .  "
  248.                                 der Uhrzeitmaske besetzt */
  249.     if (hours>19)
  250.      *cl_line='2';
  251.     else
  252.      *cl_line='1';
  253.    else
  254.     *cl_line=' ';
  255.    *(cl_line+1)=(hours%10)+48;  /* hier       " X.  .  " */
  256.    *(cl_line+3)=(tempminutes/10)+48; /* jetzt "  .X .  " */
  257.    *(cl_line+4)=(tempminutes%10)+48; /* usw. */
  258.    *(cl_line+6)=(secs/10)+48;
  259.    *(cl_line+7)=(secs%10)+48;
  260.    dstr(cl_line,cl_pos_x,cl_pos_y,cl_col);
  261.                      /* Ausgabe unter der einstellbaren
  262.                         Position cl_pos_x,cl_pos_y und
  263.                         der Farbe cl_pos_col */
  264.   }
  265.  }
  266.  disable();
  267.  clock_active=0;      /* Fertig */
  268.  enable();
  269. }
  270.  
  271. /* u_interf : User interface routine
  272.    Diese Funktion ist die eigentliche Schnittstelle für
  273.    das Modul UTILITY.BIN, das von dBASE/FoxBASE aus geladen
  274.    wird. Da in den Registern DS:BX der Zeiger auf den über-
  275.    gebenen String steht und UTILITY.BIN aus dem String die
  276.    Funktionsmummer abspaltet und im Register AX einträgt,
  277.    brauchen wir nur die drei Register AX,BX und DS an die
  278.    Service Routine übergeben um das Gewünschte zu errei-
  279.    chen. */
  280. void interrupt u_interf (unsigned bp, unsigned di,
  281.                          unsigned si, unsigned ds,
  282.                          unsigned es, unsigned dx,
  283.                          unsigned cx, unsigned bx,
  284.                          unsigned ax)
  285. {
  286.  service(ds,bx,ax);
  287. }
  288.  
  289. void main (int argc, char *argv[])
  290. {
  291.  clrscr();
  292.  /* Es folgt eine 'kurze' Meldung */
  293.  cputs("    ╔═════════════════════════════════════════════"
  294.        "═══════════════════════╗\r\n");
  295.  cputs("    ║         Interface-Loader for dBASE/FoxBASE  "
  296.        " Vers. 1.2             ║\r\n");
  297.  cputs("    ║                                             "
  298.        "                       ║\r\n");
  299.  cputs("    ║         Features: Clock,                    "
  300.        "                       ║\r\n");
  301.  cputs("    ║                   Screen saver              "
  302.        "                       ║\r\n");
  303.  cputs("    ║                   Window handling           "
  304.        "                       ║\r\n");
  305.  cputs("    ║                   Printer driver            "
  306.        "                       ║\r\n");
  307.  cputs("    ║                   Cursor layout             "
  308.        "                       ║\r\n");
  309.  cputs("    ║                   Delay function            "
  310.        "                       ║\r\n");
  311.  cputs("    ║    Access by interrupt 0x60, controlling int"
  312.        " 0x09, 0x10, 0x1C.     ║\r\n");
  313.  cputs("    ║                                             "
  314.        "                       ║\r\n");
  315.  cputs("    ╚═════════════════════════════════════════════"
  316.        "═══════════════════════╝\r\n");
  317.  if (getvect(0x60)!=NULL) /* Prüfung ob Interrupt 60h
  318.            bereits besetzt ist */
  319.   cputs("Warnung int 60h in Benutzung, wird abgehängt");
  320.  disable();
  321.  setvect(0x60,u_interf);  /* Setzen von int 60h auf die
  322.          Funkt. u_interf() */
  323.  oldclock=getvect(0x1C);  /* Sichern der originalen Inter-
  324.          ruptvektoren */
  325.  oldkeyb=getvect(0x09);
  326.  oldcons=getvect(0x10);
  327.  setvect(0x09,newkeyb);   /* Setzen der neuen Vektoren */
  328.  setvect(0x10,newcons);
  329.  setvect(0x1C,newclock);
  330.  enable();
  331.  gettextinfo(&ti); /* speziell für die Ermittlung
  332.                        der Bildschirmadresse */
  333.  screen_init();         /* siehe Modul screenh.c */
  334.  delay(1000);  /* 1 Sekunde Verschnaufen um die
  335.                   Funktion delay() zu Kalibrieren
  336.                   (siehe Reference Guide TURBO C) */
  337.  spawnvp(P_WAIT,argv[1],argv+1); /* lade das gewünschte
  338.                Programm samt Parametern */
  339.  if (temphandle)    /* falls temporäre Datei geöffnet
  340.                        wurde ... */
  341.  {
  342.   close(temphandle);  /* ... schließen und ... */
  343.   unlink(tempname);   /* ... löschen */
  344.  }
  345.  disable();
  346.  setvect(0x60,NULL);  /* Setze die originalen Vektoren
  347.                          wieder ein */
  348.  setvect(0x1C,oldclock);
  349.  setvect(0x09,oldkeyb);
  350.  setvect(0x10,oldcons);
  351.  enable();
  352.  clrscr();             /* Lösche Bildschirm und Ende */
  353. }
  354. /* ------------------------------------------------------ */
  355. /*              Ende von LOADER.C                         */
  356.  
  357.