home *** CD-ROM | disk | FTP | other *** search
- MODULE xferdemo;
-
- (* (C) Copyright 1987 Fitted Software Tools. All rights reserved. *)
-
- (*
- This is a small example showing the use of the coroutine handling
- capabilities in this Modula-2 system.
- *)
-
- FROM SYSTEM IMPORT ASSEMBLER, ADDRESS, NEWPROCESS, TRANSFER, IOTRANSFER;
- FROM Storage IMPORT ALLOCATE;
- FROM System IMPORT GetVector, ResetVector, TermProcedure;
- FROM InOut IMPORT Write, WriteCard, WriteLn;
-
- VAR SysPrtScr :ADDRESS; (* original PrtSc ISR *)
- SysClock :ADDRESS; (* original clock ISR *)
- ProcSpace :POINTER TO CHAR; (* pointers to processes workspaces *)
- ClockSpace :POINTER TO CHAR;
- StopSpace :POINTER TO CHAR;
- p1, p2 :ADDRESS; (* coroutine (process) pointers *)
- p3, p4 :ADDRESS;
- p5, p6 :ADDRESS;
- ticks :CARDINAL; (* tick counter *)
- xfers :CARDINAL; (* transfers performed during run *)
- done :BOOLEAN; (* terminate flag *)
-
-
- PROCEDURE clock;
- (*
- this is the clock process.
-
- it increments 'ticks' on every clock interrupt.
-
- from the time that this process starts until such time as
- the program terminates, the system timer will not be updated,
- as this routine ruthlessly steals the clock interrupts from DOS.
-
- it would have been much better to run this process off interrupt
- 1CH, but in that case we would not have to send the EOI to the
- 8259 chip, making this exercise a little less instructive.
- *)
- BEGIN
- LOOP
- IOTRANSFER( p3, p4, 8 );
- INC(ticks);
- ASM (* send EOI to 8259 *)
- MOV AL, 20H (* the 8259 interrupt controller will *)
- OUT 20H, AL (* prevent all interrupt at or below *)
- (* our level until we send it an EOI *)
- END; (* command *)
- END;
- END clock;
-
-
- PROCEDURE putT;
- (*
- this is a process that works hand in hand with the main process.
-
- it alternately outputs a 'T' or a 't' and resumes the main process.
- *)
- BEGIN
- LOOP
- Write('T');
- TRANSFER( p2, p1 );
- Write('t');
- TRANSFER( p2, p1 );
- END;
- END putT;
-
-
- PROCEDURE stop;
- (*
- this process will signal the main process that the user wishes
- to terminate the program by setting 'done' to TRUE whenever
- the user presses the PrtSC key generating a 'print screen'
- interrupt.
-
- we do not simply terminate the program with a RETURN, because we
- may be in DOS when the interrupt occurs.
- *)
- BEGIN
- LOOP
- IOTRANSFER( p5, p6, 5 );
- done := TRUE;
- END;
- END stop;
-
-
- PROCEDURE end;
- (*
- this is the procedure to be executed on program termination.
-
- we MUST restore the interrupt vectors that we have stolen.
- *)
- BEGIN
- ResetVector( 5, SysPrtScr );
- ResetVector( 8, SysClock );
- END end;
-
-
- BEGIN
- done := FALSE;
- ticks := 0;
- xfers := 0;
-
- GetVector( 5, SysPrtScr ); (* get the original values of the *)
- GetVector( 8, SysClock ); (* interrupt vectors that we will use *)
- TermProcedure( end ); (* and install 'end' to execute on *)
- (* program termination *)
-
- (* now, create the new processes *)
-
- ALLOCATE( ProcSpace, 512 );
- NEWPROCESS( putT, ProcSpace, 512, p2 );
-
- ALLOCATE( ClockSpace, 512 );
- NEWPROCESS( clock, ClockSpace, 512, p3 );
-
- ALLOCATE( StopSpace, 512 );
- NEWPROCESS( stop, StopSpace, 512, p5 );
-
- (* start the 'stop' process *)
- TRANSFER( p6, p5 );
-
- (* start the 'clock' process *)
- TRANSFER( p4, p3 );
-
- (*
- this is the main loop of the main process.
-
- on every loop, the 'done' flag is checked and, if it is not time
- to stop, we write out the value of ticks and reactivate the 'putT'
- process.
- *)
- WHILE NOT done DO
- WriteCard( ticks, 6 );
- TRANSFER( p1, p2 );
- INC( xfers );
- END;
-
- WriteLn; WriteCard( xfers, 4 ); WriteLn;
-
- END xferdemo.