home *** CD-ROM | disk | FTP | other *** search
- /* ------------------------------------------------------ */
- /* LOADER.C */
- /* (c) 1991 Helmut Guttenberg & DMV-Verlag */
- /* ------------------------------------------------------ */
- #include <process.h>
- #include <string.h>
- #include <stdlib.h>
- #include <conio.h>
- #include <dos.h>
- #include <io.h>
- #include <fcntl.h>
- #include "serv.h"
-
- #define SSCD 300 /* Initialwert für Screensaver:
- 300 Ticks = 16.4 s */
-
- /* Puffer für Interrupt pointer: */
- void interrupt (*oldclock) (void); /* int 1Ch */
- void interrupt (*oldkeyb) (void); /* int 09h */
- void interrupt (*oldcons) (void); /* int 10h */
-
- /* und die neuen Funktionen */
- void interrupt newclock (void);
- void interrupt newkeyb (void);
- void interrupt newcons (unsigned bp, unsigned di,
- unsigned si, unsigned ds,
- unsigned es, unsigned dx,
- unsigned cx, unsigned bx,
- unsigned ax);
-
- static void interrupt u_interf (unsigned bp, unsigned di,
- unsigned si, unsigned ds,
- unsigned es, unsigned dx,
- unsigned cx, unsigned bx,
- unsigned ax);
- /* Userinterrupt der von UTILITY.BIN
- (von dBASE mit load geladen) bedient wird */
-
- void service (unsigned ds, unsigned bx, unsigned ax);
- /* Die eigentliche Schnittstelle zu den verschiedenen
- implementierten Funktionen */
-
- extern int errno;
- extern int *videoseg;
-
- int clock_active = 0; /* Flag für newclock(), verhindert
- Mehrfachaufruf */
- int clock_on = 0; /* Flag: Uhrzeit anzeigen oder
- nicht */
- int minutes = -1;
-
- int cl_pos_x = 66; /* Default Position Uhrzeit und
- Farbe */
- int cl_pos_y = 0;
- int cl_col = 0x0F;
-
- unsigned long *CntPtr=
- (char *) MK_FP(0x0040,0x006C);
- /* Pointer auf DOS UhrzeitZähler */
- unsigned long CntVal; /* Puffer für Uhrzeit-Zähler */
- int tempminutes,hours,secs,osecs;
- static char cl_line[9]=" . . "; /* Maske für Uhrzeit */
-
- struct text_info ti; /* siehe Reference guide
- von TURBO C */
- int save_screen_buffer[80*25]; /* Puffer für Bildschirm */
- int countdown=SSCD,cdinit=SSCD; /* Zählervariable und Ini-
- tialwert dafür*/
- int screen_saved = 0; /* Flag für Screen Saver */
- int saver_on=0; /* Screen Saver on/off */
- int cp_xy,cp_f; /* Cursor Position und Form */
- int sscx=1; /* Laufvariable Screen
- Saver für Symbol '■' */
-
- int temphandle=0; /* Temporäre Swapdatei für
- Window Puffer und */
- char tempname[50]; /* von DOS ermittelter Name
- dafür. */
-
- /* dstr : Display string
- Schreibt an der Stelle px,py mit der Farbe attr den
- String str */
- void dstr(char *str, int px, int py, int attr)
- {
- int i;
- for (i = 0; *(str+i) != 0; i++)
- dispchar(*(str+i), px+i, py, attr);
- }
-
- /* ClrScr : Clear Screen
- löscht Bildschirm, ohne weitere Funktionen wie im einge-
- bauten clrscr() */
- void ClrScr (void)
- {
- memset(videoseg,0,4000);
- }
-
- /* save_screen : --
- sichert Bildschirminhalt, Cursorposition und -form */
- void save_screen (void)
- {
- gettext(1,1,80,25,save_screen_buffer);
- /* speichere ganzen Bildschirm */
- _AX=0x0300;
- _BX=0x0000;
- geninterrupt(0x10); /* Hole Cursorposition und -form */
- cp_xy=_DX;
- cp_f=_CX;
- _AX=0x0100;
- _CX=0x0E0F;
- geninterrupt(0x10); /* Lösche Cursor weg */
- ClrScr(); /* Lösche Bildschirminhalt weg */
- screen_saved=1;
- }
-
- /* rest_screen : Restore Screen
- stellt den vorher mit save_screen() abgespeicherten
- Bildschirminhalt wieder her, einschl. des Cursors */
- void rest_screen (void)
- {
- screen_saved=0;
- puttext(1,1,80,25,save_screen_buffer); /* restore screen*/
- _AX=0x0200;
- _BX=0;
- _DX=cp_xy;
- geninterrupt(0x10); /* restore cursor position */
- _AX=0x0100;
- _CX=cp_f;
- geninterrupt(0x10); /* restore cursor form */
- }
-
- /* newkeyb : New keyboard interrupt
- flickt an den alten int 09h eine Routine an, die den
- Countdown für den Screen saver wieder auf den Initial-
- wert setzt und falls der Bildschirm schon gesichert
- worden ist, wird er durch rest_screen() wiederherge-
- stellt. */
- void interrupt newkeyb (void)
- {
- (*oldkeyb)(); /* Bearbeite erstmal den alten
- int 09h */
- countdown=cdinit; /* setzt countdown wieder hoch */
- if (screen_saved) /* falls Bildschirm gesichert
- wurde ... */
- rest_screen(); /* ... stelle Bildschirm wieder
- her */
- }
-
- /* newcons : New console interrupt
- arbeitet genauso wie newbeyb(), mit dem Unterschied,
- daß der Bildschirm wiederhergestellt werden muß
- bevor (!) der schreibende Zugriff auf den Bildschirm
- stattfindet. Die Parameter müssen angegeben werden, da
- der Softwareinterrupt 0x10 in den Registern Werte über-
- nimmt und zurückliefert, die durch die eingeschobene
- Routine zerstört werden. Auf diese Weise können die
- Register zum Eintritt in die alte Interruptroutine auf
- die richtigen Funktionswerte und bei der Rückkehr auf
- die richtigen Ergebniswerte gesetzt werden. Siehe auch
- Reference guide TURBO C.*/
- void interrupt newcons (unsigned bp, unsigned di,
- unsigned si, unsigned ds,
- unsigned es, unsigned dx,
- unsigned cx, unsigned bx,
- unsigned ax)
-
- {
- countdown=cdinit;
- if (screen_saved)
- rest_screen();
- _DX=dx;
- _CX=cx;
- _BX=bx;
- _AX=ax;
- (*oldcons)(); /* Aufruf alter int 10h */
- ax=_AX;
- bx=_BX;
- cx=_CX;
- dx=_DX;
- }
-
- /* newclock : New clock interrupt
- wird per Hardware 18.2 mal pro Sekunde aufgerufen und
- dient der Anzeige der Uhrzeit, dem Countdown für den
- Screen saver und der Darstellung des Laufpunktes, wenn
- der Screen Saver aktiv ist. */
- void interrupt newclock (void)
- {
- (*oldclock)(); /* Ruf' alten int 1Ch auf, falls
- andere residente Programme die-
- sen benötigen */
- disable(); /* Laß keine weiteren Interr. zu */
- if (clock_active) /* falls diese Routine bereits
- aktiv ... */
- {
- enable(); /* ... lasse Interrupts wieder
- zu ... */
- return; /* ... und kehre zurück */
- }
- clock_active = 1; /* sonst vermerke, daß diese Rou-
- tine aktiv ist ... */
- enable(); /* ... und lasse Interrupts wieder
- zu */
- if (!screen_saved) /* falls Bildschirm noch nicht
- gesichert ... */
- {
- if (countdown<0) /* ... und falls countdown auf 0
- runtergeszählt wurde */
- save_screen(); /* ... sichere Bildschirm */
- else
- if (saver_on) /* sonst falls Screen saver
- aktiv ... */
- countdown--; /* count down */
- }
- else /* Bildschirm gesichert, zeige
- laufendes '■' */
- {
- dispchar(' ', sscx, 24, 0x07);
- sscx = (sscx + 1) % 80 + 1;
- dispchar('■', sscx, 24, 0x07);
- }
- if (clock_on && !screen_saved) /* falls Uhr eingeschaltet
- und Bildschirm nicht
- gesichert */
- {
- disable();
- clock_active=1;
- CntVal=*CntPtr; /* Kopiere den Uhrzeitwert
- von DOS */
- enable(); /* ansonsten: */
- minutes=(int)(CntVal/1092); /* 60 s * 18.2 Ticks/s =
- 1092 Ticks */
- hours=minutes/60;
- tempminutes=minutes%60; /* = Minuten der angefange-
- nen Stunde */
- secs=(int)((CntVal*10-(unsigned long)minutes*10920)/182);
- /* = volle Sekunden */
- if (secs!=osecs) /* falls die Sekundenbe-
- rechnung das selbe Er-
- gebnis bringt, wie das
- letzte Mal braucht die
- ausgegebene Uhrzeit
- nicht korrigiert zu wer-
- den, sonst ... */
- {
- osecs=secs;
- if (hours>9) /* Hier wird "X . . "
- der Uhrzeitmaske besetzt */
- if (hours>19)
- *cl_line='2';
- else
- *cl_line='1';
- else
- *cl_line=' ';
- *(cl_line+1)=(hours%10)+48; /* hier " X. . " */
- *(cl_line+3)=(tempminutes/10)+48; /* jetzt " .X . " */
- *(cl_line+4)=(tempminutes%10)+48; /* usw. */
- *(cl_line+6)=(secs/10)+48;
- *(cl_line+7)=(secs%10)+48;
- dstr(cl_line,cl_pos_x,cl_pos_y,cl_col);
- /* Ausgabe unter der einstellbaren
- Position cl_pos_x,cl_pos_y und
- der Farbe cl_pos_col */
- }
- }
- disable();
- clock_active=0; /* Fertig */
- enable();
- }
-
- /* u_interf : User interface routine
- Diese Funktion ist die eigentliche Schnittstelle für
- das Modul UTILITY.BIN, das von dBASE/FoxBASE aus geladen
- wird. Da in den Registern DS:BX der Zeiger auf den über-
- gebenen String steht und UTILITY.BIN aus dem String die
- Funktionsmummer abspaltet und im Register AX einträgt,
- brauchen wir nur die drei Register AX,BX und DS an die
- Service Routine übergeben um das Gewünschte zu errei-
- chen. */
- void interrupt u_interf (unsigned bp, unsigned di,
- unsigned si, unsigned ds,
- unsigned es, unsigned dx,
- unsigned cx, unsigned bx,
- unsigned ax)
- {
- service(ds,bx,ax);
- }
-
- void main (int argc, char *argv[])
- {
- clrscr();
- /* Es folgt eine 'kurze' Meldung */
- cputs(" ╔═════════════════════════════════════════════"
- "═══════════════════════╗\r\n");
- cputs(" ║ Interface-Loader for dBASE/FoxBASE "
- " Vers. 1.2 ║\r\n");
- cputs(" ║ "
- " ║\r\n");
- cputs(" ║ Features: Clock, "
- " ║\r\n");
- cputs(" ║ Screen saver "
- " ║\r\n");
- cputs(" ║ Window handling "
- " ║\r\n");
- cputs(" ║ Printer driver "
- " ║\r\n");
- cputs(" ║ Cursor layout "
- " ║\r\n");
- cputs(" ║ Delay function "
- " ║\r\n");
- cputs(" ║ Access by interrupt 0x60, controlling int"
- " 0x09, 0x10, 0x1C. ║\r\n");
- cputs(" ║ "
- " ║\r\n");
- cputs(" ╚═════════════════════════════════════════════"
- "═══════════════════════╝\r\n");
- if (getvect(0x60)!=NULL) /* Prüfung ob Interrupt 60h
- bereits besetzt ist */
- cputs("Warnung int 60h in Benutzung, wird abgehängt");
- disable();
- setvect(0x60,u_interf); /* Setzen von int 60h auf die
- Funkt. u_interf() */
- oldclock=getvect(0x1C); /* Sichern der originalen Inter-
- ruptvektoren */
- oldkeyb=getvect(0x09);
- oldcons=getvect(0x10);
- setvect(0x09,newkeyb); /* Setzen der neuen Vektoren */
- setvect(0x10,newcons);
- setvect(0x1C,newclock);
- enable();
- gettextinfo(&ti); /* speziell für die Ermittlung
- der Bildschirmadresse */
- screen_init(); /* siehe Modul screenh.c */
- delay(1000); /* 1 Sekunde Verschnaufen um die
- Funktion delay() zu Kalibrieren
- (siehe Reference Guide TURBO C) */
- spawnvp(P_WAIT,argv[1],argv+1); /* lade das gewünschte
- Programm samt Parametern */
- if (temphandle) /* falls temporäre Datei geöffnet
- wurde ... */
- {
- close(temphandle); /* ... schließen und ... */
- unlink(tempname); /* ... löschen */
- }
- disable();
- setvect(0x60,NULL); /* Setze die originalen Vektoren
- wieder ein */
- setvect(0x1C,oldclock);
- setvect(0x09,oldkeyb);
- setvect(0x10,oldcons);
- enable();
- clrscr(); /* Lösche Bildschirm und Ende */
- }
- /* ------------------------------------------------------ */
- /* Ende von LOADER.C */
-
-