summaryrefslogtreecommitdiff
path: root/fpcdocs/go32ex/keyclick.pp
blob: 0979ee477444ca6b02551a41dfa2d0fbd0d07c94 (plain)
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
{$ASMMODE ATT}
{$MODE FPC}

uses
        crt,
        go32;

const
        kbdint = $9;

var
        oldint9_handler : tseginfo;
        newint9_handler : tseginfo;

        clickproc : pointer;
        backupDS : Word; external name '___v2prt0_ds_alias';

procedure int9_handler; assembler;
asm
        cli
        pushl %ds
        pushl %es
        pushl %fs
        pushl %gs
        pushal
        movw %cs:backupDS, %ax
        movw %ax, %ds
        movw %ax, %es
        movw dosmemselector, %ax
        movw %ax, %fs
        call *clickproc
        popal
        popl %gs
        popl %fs
        popl %es
        popl %ds
        ljmp %cs:oldint9_handler
end;
procedure int9_dummy; begin end;

procedure clicker;
begin
        sound(500); delay(10); nosound;
end;
procedure clicker_dummy; begin end;

procedure install_click;
begin
        clickproc := @clicker;
        lock_data(clickproc, sizeof(clickproc));
        lock_data(dosmemselector, sizeof(dosmemselector));

        lock_code(@clicker,
                longint(@clicker_dummy) - longint(@clicker));
        lock_code(@int9_handler,
                longint(@int9_dummy)-longint(@int9_handler));
        newint9_handler.offset := @int9_handler;
        newint9_handler.segment := get_cs;
        get_pm_interrupt(kbdint, oldint9_handler);
        set_pm_interrupt(kbdint, newint9_handler);
end;

procedure remove_click;
begin
        set_pm_interrupt(kbdint, oldint9_handler);
        unlock_data(dosmemselector, sizeof(dosmemselector));
        unlock_data(clickproc, sizeof(clickproc));

        unlock_code(@clicker,
                longint(@clicker_dummy)-longint(@clicker));
        unlock_code(@int9_handler,
                longint(@int9_dummy)-longint(@int9_handler));
end;

var
        ch : char;

begin
        install_click;
        Writeln('Enter any message. Press return when finished');
        while (ch <> #13) do begin
                ch := readkey; write(ch);
        end;
        remove_click;
end.