ΠΕΡΙΕΧΟΜΕΝΑ
ΣΤ. SYSTEM RELATED FUNCTIONS
Το
πρωτότυπό της βρίσκεται στο <dos.h> :
void sleep(unsigned
timeinsec)
Καθυστερεί
την εκτέλεση του προγράμματος για timeinsec αριθμό
δευτερολέπτων.
Π.χ.: #include<dos.h>
#include<stdio.h>
main( )
{
printf(“Hello”);
sleep(10);
printf(“There”);
}
Θα
προκαλέσει delay 10
δευτερολέπτων μεταξύ των μηνυμάτων.
Τα
πρωτότυπά τους βρίσκονται στο <dir.h> :
void getdate(struct date *d) / void gettime(struct
time *t)
Η getdate γεμίζει τη δομή date με την τρέχουσα ημερομηνία του συστήματος, ενώ η gettime γεμίζει τη δομή time με την τρέχουσα ώρα.
Π.χ.: struct time dos_time;
struct date dos_date;
getdate(&dos_date) ;
gettime(&dos_time) ;
Το πρωτότυπό της βρίσκεται στο <time.h> : doube
difftime( time_t time2, time_t time1)
Επιστρέφει
τη διαφορά σε δευτερόλεπτα την ώρας time2 από την time1, δηλαδή εκτελεί την διαφορά time2 – time1 και
επιστρέφει έναν double που
εκφράζει seconds.
Π.χ.: #include<time.h>
#include<stddef.h>
main( )
{
time_t
start, end;
long
unsigned int t;
start
= time(NULL);
for(
t=o, t<500000; t++);
end
= time(NULL);
printf(“loop
required %f seconds \n”, difftime(end, start));
}
Το
παράδειγμα αυτό θα εμφανίσει loop
required 3.00000 seconds ( σε έναν IBM Model – 60).
Τα
πρωτότυπά τους βρίσκονται στο <dos.h> :
void setdate(struct date *d) / void settime (struct
time *t)
Θέτει
(αλλάζει) την ώρα του συστήματος σε μία ώρα που εμείς θέλουμε:
Π.χ.: struct time_t;
t.ti_hour=10;
t.ti_min=10;
t.ti_sec=10;
t.ti_hund=0 ;
settime(&t);
Θα θέσει την ώρα του συστήματος
στην 10:10:10:00.
Το
πρωτότυπό της βρίσκεται στο <bios.h> :
long biostime(int cmd, long newitme)
Διαβάζει το ρολόι του BIOS. Το ρολόι του BIOS χτυπά σε μία συχνότητα περίπου 18.2 tick / sec. Η τιμή του είναι 0 τα μεσάνυχτα και αυξάνεται έως ότου μηδενιστεί ξανά τα επόμενα μεσάνυχτα ή έως ότου τεθεί σε κάποια τιμή. Αν το cmd είναι 0 η biostime( ) επιστρέφει την τρέχουσα τιμή του timer στην τιμή του newtime.
Π.χ.: #include<bios.h>
main( )
{
printf(“The
current timer value is %ld”, biostime0.0);
}
Τα
πρωτότυπά τους βρίσκονται στο <dos.h> :
int absread( int drive, int numsects, int secetnum,
void *buf)
int absread( int drive, int numsects, int secetnum,
void *buf)
Εκτελούν
απόλυτο διάβασμα και γράψιμο δίσκου. Προσπερνούν τη λογική δομή του δίσκου και
αγνοούν αρχεία και καταλόγους. Το drive ορίζεται
σαν 0 για το Α, κλπ. Ο αριθμός των sectors για
διάβασμα ή γράψιμο ορίζεται από την παράμετρο numsects και οι πληροφορίες διαβάζονται στο ή από το τμήμα της
μνήμης που δείχνεται από το buf.
Οι
συναρτήσεις αυτές επιστρέφουν 0 για επιτυχία ή nonzero σε αποτυχία. Οι τιμές που επιστρέφονται ορίζονται από το DOS και θα χρειαστεί να
ανατρέξουμε σε τεχνικά εγχειρίδια του DOS για να
προσδιορίσουμε τη φύση των λαθών που προκύπτουν.
Φυσικά
η abswrite θα πρέπει
να καλείται με προσοχή γιατί είναι εύκολο να καταστρέψουμε το δίσκο ή αρχεία με
τη χρήση της.
Π.χ.: #include<dos.h>
main( )
{
char
buf [512];
int
sector, i, j;
for
(;;)
{
printf(“Enter
Sector:”);
scanf(
“%d”, §or);
if
(sector ==-1) exit(0);
absread(3,1,sector,
buf);
for
(i=0, j=0; i<512; i++)
{
printf(“%x”,
buf[i]);
if(!(i%16));
{
for
(;j<i; ++) printf(“%c”, buf[ j ];
printf(“\n”);
} / * Ends if
*/
} / *
Ends for * /
} / * Ends infinite loop * /
} /
* Ends main * /
Το
πρόγραμμα αυτό διαβάζει έναν σέκτορα από τον σκληρό και τον εμφανίζει στην
οθόνη σε δεκαεξαδική και μορφή χαρακτήρα.
Το
πρωτότυπό της βρίσκεται στο <dos.h> :
void getdfree ( int drive, struct dfree *dfptr)
Επιστρέφει
το σύνολο του ελεύθερου δίσκου σε μία δομή η οποία δείχνεται από τον pointer dfptr. Τα drive ξεκινούν
από 1 για το Α, κλπ. Η δομή είναι:
struct dfree {
unsigned
df_avail; / * unused clusters */
unsigned
df_total; / * total no of
clust * /
unsigned
df_bsec; / * no of bytes per
sect * /
unsigned
df_sclus; / * no of sect per
clust * /
}
Αν
παρουσιαστεί ένα σφάλμα το df_clust τίθεται στο – 1.
Π.χ.: #include<dos.h>
Main(
)
{
struct
dfree p;
getdfree(3,
&p); / * Drive C * /
printf
( “No of free clusters is %d”, p.df_avail);
}
Τα
πρωτότυπά τους βρίσκονται στο <dos.h> :
void getfat( int drive, struct fatinfo *fptr)
void getfatd( struct fatinfo *fptr)
H
getfat( ) επιστρέφει διάφορες
πληροφορίες για τη δισκέτα στο drive, οι
οποίες αποτελούνται από το FAT. Αν η
τιμή είναι 0 αναφερόμαστε στο default
drive, αν είναι 1, στο Α, κλπ.
Η
δομή fatinfo ορίζεται
ως εξής:
struct fatinfo {
char
fi_sclus; / * no of sectors per cluster *
/
char
fi_fatid; / * FAT ID * /
int
fi_nclus; / * total no of clusters *
/
int
fi_bysec; / * no of bytes per sector *
/
}
Η
συνάρτηση getfatd( )
εκτελεί τις ίδιες λειτουργίες με την getfat( ) με τη
διαφορά ότι χρησιμοποιεί πάντα το default
drive.
Π.χ.: #include<dos.h>
main(
)
{
long
total;
struct
fatinfo p;
getfat(
0, &p);
total
= (long) p. fi_sclus*(long) p. fi_nclus * (long) p. fi_bysec;
printf
( “Total storage capacity : %d”, total);
}
Το
πρόγραμμα αυτό εμφανίζει τη συνολική χωρητικότητα του default drive σε bytes. Παρατηρούμε ότι στον υπολογισμό του total χρησιμοποιούμε casts για τη μετατροπή των ακέραιων τιμών του structure σε long. Βασικά αυτό θα μπορούσε να παραλειφθεί μια και η Turbo C δεν το απαιτεί, αφού ήδη η μεταβλητή total έχε δηλωθεί σαν long. Απλά αναφέρεται γιατί η C++ το απαιτεί, αλλά και για
καλύτερη κατανόηση του κώδικα.
Το
πρωτότυπό της βρίσκεται στο <dos.h> :
int getftime ( int handle, struct ftime *ftptr)
Επιστρέφει
την ώρα και ημερομηνία λειτουργίας ενός αρχείου, το όνομα του οποίου σχετίζεται
με το handle. Οι πληροφορίες «φορτώνονται»
στη δομή που δείχνεται από τον pointer
ftptr.
Η
δομή ftime ορίζεται στη συνάρτηση ως
εξής:
struct ftime {
unsigned
ft_tsec:5; / * seconds * /
unsigned
ft_min:6; / * minutes * /
unsigned
ft_hour:5; / * hours * /
unsigned
ft_day:5 / * days * /
unsigned
ft_month:4; / * month * /
unsigned
ft_year:7; / * year from 1980 * /
}
Η
getftime( )
επιστρέφει 0 σε επιτυχία. Αν προκληθεί λάθος επιστρέφει –1 και θέτει το errno ή σε EINVFNC (invalid function number) ή σε EBADF (bad
file number).
Υπενθυμίζεται
ότι τα αρχεία που σχετίζονται με file
descriptions (handles), χρησιμοποιούν το UNIX – like
I/O system, το οποίο
δεν ορίζεται από το ANSI standard.
Π.χ.: #include<io.h>
#include<dos.h>
#include<fnctl.h>
main( )
{
struct
ftime p;
int fd;
if(
( fd = open ( “TEST.TST”, O_RDONLY) ) == - 1 )
{
printf(
“cannot open file… “);
exit(1);
}
getftime
(fd, &p);
printf(“%d”,
p.ft_year+1980);
}
Το
παραπάνω πρόγραμμα εμφανίζει το έτος δημιουργίας του αρχείου TEST.TST.
Το
πρωτότυπό της βρίσκεται στο <dos.h> :
void keep ( int status, int size)
Η
συνάρτηση keep( )
εκτελεί το interrupt 0x31, το οποίο αναγκάζει το τρέχον πρόγραμμα να
τερματιστεί, αλλά να παραμείνει resident στη μνήμη
(T.S.R. = Terminate and Stay
Resident). Η τιμή
του status επιστρέφεται στο DOS σαν επιστρεφόμενος κωδικός. Το size του προγράμματος, που μένει
resident,
καθορίζεται στο size. Η
υπόλοιπη μνήμη ελευθερώνεται για χρήση από το DOS.
Επειδή
το αντικείμενο των TSR’s προγραμμάτων είναι αρκετά περίπλοκο δεν
παρουσιάζεται παράδειγμα εδώ. Ο ενδιαφερόμενος αναγνώστης μπορεί να αναφερθεί
στο βιβλίο:
C: Power User’s
Guide
(by Herbert Schildt, Osborne / Mc
Graw-Hill, 1987)
Πάντως,
αναφέρουμε ότι σχετιζόμενη με την keep( )
συνάρτηση είναι η geninterrupt( ).
11. peek( ) / peekb( ) / poke( ) / pokeb( )
Τα
πρωτότυπά τους βρίσκονται στο <dos.h> :
int peek ( int seg, unsigned offset)
char peekb ( int seg, unsigned offset)
void poke (int seg, unsigned offset, int word)
void pokeb (int seg, unsigned offset, char byte)
Βασικά
αποτελούν macros κι όχι
συναρτήσεις.
-
peek( ) :
Επιστρέφει μία 16-bit τιμή, που
βρίσκεται στη μνήμη, στο σημείο seg:offset.
-
peekb( ) :
Επιστρέφει μία 8-bit τιμή, που
βρίσκεται στη μνήμη, στο σημείο seg:offset.
-
poke( ) :
Αποθηκεύει μία 16-bit τιμή (την
τιμή word), στη διεύθυνση μνήμης seg:offset.
-
pokeb( ) :
Αποθηκεύει μία 8-bit τιμή (την
τιμή byte), στη διεύθυνση μνήμης seg:offset.
Π.χ.: #include<dos.h>
main(
)
{
printf( “%d”, peekb ( 0,0x0100) );
}
Το
παραπάνω πρόγραμμα εμφανίζει στην οθόνη την τιμή του byte που βρίσκεται στη διεύθυνση μνήμης 0000:0100.
Το
πρωτότυπό της βρίσκεται στο <bios.h> :
int biosmemory (void)
Επιστρέφει
το σύνολο της μνήμης (RAM) σε
μονάδες του 1ΚΒ.
Π.χ.: #include<bios.h>
main(
)
{
printf( “%bKB of RAM, biosmemory( ) );
}
Το
πρωτότυπό της βρίσκεται στο <bios.h> :
int biosprint (int cmd, int byte, int port)
Ελέγχει
την πόρτα του εκτυπωτή η οποία ορίζεται στο port. Αν η θύρα είναι 0, εννοείται η LPT1, ενώ αν είναι 1 η LPT2. Οι ενέργειες της συνάρτησης λαμβάνουν χώρα πάνω στο cmd. Οι αποδεκτές τιμές του cmd είναι:
Τιμή
0 1 2 |
Έννοια
Print the character in byte Initialize the Printer Port Return the status of the port |
Το printer-port status
κωδικοποιείται από το low-order byte της επιστρεφόμενης τιμής ως εξής:
0 1 2 3 4 5 6 7 8 |
|
Time-Out Error Unused Unused Unused I/O Error Printer Selected Out-of-paper Error Acknowledge Print No Busy |
Π.χ.: char p[ ] = “hello”;
while (*p) biosprint (0, *p++, 0);
Το
παραπάνω τμήμα κώδικα τυπώνει το string “hello” στον εκτυπωτή που είναι συνδεδεμένος στο LPT1.
Το
πρωτότυπό της βρίσκεται στο <bios.h> :
int biosequip (void)
Επιστρέφει
τον εξοπλισμό του συστήματος σε μία τιμή των 16-bit. Η κωδικοποίηση της τιμής είναι η εξής:
0
Must boot
from floppy drive
1
80x86 math
co. installed
2,3 Motherboard
RAM size
00
: 16KB
01
: 32KB
10
: 48KB
11
: 64KB
4,5 Initial
Video Mode
00
: Unused
01
: 40x25 BW, color adapter
10
: 80x25 BW , color adapter
11 : 80x25, monochrome adapter
6,7 Number
of FDDs
00 : One
01 :
Two
10 :
Three
11 : Four
8
DMA chip
installed
9, 10, 11 Number
of serial ports
000
: Zero
001
: One
010
: Two
011:
Three
100
: Four
101
: Five
110
: Six
111
: Seven
12
Game
adapter installed
13
Serial
printer installed (PCjr only)
14, 15 Number
of printers
00
: Zero
01
: One
10 : Two
11
: Three
Π.χ.: #include <bios.h>
main(
)
{
unsigned
eq;
eq
= biosequip( );
eq>>6; / * Shifts bits 6 and 7 into lowest position
* /
printf
(“No of FDDs : %d”, eq+1);
}
Το παραπάνω παράδειγμα εμφανίζει
τον αριθμό των floppy
drives που είναι εγκατεστημένα
στον Η/Υ.
Το
πρωτότυπό της βρίσκεται στο <bios.h> :
int bioscom (int
cmd, char byte, int port)
Χρησιμοποιείται
για να ελέγχει την RS – 232 asynchronous communication port, η οποία
ορίζεται στο port. Η χρήση
γίνεται σε σχέση με την τιμή της cmd, η οποία
παίρνει τιμές ως εξής:
Εντολή 0 1 2 3 |
Έννοια Initialize the port Send a character Receive a character Return the port status |
Πριν τη
χρήση της RS – 232
πιθανόν να θέλουμε να αρχικοποιήσουμε τη θύρα με τιμή άλλη από το default setting. Για να γίνει αυτό πρέπει
να καλέσουμε τη bioscom( ) με τη cmd = 0.
Ο ακριβής τρόπος για να γίνει setup στη θύρα δείχνεται από την τιμή του byte. Η κωδικοποίηση του byte είναι η εξής:
Bit Numbers 7, 6, 5 4, 6 2 1, 0 |
Initialization Baud Parity Stop bits Data bits |
Τα baud κωδικοποιούνται ως εξής:
Baud 9600 4800 2400 1200 600 300 150 100 |
Bit Pattern
1 1 1 1 1 0 1 0 1 1 0 0 0 1 1 0 1 0 0 0 1 0 0 0 |
Το
parity κωδικοποιείται
ως εξής:
Parity No parity Odd Even |
Bit Pattern
0 0 ή 1
0 0 1 1 1 |
Υπενθυμίζεται
ότι το parity ελέγχει την ορθότητα του byte. Αυτό γίνεται με την εξής λογική: ελέγχεται το
άθροισμα των ενεργών bit
(1) μέσα στο byte και αν είναι Odd ή Even
επιστρέφεται True ή False (αν είναι false, έχουμε error και
γίνεται retransmit). Το Odd ή Even ορίζεται από τον προγραμματιστή ανάλογα με το
σύστημα.
Ο
αριθμός των stop bits καθορίζεται από το bit 2, κατά τη διάρκεια τη αρχικοποίησης της serial port. Αν είναι 1, τότε χρησιμοποιούνται 2 stop bits, αλλιώς 1 stop
bit χρησιμοποιείται.
Τέλος,
ο αριθμός των data bits ορίζεται από τα δύο τελευταία bits. Αυτά κωδικοποιούνται ως εξής:
1 0 à 7 data bit
used
1 1 à 8 data bit
used
Οι
υπόλοιποι συνδυασμοί είναι άκυροι.
Π.χ.: Αν θέλουμε να αρχικοποιήσουμε την RS – 232 με το παρακάτω configuration: 9600 Baud, Even Parity, 1 Stop
Bit, 8 Data Bit…
Θα
πρέπει στη θέση του byte να
βάλουμε τον αριθμό 251. Αυτό γίατί:
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
= 251 Δεκαδικό |
1 |
1 |
1 |
1 |
1 |
0 |
1 |
1 |
|
9600 Baud |
Even Parity |
1 stop |
8 data bits |
Η τιμή που επιστρέφει η bioscom( ), είναι μία 16-bit ποσότητα. Το high-order byte περιέχει τα status bits
και αυτά κωδικοποιούνται ως εξής:
Meaning when set Data ready Overrun Error Parity Error Frdming Error Break-detect Error Transfer holding register empty Transfer shift register empty Time – Out
Error |
Bit 0 1 2 3 4 5 6 7 |
Αν το cmd είναι 0,1 ή 3, το low-order byte κωδικοποιείται ως εξής:
Meaning when set
Change in clear-to-send Change in data-set-ready Trailing-edge ring detector Change in line signal Clear-to-send Data-set-ready Ring indicator Line signal detected |
Bit
0 1 2 3 4 5 6 7 |
Αν το cmd είναι 2, τότε το low-order byte περιέχει την τιμή που
διαβάζεται από τη θύρα.
Π.χ.: Στο προηγούμενο παράδειγμα η εντολή θα
είναι: bioscom( 0, 251, 0);
Το
πρωτότυπό της βρίσκεται στο <bios.h> :
int bioskey (int
cmd)
Εκτελεί
κατ’ ευθείαν διαδικασίες του πληκτρολογίου. Η τιμή του cmd διευκρινίζει τι είδους λειτουργία εκτελείται.
Αν
το cmd είναι 0, η bioskey( ) επιστρέφει το επόμενο πλήκτρο
που θα πατηθεί (καθαρίζει τον buffer και περιμένει
να πατηθεί ένα πλήκτρο). Επιστρέφει μία 16 – bit τιμή, η οποία περιλαμβάνει δύο διαφορετικά πράγματα. Το low-order
byte περιέχει τον ASCII κωδικό του χαρακτήρα που
καταχωρήθηκε, αν έχει πατηθεί ένα normal-key. Αν όμως έχει πατηθεί ένα special-key, θα
περιέχει 0 (special-keys είναι τα βελάκια, τα F-keys, κλπ). Το
high-order byte περιέχει
τον scan-code του πλήκτρου.
Αν
το cmd είναι 1, ελέγχει αν έχει
πατηθεί από πριν ένα πλήκτρο (ελέγχει τον keyboard-buffer, αν περιέχει
κάτι). Αν βρεθεί περιεχόμενο στον buffer,
επιστρέφει nonzero, αλλιώς
0.
Αν
το cmd είναι 2, επιστρέφεται το shift-status. Βασικά
ελέγχει αν έχει πατηθεί μαζί με ειδικό χαρακτήρα κάποιο shift-key. Το shift-status
κωδικοποιείται στο low-order byte ως εξής:
Bit 0 1 2 3 4 5 6 7 |
Έννοια
Right Shift pressed Left Shift pressed CTRL pressed ALT pressed SCROLL LOCK on NUM LOCK on CAPS LOCK on Insert on |
Π.χ.: #include <bios.h>
#include
<stdio.h>
main(
)
{
int
i, j;
clrscr(
);
do
{
i
= bioskey(0);
j
= bioskey(2);
printf(“%d---%x---%c\n,
,j, j, j);
while(i!=283);
}
Το
πρόγραμμα αυτό ελέγχει αν έχει πατηθεί κάποιο shift key και
τερματίζεται αν πατηθεί esc.
Π.χ.: #include <bios.h>
#include
<stdio.h>
main(
)
{
int
i;
clrscr(
);
do
{
i
= bioskey(0);
printf(“%d---%x---%c\n,
,i, i, i);
while(i!=283);
}
Ελέγχει
αν έχει πατηθεί πλήκτρο (ακόμα και ειδικό) και επιστρέφει την τιμή του σε
δεκαδικό, δεκαεξαδικό σύστημα και σε μορφή ASCII χαρακτήρα. Σταματάει αν πατηθεί esc. Το esc είναι
ειδικό πλήκτρο και η τιμή του είναι 283.