Oberon/V2/Input

MODULE Input; (*NW 5.10.86 / 15.11.90 Ceres-2*)
 	IMPORT SYSTEM, Kernel;
 
 	CONST N = 32;
 		MOUSE = 0FFFFB000H; UART = 0FFFFC000H; ICU = 0FFFF9000H;
 
 	VAR MW, MH: INTEGER; (*mouse limits*)
 		T: LONGINT; (*time counter*)
 		n, in, out: INTEGER;
 		buf: ARRAY N OF CHAR;
 
 	PROCEDURE Available*(): INTEGER;
 	BEGIN RETURN n
 	END Available;
 
 	PROCEDURE Read*(VAR ch: CHAR);
 	BEGIN
 		REPEAT UNTIL n > 0;
 		DEC(n); ch := buf[out]; out := (out+1) MOD N
 	END Read;
 
 	PROCEDURE Mouse*(VAR keys: SET; VAR x, y: INTEGER);
 		VAR u: LONGINT;
 	BEGIN SYSTEM.GET(MOUSE, u);
 		keys := {0,1,2} - SYSTEM.VAL(SET, u DIV 1000H MOD 8);
 		x := SHORT(u MOD 1000H) MOD MW;
 		y := SHORT(u DIV 10000H) MOD 819;
 		IF y >= MH THEN y := 0 END
 	END Mouse;
 
 	PROCEDURE SetMouseLimits*(w, h: INTEGER);
 	BEGIN MW := w; MH := h
 	END SetMouseLimits;
 
 	PROCEDURE Time*(): LONGINT;
 		VAR lo, lo1, hi: CHAR; t: LONGINT;
 	BEGIN
 		REPEAT SYSTEM.GET(UART+28, lo); SYSTEM.GET(UART+24, hi);
 			t := T - LONG(ORD(hi))*256 - ORD(lo); SYSTEM.GET(UART+28, lo1)
 		UNTIL lo1 = lo;
 		RETURN t
 	END Time;
 
 	PROCEDURE+ KBINT;
 		VAR ch: CHAR;
 	BEGIN SYSTEM.GET(UART+12, ch); (*RHRA*)
 		IF ch = 0FFX THEN HALT(24) END ;
 		IF n < N THEN buf[in] := ch; in := (in+1) MOD N; INC(n) END
 	END KBINT;
 
 	PROCEDURE+ CTInt;
 		VAR dmy: CHAR;
 	BEGIN SYSTEM.GET(UART+60, dmy); (*stop timer*)
 		INC(T, 0FFFFH); SYSTEM.GET(UART+56, dmy) (*restart timer*)
 	END CTInt;
 	
 BEGIN MW := 1024; MH := 800;
 	n := 0; in := 0; out := 0; T := 0FFFFH;
 	Kernel.InstallIP(KBINT, 4); Kernel.InstallIP(CTInt, 0);
 	SYSTEM.PUT(UART+16, 10X); (*ACR*)
 	SYSTEM.PUT(UART+ 8, 15X); (*CRA enable*)
 	SYSTEM.PUT(UART, 13X); (*MR1A, RxRdy -Int, no parity, 8 bits*)
 	SYSTEM.PUT(UART, 7X); (*MR2A 1 stop bit*)
 	SYSTEM.PUT(UART+ 4, 44X); (*CSRA, rate = 300 bps*)
 	SYSTEM.PUT(UART+52, 14X); (*OPCR OP4 = KB and OP3 = C/T int*)
 	SYSTEM.PUT(UART+28, 0FFX); (*CTLR*)
 	SYSTEM.PUT(UART+24, 0FFX); (*CTUR*)
 	SYSTEM.GET(UART+56, buf[0]); (*start timer*)
 	SYSTEM.PUT(ICU + 4, 18X); (*clear ICU IMR and IRR bits 0*)
 	SYSTEM.PUT(ICU + 4, 1CX); (*clear ICU IMR and IRR bits 4*)
 END Input.