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.