Use the 8253 for microsecond timings under Modula-2
The program below handles the 8253 timing chip. It can measure time in increments of 800 ns. Not very handy, but it's adequate for a good programmer.
These sources are so short that I put both the DEFINITION and the IMPLEMENTATION modules in one chunk of text.
DEFINITION MODULE Timer;
PROCEDURE OpenTimer; (* open timer chip in mode 2 *)
PROCEDURE CloseTimer; (* close timer chip in mode 2 *)
PROCEDURE ReadTimer () : CARDINAL; (* read timer chip in mode 2 *)
PROCEDURE Wait (ms : CARDINAL); (* wait for <ms> milliseconds *)
PROCEDURE LongWait (time : CARDINAL); (* wait for time ms; time > 55 *)
END Timer.
IMPLEMENTATION MODULE Timer;
FROM SYSTEM IMPORT ASSEMBLER;
PROCEDURE OpenTimer;
BEGIN
ASM
MOV AL, 34H (* open timer chip in mode 2 *)
OUT 43H, AL
XOR AL, AL
OUT 40H, AL
OUT 40H, AL
END;
END OpenTimer;
PROCEDURE CloseTimer; (* close timer chip in mode 2 *)
BEGIN
ASM
MOV AL, 36H
OUT 43H, AL
XOR AL, AL
OUT 40H, AL
OUT 40H, AL
END;
END CloseTimer;
PROCEDURE ReadTimer () : CARDINAL; (* read timer chip in mode 2 *)
VAR Time : CARDINAL;
BEGIN
ASM
MOV AL, 6
OUT 43H, AL
IN AL, 40H
MOV AH, AL
IN AL, 40H
XCHG AH, AL
MOV [Time], AX
END;
RETURN Time;
END ReadTimer;
PROCEDURE Wait (ms : CARDINAL); (* wait for <ms> milliseconds (ms < 55) *)
VAR MaxCount : CARDINAL;
BEGIN
MaxCount := 0FFFFH - ms * 1193;
OpenTimer;
WHILE ReadTimer () > MaxCount DO
(* absolutely nothing *)
END;
CloseTimer;
END Wait;
PROCEDURE LongWait (time : CARDINAL); (* wait for more than 55 ms *)
VAR i : CARDINAL;
BEGIN
FOR i := 1 TO time DO
Wait (1)
END
END LongWait;
END Timer.
Page created a long time ago,
Page equipped with FroogleBuster technology