Show the time in several formats.
The program below reads the time from the hardware clock (mostly a DS 1287 or compatible chip) and shows it on screen. The format is either text, or numeric. In the latter case, only the numbers from the clock registers are put on screen.The program is simple and easy. Just sit behind iut after you printed and see how far you come.
I won't spoil the source with comments and remarks. So if you want the source, just cut and paste it from the screen.
MODULE Datum;
(* Show the date and time of the system clocks.
One option is to use the DOS software clock and the other uses the RTC chip.
A future version should be able to set the RTC.
CopyLeft 2000, Jan Verhoeven. This is GNU GPL software
*)
FROM SYSTEM IMPORT ASSEMBLER;
FROM System IMPORT Terminate, GetArg;
FROM Strings IMPORT Assign, CompareStr;
FROM Xchar IMPORT UpperString;
FROM InOut IMPORT Write, WriteCard, WriteLn, WriteString, WriteLine, WriteHex;
FROM Keyboard IMPORT GetKey, KeyPressed;
CONST Tab = 09X;
TYPE RegisterMode = (BCD, Binary);
HourMode = (AMPM, Digital);
VAR Second, Minute, Hour,
Day, DoW, Month, Year,
Century, RegB,
Count : CARDINAL;
Option : ARRAY [0..20] OF CHAR;
DataMode : RegisterMode;
TimeFormat : HourMode;
PROCEDURE ReadRTC (Register : CARDINAL) : CARDINAL;
(* Read one byte from specified register from RTC *)
VAR Result : CARDINAL;
BEGIN
ASM
MOV AL, Register
OUT 70H, AL
IN AL, 71H
MOV AH, 00
MOV Result, AX
END;
RETURN Result
END ReadRTC;
PROCEDURE WriteRTC (Register, Value : CARDINAL);
(* Write Value to specified Register of RTC *)
BEGIN
ASM
MOV AL, Register
OUT 70H, AL
MOV AL, Value
OUT 71H, AL
END;
END WriteRTC;
PROCEDURE SetRtc; (* Write current date and time to the RTC chip *)
VAR OldRegB, (* Register B value *)
Value : CARDINAL; (* Temporary value *)
BEGIN
OldRegB := ReadRTC (11);
Value := OldRegB; INC (Value, 128);
WriteRTC (11, Value ); (* Disable clock actions *)
WriteRTC ( 0, Second );
WriteRTC ( 2, Minute );
WriteRTC ( 4, Hour );
WriteRTC ( 6, DoW );
WriteRTC ( 7, Day );
WriteRTC ( 8, Month );
WriteRTC ( 9, Year );
WriteRTC (50, Century);
WriteRTC (11, OldRegB); (* Re-Enable clock actions *)
END SetRtc;
PROCEDURE Convert (Value : CARDINAL; Mode : RegisterMode; Format : HourMode) : CARDINAL;
BEGIN
IF Format = AMPM THEN
IF 7 IN BITSET (Value) THEN DEC (Value, 116) END
END;
IF Mode = BCD THEN
RETURN (Value MOD 16) + 10 * (Value DIV 16)
ELSE
RETURN Value
END
END Convert;
PROCEDURE GetRtc;
(* Read the current date and time from the RTC chip *)
BEGIN
RegB := ReadRTC (11);
IF 1 IN BITSET (RegB) THEN (* Check 24/12 bit *)
TimeFormat := Digital
ELSE
TimeFormat := AMPM
END;
IF 2 IN BITSET (RegB) THEN (* Check DM bit *)
DataMode := Binary
ELSE
DataMode := BCD
END;
Second := Convert (ReadRTC (0), DataMode, TimeFormat);
Minute := Convert (ReadRTC (2), DataMode, TimeFormat);
Hour := Convert (ReadRTC (4), DataMode, TimeFormat);
DoW := Convert (ReadRTC (6), DataMode, TimeFormat);
Day := Convert (ReadRTC (7), DataMode, TimeFormat);
Month := Convert (ReadRTC (8), DataMode, TimeFormat);
Year := Convert (ReadRTC (9), DataMode, TimeFormat);
Century := Convert (ReadRTC (50), DataMode, TimeFormat);
WriteCard (Second, 8); WriteCard (Minute, 8);
WriteCard (Hour, 8); WriteCard (DoW, 8);
WriteCard (Day, 8); WriteCard (Month, 8);
WriteCard (Year, 8); WriteCard (Century,8); WriteLn;
IF Century = 19 THEN
INC (Year, 1900);
ELSE
INC (Year, 2000);
END;
END GetRtc;
(* PROCEDURE GetDos (VAR Month, Day, DoW, Year, Hour, Minute, Second : CARDINAL); *)
PROCEDURE GetDosData;
(* Read date and time from DOS clock. *)
BEGIN
ASM
MOV AH, 2AH
INT 21H
MOV Month, DH
MOV Day, DL
MOV DoW, AL
MOV Year, CX
MOV AH, 2CH
INT 21H
MOV Hour, CH
MOV Minute, CL
MOV Second, DH
END;
END GetDosData;
PROCEDURE SetDosData (Month, Day, DoW, Year, Hour, Minute, Second : CARDINAL);
(* Set date and time with DOS clock. *)
BEGIN
ASM
MOV DH, Month
MOV DL, Day
MOV CX, Year
MOV AH, 2BH
INT 21H
MOV CH, Hour
MOV CL, Minute
MOV DH, Second
MOV AH, 2DH
INT 21H
END;
END SetDosData;
PROCEDURE UpperCase (VAR String : ARRAY OF CHAR);
(* Convert string to uppercase characters only *)
VAR n : CARDINAL;
BEGIN
FOR n := 0 TO HIGH (String) DO
String [n] := CAP (String [n]);
END
END UpperCase;
PROCEDURE UserMessage (Code : CARDINAL);
BEGIN
CASE Code OF
1 : WriteLine ("Invalid number in day of week register.");
|
2 : WriteLine ("Invalid month specified. Please call a mechanic.");
|
3 : WriteLine ("Empty command line entered. Assuming help is needed.");
WriteLn;
|
4 : WriteLine ("Please use the following format:");
WriteLn; Write (Tab);
WriteLine ("DATUM {= <date/time}, {DOS}, {RTC}, {SET <date/time>}, {SHOW}, {HELP}");
WriteLn;
WriteLine ("Separate each argument with a space please.");
WriteLine ("Use it in any sensible combination, even such as DATUM DOS = RTC.");
|
5 : WriteLn;
WriteLine ("Thank you for using this program. It is published under the rules of the");
WriteLine ("GNU GPL, of which you should have received a copy with this program.");
WriteLine ("If you need more information, please issue a DATUM SHOW command.");
|
6 : WriteLn;
WriteLine ("Howdy y'all! This program was made by:"); WriteLn; Write (Tab);
WriteLine ("Jan Verhoeven, NL-5012 GH 272, E-mail: fruttenboel@gmail.com");
WriteLn;
WriteLine ("This is FREE software, as described in the GNU GPL documents. Please study");
WriteLine ("the GNU GPL documents for more details.");
WriteLine ("The copyrights of the sourcecode remain with me, but you are permitted to make");
WriteLine ("modifications to it, as long as the rules of the GNU GPL remain intact, also");
WriteLine ("for the modified programs."); WriteLn;
WriteLine ("In case you like this program, please send a postcard to the above address.");
END;
END UserMessage;
PROCEDURE ShowWeekday (Weekday : CARDINAL);
BEGIN
CASE Weekday OF
0 : WriteString ("Sunday"); |
1 : WriteString ("Monday"); |
2 : WriteString ("Tuesday"); |
3 : WriteString ("Wednesday"); |
4 : WriteString ("Thursday"); |
5 : WriteString ("Friday"); |
6 : WriteString ("Saturday");
ELSE
UserMessage (1);
Terminate (1);
END;
END ShowWeekday;
PROCEDURE ShowMonth (Month : CARDINAL);
BEGIN
CASE Month OF
1 : WriteString ("January"); |
2 : WriteString ("February"); |
3 : WriteString ("March"); |
4 : WriteString ("April"); |
5 : WriteString ("May"); |
6 : WriteString ("June"); |
7 : WriteString ("July"); |
8 : WriteString ("August"); |
9 : WriteString ("September"); |
10 : WriteString ("October"); |
11 : WriteString ("November"); |
12 : WriteString ("December");
ELSE
UserMessage (2);
Terminate (2);
END;
END ShowMonth;
PROCEDURE ShowData;
BEGIN
WriteString ("Today is "); ShowWeekday (DoW);
WriteCard (Day, 3); Write (" ");
ShowMonth (Month);
WriteCard (Year, 5); WriteString (" and the time is now ");
WriteCard (Hour, 2); Write (":");
WriteCard (Minute, 2); Write (":");
WriteCard (Second, 2); Write (".");
WriteLn;
END ShowData;
BEGIN
GetArg (Option, Count);
IF Count = 0 THEN
UserMessage (3);
UserMessage (4);
Terminate (3); (* Show correct syntax *)
END;
LOOP
UpperCase (Option);
IF Count = 0 THEN
EXIT;
END;
IF CompareStr (Option, 'SHOW') = 0 THEN
UserMessage (6);
END;
IF CompareStr (Option, 'HELP') = 0 THEN
UserMessage (4);
END;
IF CompareStr (Option, 'RTC') = 0 THEN
GetRtc;
ShowData;
END;
IF CompareStr (Option, 'DOS') = 0 THEN
GetDosData;
ShowData;
END;
GetArg (Option, Count);
END;
UserMessage (5);
END Datum.
Page created June 2002,
Page equipped with FroogleBuster technology