Ich hätt' da gern ma'n Problem mit BP7.0 :)
folgendes: gibt es eine möglichkeit eine prozedur sozusagen im hintergrund
laufen zu lassen, die z.b. immer die aktuelle uhrzeit auf dem bildschirm
ausgibt, auch während das programm zum beispiel auf ne eingabe wartet ?
ansonsten fällt mir da nur ein jedesmal wenn auf ne eingabe gewartet wird
und das prog damit angehalten ist ne
repeat
zeitausgabe;
until keypressed;
einzufügen, und das ist doch irgendwie ziemlich dämlich, oder ?!? :)
over
--
David Solbach aka VaDeR
--------------------------------
email: va...@mabi.de
icq# : 17414456
phone: 01702322156
Silvo.
David Solbach <va...@mabi.de> schrieb in im Newsbeitrag:
7qgb94$pbq$1...@surz18.HRZ.Uni-Marburg.DE...
> folgendes: gibt es eine möglichkeit eine prozedur sozusagen im hintergrund
> laufen zu lassen, die z.b. immer die aktuelle uhrzeit auf dem bildschirm
> ausgibt, auch während das programm zum beispiel auf ne eingabe wartet ?
Ja, geht. 18.2 mal in der Sekunde wird der sogenannte Timer-Interrupt
1Ch aufgerufen. Wenn du da eine Prozedur reinhängst, wird sie 18.2 mal
pro Sekunde aufgerufen.
Sieh dir mal die online-Hilfe zu der Prozedur Keep an.
--
David Solbach aka VaDeR
--------------------------------
email: va...@mabi.de
icq# : 17414456
phone : 01702322156
Wilfried Kramer <w...@VisionSystems.de> schrieb in im Newsbeitrag:
37cc0684...@BusinessNews.de.uu.net...
> On Tue, 31 Aug 1999 16:19:59 +0200, Frederic <f...@altavista.net>
> wrote:
>
> >David Solbach wrote:
> >
> >> folgendes: gibt es eine möglichkeit eine prozedur sozusagen im
hintergrund
> >> laufen zu lassen, die z.b. immer die aktuelle uhrzeit auf dem
bildschirm
> >> ausgibt, auch während das programm zum beispiel auf ne eingabe wartet ?
> >
> >Ja, geht. 18.2 mal in der Sekunde wird der sogenannte Timer-Interrupt
> >1Ch aufgerufen. Wenn du da eine Prozedur reinhängst, wird sie 18.2 mal
> >pro Sekunde aufgerufen.
> >
> Ja, aber!
> Mit der Ausgabe muß man schon vorsichtiger sein. Das ist dann eine
> Interrupt-Prozedur (Hardware Interrupt), und DOS und BIOS sind damit
> tabu.
> Im Textmodus mit der CRT-Unit ausgeben sollte klappen, aber Vorsicht
> mit GotoXY.
> Bei einer graphischen Oberfläche sieht das schon wieder ganz anders
> aus.
>
> >Sieh dir mal die online-Hilfe zu der Prozedur Keep an.
> >
>
> W. Kramer
>
> --
> ___________________________________________________
> VS Vision Systems GmbH, Industrial Image Processing
> Aspelohe 27A, D-22848 Norderstedt, Germany
> Tel.+49-40-5284010 Fax.+49-40-52840199
> Mailto:W...@VisionSystems.de* Wilfried Kramer
> HTTP://www.VisionSystems.de
> ---------------------------------------------------
> (privat unter whdk...@poboxes.com)
> also aus der hilfe zu der procedure keep schließe ich, das es damit nur
> möglich
> ist komplettes programm im hintergrund laufen zu lassen, nicht aber ne
> einzelne procedure
Falsch geschlossen. Vergiss das Keep einfach. Viel wichtiger in diesem Beispiel
sind GetIntVec/SetIntVec und der Zusatz "interrupt" einer Prozedur.
Im Grunde läuft das so ab: 18.2 mal pro Sekunde wird eine Routine aufgerufen,
dessen Adresse sich im Speicher bei $0000:$0070 befindet. Wenn du nun diese alte
Adresse durch die Adresse deiner Prozedur ersetzt, wird diese nunmehr 18.2 pro
Sekunde aufgerufen. Nun musst du berücksichtigen, daß jemand anderes auf die
selbe Idee wie du gekommen sein könnte und ebenfalls eine Prozedur auf diese
Weise installiert hat. Deshalb musst du unbedingt die alte Adresse speichern,
und am Ende deiner Prozedur einen Sprung zu der alten Adresse ausführen.
Eine solche Prozedur wird wie gewohnt deklariert, erhält aber den Zusatz
"interrupt". Dann gibt es noch einige Dinge zu berücksichtigen. Zum Beispiel
sollte man vermeiden, aus dieser Prozedur gewisse Interrupts aufzurufen. Nutze
also nicht writeln, sondern schreibe direkt in den Speicher. Um die Zeit zu
erfahren, nutzt du GetTime, das wiederum auf Interrupt 21h basiert. Eigentlich
sollte man GetTime also nicht nutzen - aber ich persönlich habe damit noch nie
Probleme gehabt, tu's also ruhig. Wenn jemand eine andere Möglichkeit kennt an
die Zeit ranzukommen - ich höre.
Also sollte das so aussehen:
uses crt, dos;
var
alte_adresse : procedure;
h, m, s, hun : word;
procedure Handler; interrupt;
begin
GetTime(h, m, s, hun);
mem[$B800:150] := h div 10 + 48;
mem[$B800:152] := h mod 10 + 48;
mem[$B800:154] := byte(':');
mem[$B800:156] := m div 10 + 48;
mem[$B800:158] := m mod 10 + 48;
alte_adresse
end;
begin
GetIntVec($1C, @alte_adresse);
SetIntVec($1C, addr(Handler));
repeat until readkey <> '';
SetIntVec($1C, addr(alte_adresse))
end.
>Wenn jemand eine andere Möglichkeit kennt an
>die Zeit ranzukommen - ich höre.
mit dem Biostimer bei 0h0040:0h006c könnt man was anfangen. (wird von
besagtem Interrupt inkrementiert), weiß zwar nicht, ob der Wert ne
Bedeutung hat, aber das kann man ja ändern... in sowas wie vergangene
0,055s (wer den genauen Wert kennt...) seit Mitternacht.
hth, klausi
Thomas.
Ps.: Ok, ok, es ist ein Binäry, aber wenn's hilft, warum nicht?
Anfang Quellcode:
======================================================
{$F+}
unit pit;
interface
var BIOSTimerHandler:procedure;
clock_ticks,counter:longint;
procedure Install_Routine(TimerHandler:pointer;frequency:word{Aufrufe pro
Sekunde});
procedure Uninstall_Routine;
implementation
Uses Crt, Dos;
{----------------------------------------------------------------------+
The clock_ticks variable will keep track of how many cycles the PIT has
had, it'll be intialised to 0. The counter variable will hold the new
channel 0 counter value. We'll also be adding this number to clock_ticks
every time our handler is called.
Next we need to do some initialization:
----------------------------------------------------------------------}
{ +---+---+---+---+---+---+---+---+
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
+-------------------------------+
+-+-+ +-+-+ +---+---+ +-- BCD 0 - Binary 16 bit
| | | 1 - BCD 4 decades
+----------------------+ | |
| Select Counter | | +---------- Mode Number 0 - 5
| 0 - Select Counter 0 | |
| 1 - Select Counter 1 | | +----------------------------+
| 2 - Select Counter 2 | | | Read/Load |
+----------------------+ | | 0 - Counter Latching |
+---------+ 1 - Read/Load LSB only |
| 2 - Read/Load MSB only |
| 3 - Read/Load LSB then MSB |
+----------------------------+
$34 - > 0 0 1 1 0 1 0 0
ú 0 -> - 16-Bit bin"r
ú 1 -> \
ú 2 -> - Modus 2 (Raten-Generator)
ú 3 -> /
ú 4 -> \
ú 5 -> / R/W lsb dann msb
ú 6 -> \
ú 7 -> / Counter 0 selektieren
}
procedure Install_Routine(TimerHandler : pointer; frequency : word);
begin
clock_ticks := 0;{init}
counter := $1234DD div frequency;
GetIntVec(8, @BIOSTimerHandler);{alte Routine}
SetIntVec(8, TimerHandler);{neue Routine setzen}
Port[$43] := $34;{Modus selektieren}
{Z"hler init : }
Port[$40] := counter mod 256;{Low-Byte}
Port[$40] := counter div 256;{High-Byte}
end;
{----------------------------------------------------------------------+
Pretty straightforward stuff. We save the address of the BIOS handler,
install our own, set up the variables we'll use and program PIT channel 0
for the divide-by-N mode at the frequency we need.
This next bit is what we need to do once our program is finished. It just
resets everything back to normal.
----------------------------------------------------------------------+}
procedure Uninstall_Routine;
begin
{ Restore the normal clock frequency }
Port[$43] := $34;
Port[$40] := 0;
Port[$40] := 0;
{ Restore the normal ticker handler }
SetIntVec(8, @BIOSTimerHandler);
end;
{----------------------------------------------------------------------+
Ok, here's our actual handler. This particular handler just writes an
asterix (*) to the screen. Then it does the checks to see if the BIOS
handler should be called. If so it calls it, if not it acknowledges the
interrupt itself.
----------------------------------------------------------------------+}
(*Beispiel :
1.Handler :
procedure Handler; Interrupt;
begin
{ DO WHATEVER WE WANT TO DO IN HERE }
Write('*');
{ Adjust the count of clock ticks }
clock_ticks := clock_ticks + counter;
{ Is it time for the BIOS handler to do it's thang? }
if clock_ticks >= $10000{18,2 mal je Sekunde die Zeit aktualisieren} then
begin
{ Yep! So adjust the count and call the BIOS handler }
clock_ticks := clock_ticks - $10000;
asm
pushf
end;
BIOSTimerHandler;
end
{ If not then just acknowledge the interrupt }
else
Port[$20] := $20;
end;
2.Hauptprogramm
{----------------------------------------------------------------------+
And finally our calling program. What follows is just an example program
which sets everything up, waits for us to press a key and then cleans up
after itself.
----------------------------------------------------------------------+}
begin
SetTimer(Addr(Handler),100);
ReadKey;
CleanUpTimer;
end.
*)
begin
end.
======================================================
Klaus Loerke <klaus....@muenster.de> schrieb in im Newsbeitrag:
7qhce4$m0g$2...@news.citykom.de...
> ... Um die Zeit zu
> erfahren, nutzt du GetTime, das wiederum auf Interrupt 21h basiert. Eigentlich
> sollte man GetTime also nicht nutzen - aber ich persönlich habe damit noch nie
> Probleme gehabt, tu's also ruhig. Wenn jemand eine andere Möglichkeit kennt an
> die Zeit ranzukommen - ich höre.
asm
mov al, 04h { Stunden ermitteln, 02h für Min, 00h für Sekunden }
out 70h, al
in al, 71h { Sekunden sind in al (gepacktes BCD-Format) }
mov ah, al { Sekunden in ah sichern }
shr al, 4 { BCD entpacken: 10er Stunden in al }
and ah, 0Fh { 1er Stunden in ah }
add ax, 3030h { in Zeichen umrechnen, ah und al+=Ord('0') }
ah und al irgendwo nach 0b800:2*irgendwas schreiben
end
Wolf
> > Mit der Ausgabe muß man schon vorsichtiger sein. Das ist dann eine
> > Interrupt-Prozedur (Hardware Interrupt), und DOS und BIOS sind damit
> > tabu.
> > Bei einer graphischen Oberfläche sieht das schon wieder ganz anders
> > aus.
> Das is Schonmal schlecht, is naemlich ne grafische oberfläche !
Auch dann kann man direkt in den Speicher schreiben, der dann (VGA) bei
A000:0 beginnt. Vielleicht schreibt der BGI-Treiber auch direkt?
Sollte es ein Windows-Programm sein, könnte es vielleicht eine Art
Timer-Komponente wie bei Delphi geben (Keine Ahnung, ob sowas bei BP für
Win auch möglich ist).
Ach, bitte nicht immer alles vom Vorgänger hinter der eigentlichen
Nachricht quoten, sondern nur den _relevanten Teil_, und _vor_ der
Nachricht. Danke.
Wolf
Wolf Behrenhoff <wolf.be...@gmxY.net> schrieb in im Newsbeitrag:
37CC635C...@gmxY.net...
> Hai,
>
> Ich hätt' da gern ma'n Problem mit BP7.0 :)
>
> folgendes: gibt es eine möglichkeit eine prozedur sozusagen im hintergrund
> laufen zu lassen, die z.b. immer die aktuelle uhrzeit auf dem bildschirm
> ausgibt, auch während das programm zum beispiel auf ne eingabe wartet ?
Ich würd mich da in den Timer-Int (Int 8h) reinhängen und alle, sagen
wir mal, 20 Aufrufe die neue Zeit ausgeben. Ist aber nicht das
einfachste was man so als Fingerübung macht.
Attila Kinali
PS: Mache bei x-postings ein Followup auf eine NG
> folgendes: gibt es eine möglichkeit eine prozedur sozusagen im hintergrund
> laufen zu lassen, die z.b. immer die aktuelle uhrzeit auf dem bildschirm
> ausgibt, auch während das programm zum beispiel auf ne eingabe wartet ?
> ansonsten fällt mir da nur ein jedesmal wenn auf ne eingabe gewartet wird
> und das prog damit angehalten ist ne
>
> repeat
> zeitausgabe;
> until keypressed;
>
> einzufügen, und das ist doch irgendwie ziemlich dämlich, oder ?!? :)
Nicht ganz, ich würde einfach eine Hauptschleife machen, in der immer
die Zeit aktualisiert wird, und dann, wenn irgendwelche Eingaben
kommen, reagiert wird.
repeat
ZeitAusgabe;
if KeyPressed then
begin
c:=ReadKey;
...
end;
until ProgrammEnde;
Falls du aber aufwendige Rechensachen machen willst, und nicht nur
auf die Eingabe warten, sind die Vorschläge mit dem Timerinterrupt
besser.
hth, Martin
>[Schleife]
>
>Falls du aber aufwendige Rechensachen machen willst, und nicht nur
>auf die Eingabe warten, sind die Vorschläge mit dem Timerinterrupt
>besser.
>
Da haste ja schon den Grundstein für ein _komplett_ ereignisgesteuertes
Programm gelegt. Damit fallen dann sämtliche Eingaben über readln weg.
Kann man machen, sicherlich <ggggg> Fraglich, ob es sich lohnt, so nen
Projekt in Angriff zu nehmen, nur um die Zeit immer aktualisiert auf dem
Bildschirm zu haben ;-)
so far, klausi
Martin Beck <Spix...@gmx.de> schrieb in im Newsbeitrag:
37CD7981...@gmx.de...
> David Solbach wrote:
> >
> > Hai,
> Moin.
>
> > folgendes: gibt es eine möglichkeit eine prozedur sozusagen im
hintergrund
> > laufen zu lassen, die z.b. immer die aktuelle uhrzeit auf dem bildschirm
> > ausgibt, auch während das programm zum beispiel auf ne eingabe wartet ?
> > ansonsten fällt mir da nur ein jedesmal wenn auf ne eingabe gewartet
wird
> > und das prog damit angehalten ist ne
> >
> > repeat
> > zeitausgabe;
> > until keypressed;
> >
> > einzufügen, und das ist doch irgendwie ziemlich dämlich, oder ?!? :)
> Nicht ganz, ich würde einfach eine Hauptschleife machen, in der immer
> die Zeit aktualisiert wird, und dann, wenn irgendwelche Eingaben
> kommen, reagiert wird.
>
> repeat
> ZeitAusgabe;
> if KeyPressed then
> begin
> c:=ReadKey;
> ...
> end;
> until ProgrammEnde;
>
> Falls du aber aufwendige Rechensachen machen willst, und nicht nur
> auf die Eingabe warten, sind die Vorschläge mit dem Timerinterrupt
> besser.
>
> hth, Martin
bye, Martin
> Da haste ja schon den Grundstein für ein _komplett_ ereignisgesteuertes
> Programm gelegt. Damit fallen dann sämtliche Eingaben über readln weg.
> Kann man machen, sicherlich <ggggg> Fraglich, ob es sich lohnt, so nen
> Projekt in Angriff zu nehmen, nur um die Zeit immer aktualisiert auf dem
> Bildschirm zu haben ;-)
>
Das bringt mich auf die Idee, dass man das eigentlich auch mit TV
machen könnte. Da hat man das Problem mit dem Blockieren bei der
Eingabe nicht und könnte die Zeitausgabe in ein HandleEvent
reinhängen. Und das ganze währe noch sehr simpel (sofern man schon was
in TV gemacht hat)
Attila Kinali
Was hat sich nicht gelohnt - die Win32-Programmierung ??
cu,
...Danilo Krahn