forked from schierlm/Oberon2013Modifications
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Trappy.Mod.txt
113 lines (102 loc) · 3.65 KB
/
Trappy.Mod.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
MODULE Trappy;
IMPORT SYSTEM, Kernel, Modules, Display, Fonts;
TYPE NextPointer = PROCEDURE;
VAR
CodeArea: ARRAY 4 OF INTEGER;
NextTrap, NextAbort: NextPointer;
NextAdr: INTEGER;
PROCEDURE Test*;
BEGIN ASSERT(FALSE)
END Test;
PROCEDURE DrawText(text: ARRAY OF CHAR; x, y: INTEGER);
VAR
dx, xx, yy, t1, t2, patAdr, i: INTEGER;
BEGIN
i := 0;
WHILE text[i] # 0X DO
Fonts.GetPat(Fonts.Default, text[i], dx, xx, yy, t1, t2, patAdr);
Display.CopyPattern(Display.white, patAdr, x + xx, y + yy, Display.replace);
INC(x, dx);
INC(i)
END
END DrawText;
PROCEDURE HandleTrap(title, module, pos: ARRAY OF CHAR; addr: INTEGER);
VAR i, d: INTEGER; addrText: ARRAY 12 OF CHAR;
BEGIN
addrText[0] := "a";
addrText[1] := "t";
addrText[2] := " ";
FOR i := 0 TO 7 DO
d := addr MOD 10H;
IF d < 10 THEN INC(d, 30H) ELSE INC(d, 37H) END;
addrText[10 - i] := CHR(d);
addr := addr DIV 10H;
END;
addrText[11] := 0X;
Display.ReplConst(Display.white, 400, 300, 110, 80, Display.replace);
Display.ReplConst(Display.black, 405, 305, 100, 70, Display.replace);
DrawText(title, 410, 360);
DrawText(module, 410, 345);
DrawText(pos, 410, 330);
DrawText(addrText, 410, 315);
REPEAT SYSTEM.PUT(-64, Kernel.Time() + 1000); SYSTEM.GET(-40, i); UNTIL i DIV 1000000H MOD 8 = 5;
Display.ReplConst(Display.black, 400, 300, 110, 80, Display.replace);
REPEAT SYSTEM.PUT(-64, Kernel.Time() + 1000); SYSTEM.GET(-40, i); UNTIL i DIV 1000000H MOD 8 = 0;
END HandleTrap;
PROCEDURE DoTrap(num, pos, addr: INTEGER; mod: Modules.Module);
VAR
title, posText: ARRAY 10 OF CHAR;
BEGIN
title[0] := "T"; title[1] := "R"; title[2] := "A"; title[3] := "P"; title[4] := " ";
title[5] := CHR(30H + (num DIV 100));
title[6] := CHR(30H + (num DIV 10 MOD 10));
title[7] := CHR(30H + (num MOD 10));
title[8] := 0X;
posText[0] := "p"; posText[1] := "o"; posText[2] := "s"; posText[3] := " ";
posText[4] := CHR(30H + (pos DIV 10000 MOD 10));
posText[5] := CHR(30H + (pos DIV 1000 MOD 10));
posText[6] := CHR(30H + (pos DIV 100 MOD 10));
posText[7] := CHR(30H + (pos DIV 10 MOD 10));
posText[8] := CHR(30H + (pos MOD 10));
posText[9] := 0X;
IF mod # NIL THEN
HandleTrap(title, mod.name, posText, addr)
ELSE
HandleTrap(title, "<?>", posText, addr)
END
END DoTrap;
PROCEDURE Trap(VAR a: INTEGER; b: INTEGER);
VAR u, v, w: INTEGER; mod: Modules.Module;
BEGIN u := SYSTEM.REG(15); SYSTEM.GET(u - 4, v); w := v DIV 10H MOD 10H; (*trap number*)
IF w = 0 THEN
Kernel.New(a, b)
ELSE
mod := Modules.root;
WHILE (mod # NIL) & ((u < mod.code) OR (u >= mod.imp)) DO mod := mod.next END;
DoTrap(w, v DIV 100H MOD 10000H, u, mod);
SYSTEM.LDREG(10, u);
NextTrap();
END
END Trap;
PROCEDURE Abort;
VAR n: INTEGER;
BEGIN
n := SYSTEM.REG(15);
HandleTrap("ABORT", "", "", n);
SYSTEM.LDREG(10, n);
NextAbort();
END Abort;
BEGIN
SYSTEM.GET(20H, NextAdr);
NextAdr := ((NextAdr MOD 1000000H) + 1) * 4 + 20H;
CodeArea[0] := 0F00000AH; (* MOV R15 0 R10 *)
CodeArea[1] := 0E7000000H + ((NextAdr - SYSTEM.ADR(CodeArea[1])) DIV 4 - 1) MOD 1000000H;
NextTrap := SYSTEM.VAL(NextPointer, SYSTEM.ADR(CodeArea[0]));
Kernel.Install(SYSTEM.ADR(Trap), 20H);
SYSTEM.GET(0H, NextAdr);
NextAdr := ((NextAdr MOD 1000000H) + 1) * 4;
CodeArea[2] := 0F00000AH; (* MOV R15 0 R10 *)
CodeArea[3] := 0E7000000H + ((NextAdr - SYSTEM.ADR(CodeArea[3])) DIV 4 - 1) MOD 1000000H;
NextAbort := SYSTEM.VAL(NextPointer, SYSTEM.ADR(CodeArea[2]));
Kernel.Install(SYSTEM.ADR(Abort), 0);
END Trappy.