Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Subroutine ??

5 views
Skip to first unread message

David Solbach

unread,
Aug 31, 1999, 3:00:00 AM8/31/99
to
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 ?
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

unread,
Aug 31, 1999, 3:00:00 AM8/31/99
to
Warum? Das ist jedenfals einfacher als das Programm so zu programmieren, daß
periodisch eine Routine aufgerufen wird.
Wer's genau wissen will wie man den schwierigen Weg geht, dann mail an mich
und ich suche mir den Teil wieder heraus, denn aus dem Ärmel kann ich das
Wissen nicht mehr zaubern, da ich innerhalb 1 Jahr C++Programmierung unter
Win32 auf diesem Gebiet total verblödet bin und danach muß ich sagen: "Es
hat sich nicht gelohnt!"

Silvo.


David Solbach <va...@mabi.de> schrieb in im Newsbeitrag:
7qgb94$pbq$1...@surz18.HRZ.Uni-Marburg.DE...

Frederic

unread,
Aug 31, 1999, 3:00:00 AM8/31/99
to
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.

Sieh dir mal die online-Hilfe zu der Prozedur Keep an.


David Solbach

unread,
Aug 31, 1999, 3:00:00 AM8/31/99
to
Das is Schonmal schlecht, is naemlich ne grafische oberfläche !

--
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)

Silvo

unread,
Aug 31, 1999, 3:00:00 AM8/31/99
to
Denke an das InDos-Flag!
Bios-Funktionen gehen auch!
Außerdem will er 'ne Zeit ausgeben, das ist sowieso am effektivsten, wenn er
direkt auf den Speicher bei $b800 zugreift. Dies verhindert übrigens auch
gleich jegliches abstürzen, da man nicht ein anderes Code- oder Datensegment
benötigt.

Frederic

unread,
Aug 31, 1999, 3:00:00 AM8/31/99
to
David Solbach wrote:

> 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.


Klaus Loerke

unread,
Aug 31, 1999, 3:00:00 AM8/31/99
to

Frederic schrieb in Nachricht <37CC1CBD...@altavista.net>...
>David Solbach wrote:


>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

Silvo

unread,
Sep 1, 1999, 3:00:00 AM9/1/99
to
probiert's vielleicht mal hiermit!
Aber bitte kein flaming, fals die Unit nicht funzt!

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...

Wolf Behrenhoff

unread,
Sep 1, 1999, 3:00:00 AM9/1/99
to
Frederic wrote:

> ... 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

Wolf Behrenhoff

unread,
Sep 1, 1999, 3:00:00 AM9/1/99
to
David Solbach wrote:

> > 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


Silvo

unread,
Sep 1, 1999, 3:00:00 AM9/1/99
to
Nimm CMOS-Ports $70 und $71, da bekommste die Zeit direkt von der Uhr des
PC.


Wolf Behrenhoff <wolf.be...@gmxY.net> schrieb in im Newsbeitrag:
37CC635C...@gmxY.net...

Attila Kinali

unread,
Sep 1, 1999, 3:00:00 AM9/1/99
to
On Tue, 31 Aug 1999 10:37:24, "David Solbach" <va...@mabi.de> wrote:

> 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

Martin Beck

unread,
Sep 1, 1999, 3:00:00 AM9/1/99
to
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

Klaus Loerke

unread,
Sep 1, 1999, 3:00:00 AM9/1/99
to

Martin Beck schrieb in Nachricht <37CD7981...@gmx.de>...

>David Solbach wrote:
>Nicht ganz, ich würde einfach eine Hauptschleife machen, in der immer
>die Zeit aktualisiert wird, und dann, wenn irgendwelche Eingaben
>kommen, reagiert wird.
>

>[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


Silvo

unread,
Sep 2, 1999, 3:00:00 AM9/2/99
to
Wie sieht's denn mit Port $64 aus. Da kannste direkt ablesen, ob irgendein
Ereignis passiert ist. Jedoch klappt das nur wenn Du die
Tastaturinterruptroutine entweder ersetzt oder deaktivierst.


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

Martin Beck

unread,
Sep 2, 1999, 3:00:00 AM9/2/99
to
Klaus Loerke wrote:
>
> 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 ;-)
<g> Ich finde es ehrlich gesagt so aber besser, da es doch ziemliche
Arbeit für einen Anfänger ist, sich in den Timer-Interupt zu hängen.
An sich geht es natürlich schnell, aber ich finde man sollte auch ver-
stehen, was man macht. Und außerdem ist es doch ein guter Einstieg
in die weitere Programmierung, wenn man von den ReadLn's usw. weg-
kommt, da man später auch Programme hat, die nicht nur die Zeit
nebenbei anzeigen...

bye, Martin


Attila Kinali

unread,
Sep 3, 1999, 3:00:00 AM9/3/99
to
On Wed, 1 Sep 1999 19:29:05, "Klaus Loerke" <klaus....@muenster.de>
wrote:

> 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

Danilo Krahn

unread,
Dec 5, 1999, 3:00:00 AM12/5/99
to

Silvo schrieb:

>da ich innerhalb 1 Jahr C++Programmierung unter
>Win32 auf diesem Gebiet total verblödet bin und
>danach muß ich sagen: "Es hat sich nicht gelohnt!"

Was hat sich nicht gelohnt - die Win32-Programmierung ??

cu,
...Danilo Krahn


0 new messages