Folge dem Video um zu sehen, wie unsere Website als Web-App auf dem Startbildschirm installiert werden kann.
Anmerkung: Diese Funktion ist in einigen Browsern möglicherweise nicht verfügbar.
#define KEYB_PORT 0x60 /* keyboard port */
#define KEYB_CTRL 0x64 /* keyboard controller port */
#define KCTRL_ENABLE_AUX 0xA8 /* enable aux port (PS/2 mouse) */
#define KCTRL_WRITE_CMD_BYTE 0x60 /* write to command register */
#define KCTRL_WRITE_AUX 0xD4 /* write next byte at port 60 to aux port */
#define KCTRL_IRQ1 0x01 /* flags for KCTRL_WRITE_CMD_BYTE */
#define KCTRL_IRQ12 0x02
#define KCTRL_SYS 0x04
#define KCTRL_OVERRIDE_INHIBIT 0x08
#define KCTRL_DISABLE_KEYB 0x10
#define KCTRL_DISABLE_AUX 0x20
#define KCTRL_TRANSLATE_XT 0x40
#define KEYB_SET_LEDS 0xED /* commands to keyboard */
#define KEYB_SET_SCANCODE_SET 0xF0
#define KEYB_IDENTIFY 0xF2
#define KEYB_SET_TYPEMATIC 0xF3
#define KEYB_ENABLE 0xF4
#define KEYB_RESET_DISABLE 0xF5
#define KEYB_ALL_TYPM_MAKE_BRK 0xFA
#define KEYB_ACK "\xFA" /* default ACK from keyboard following command */
#define AUX_INFORMATION 0xE9 /* commands to aux device (PS/2 mouse) */
#define AUX_ENABLE 0xF4
#define AUX_IDENTIFY 0xF2
#define AUX_RESET 0xFF
#define min(a, b) ((a) < (b) ? (a) : (b))
#define max(a, b) ((a) > (b) ? (a) : (b))
static short interrupts;
typedef struct Ps2Mouse Ps2Mouse;
struct Ps2Mouse {
int has_wheel;
int x, y, xmax, xmin, ymax, ymin, wheel;
int buttons;
};
extern int mouseclicked;
int first=1;
int in_isr = 0;
void ps2ISR();
int mouseclicked = 0;
Ps2Mouse* ctx;
void kbdWrite(short port, char data)
{
int timeout;
char stat;
for (timeout = 500000L; timeout != 0; timeout--)
{
stat = inportb(KEYB_CTRL);
if ((stat & 0x02) == 0)
break;
}
if (timeout != 0)
outportb(port, data);
}
char kbdRead()
{
unsigned long Timeout;
char Stat, Data;
for (Timeout = 50000L; Timeout != 0; Timeout--)
{
Stat = inportb(KEYB_CTRL);
if ((Stat & 0x01) != 0)
{
Data = inportb(KEYB_PORT);
if((Stat & 0xC0) == 0)
return Data;
}
}
return -1;
}
char kbdWriteRead(short port, char data, const char* expect)
{
int RetVal;
kbdWrite(port, data);
for (; *expect; expect++)
{
RetVal = kbdRead();
if ((char) *expect != RetVal)
{
return RetVal;
}
}
return 0;
}
static DEVICE_T dev_ps2maus =
{
{'P','S','2','M','a','u','s','\0','\0',},
0,
{12,0},
{0,0},
{0x60, 0},
};
void InitPS2()
{
static char s1[] = { 0xF3, 0xC8, 0xF3, 0x64, 0xF3, 0x50, 0 };
const char* ch;
char id;
kbdWrite(KEYB_CTRL, KCTRL_ENABLE_AUX);
for (ch = s1; *ch; ch++)
{
kbdWrite(KEYB_CTRL, KCTRL_WRITE_AUX);
kbdWriteRead(KEYB_PORT, *ch, KEYB_ACK);
}
kbdWrite(KEYB_CTRL, KCTRL_WRITE_AUX);
kbdWriteRead(KEYB_PORT, AUX_IDENTIFY, KEYB_ACK);
id = kbdRead();
ctx->has_wheel = id == 3;
kbdWrite(KEYB_CTRL, KCTRL_WRITE_AUX);
kbdWriteRead(KEYB_PORT, 0xF3, KEYB_ACK);
kbdWrite(KEYB_CTRL, KCTRL_WRITE_AUX);
kbdWriteRead(KEYB_PORT, 0xFF, KEYB_ACK);
kbdWrite(KEYB_CTRL, KCTRL_WRITE_AUX);
kbdWriteRead(KEYB_PORT, AUX_INFORMATION, KEYB_ACK);
kbdWrite(KEYB_CTRL, KCTRL_WRITE_AUX);
kbdWriteRead(KEYB_PORT, AUX_ENABLE, KEYB_ACK);
set_vector(ps2ISR, M_VEC+12, D_PRESENT + D_INT + D_DPL3); /* IRQ12 Handler */
enable_irq(12);
ctx->xmin = ctx->ymin = 0;
ctx->xmax = 640;
ctx->ymax = 480;
ctx->x = 320;
ctx->y = 240;
}
char ps2AuxRead()
{
char Stat, Data;
int tmout = 1000;
while (tmout)
{
Stat = inportb(KEYB_CTRL);
if ((Stat & 0x01) != 0)
{
Data = inportb(KEYB_PORT);
if((Stat & 0xC0) == 0)
return Data;
}
tmout--;
}
return (char) -1;
}
void ps2Packet()
{
int dx=0, dy=0, db0=0, db1=0;
unsigned char buf[4];
buf[0] = ps2AuxRead();
if (buf[0] == (char) -1)
{
return;
}
buf[1] = ps2AuxRead();
buf[2] = ps2AuxRead();
if (ctx->has_wheel)
{
buf[3] = ps2AuxRead();
}
else
{
buf[3] = 0;
}
db0 = (buf[0] & 0x01) << 2;
db1 = (buf[0] & 0x02) >> 1;
dx = (buf[0] & 0x10) ? (buf[1] - 256) : buf[1];
dy = (buf[0] & 0x20) ? -(buf[2] - 256) : -buf[2];
call_syscall(SC_SETMOUSE,dx,dy);
call_syscall(SC_MOUSEBUTTON, db0?1:0 + db1?2:0,0);
db0 = db1;
db0 = dx;
db0 = dy;
db0 = 1;
mouseclicked = db0;
}
void ps2_Isr()
{
char stat;
stat=inportb(KEYB_CTRL);
if ((stat & 0x01) != 0)
{
ps2Packet();
}
outportb(0xA0,0x20);
outportb(0x20,0x20);
}
void _ps2ISR() {
asm db 0x60
asm call _ps2_Isr
asm db 0x61
asm iret
}
;
; Microsoft kompatibler Maustreiber für den Textmode 0x03
;
; Copyright (c) 1997 by Michael Neumann
;
; Assemblieren und Linken: TASM msmaus.asm --> TLINK msmaus.obj
;
.386P
LOCALS @@
COM1INTR EQU 0Ch
COM1PORT EQU 03F8h
MIRQ EQU 04h
CODE SEGMENT USE16
ASSUME CS:CODE,DS:CODE
START: JMP BEGIN
; Daten
bytenum DB 0 ; nummer des bytes, welches gerade übertragen wurde
combytes DB 3 DUP(0) ; byte buffer, für die 3 empfangenen bytes
mousek DB 0 ; mousekey - gedrückte maustaste
relx DW 0
rely DW 0
mousex DW 0 ; mousex
mousey DW 0 ; mousey
oldmx DW 0 ; oldx
oldmy DW 0 ; oldy
showm DB 0 ; showmouse? 0=nicht 1=zeigen
oldoff DW 0 ; alter Bld-offset
oldmousehandler DD 0 ; alter maushandler
inbyte DB 0 ; nimmt in al,dx auf
VID_OFFS DW 0
VID_SEG DW 0b800h
MouseHandler PROC FAR
PUSH AX
PUSH BX
PUSH DX
PUSH DS
MOV AX,CS
MOV DS,AX
MOV DX,COM1PORT
IN AL,DX
MOV [inbyte],al
AND AL,64
CMP AL,64
JNE NOT64
MOV [bytenum],0
NOT64: XOR AX,AX
MOV AL,[bytenum]
MOV BX,AX
ADD BX,OFFSET combytes
MOV AL,[inbyte]
MOV [BX],al
INC [bytenum]
CMP [bytenum],3
JNE NOT3
MOV AL,[combytes]
AND AL,3
SHL AL,6
ADD AL,[combytes+1]
CBW
CMP AX,128
JL NOT_B128_X
SUB AX,256
NOT_B128_X: ADD [mousex],AX
MOV AL,[combytes]
AND AL,12
SHL AL,4
ADD AL,[combytes+2]
CBW
CMP AX,128
JL NOT_B128_Y
SUB AX,256
NOT_B128_Y: ADD [mousey],AX
MOV AL,[combytes]
AND AL,32
OR AL,AL
SETNZ AL
MOV [mousek],al
MOV AL,[combytes]
AND AL,16
OR AL,AL
SETNZ AL
SHL AL,1
ADD [mousek],AL
MOV [bytenum],0
CMP [mousex],0
JGE @@WEIT1
MOV [mousex],0
@@WEIT1: CMP [mousex],639
JLE @@WEIT2
MOV [mousex],639
@@WEIT2: CMP [mousey],0
JGE @@WEIT3
MOV [mousey],0
@@WEIT3: CMP [mousey],399
JLE @@WEIT4
MOV [mousey],399
@@WEIT4:
CMP [showm],0
JE NOT3
CALL REDRAWCURSOR;oldmx,oldmy
MOV AX,[mousex]
MOV [oldmx],AX
MOV AX,[mousey]
MOV [oldmy],AX
CALL REDRAWCURSOR
NOT3:
MOV AL,20H
OUT 20H,AL
POP DS
POP DX
POP BX
POP AX
IRET
MouseHandler ENDP
;0Ch = COM1
;0Dh = COM2
InitMouse PROC NEAR
; DTR - Data Transfer Ready auf 1
; warten, wenn Datenleitungen = 'M'
CLI
IN AL,21h
JMP $+2
JMP $+2
AND AL, NOT 2 SHL (MIRQ-1) ; Maus-IRQ aktivieren
OUT 21h, AL
MOV dx, COM1PORT+3
MOV AL, 80h ; Baudrate auf 1200 setzen
OUT DX, AL
SUB DX, 3
MOV AX, 115200 / 1200
OUT DX, AL
INC DX
MOV AL, AH
OUT DX, AL
ADD DX, 2
MOV AL, 2
OUT DX, AL
SUB DX, 2
MOV AL, 1
OUT DX, AL ; Interrupts aktivieren
ADD DX, 3
MOV AL, 1 OR 2 OR 8 ; DTR, RTS, OUT2
OUT DX, AL
SUB DX, 4
IN AL, DX
MOV AL, 20h ; Interrupt beenden
OUT 20h, AL
RET
InitMouse ENDP
InstallMouse PROC NEAR
CALL InitMouse
CLI
XOR BX,BX
MOV ES,BX
MOV BX,(COM1INTR*4)
MOV EAX,ES:[BX]
MOV [oldmousehandler],EAX
MOV AX,CS
SHL EAX,16
MOV AX,OFFSET MouseHandler
MOV ES:[BX],EAX
STI
RET
InstallMouse ENDP
ResetMouse PROC NEAR
CALL HideMouse
XOR AX,AX
MOV [bytenum],AL
MOV [mousek],AL
MOV [mousex],AX
MOV [mousey],AX
MOV [oldmx],AX
MOV [oldmy],AX
MOV [showm],AL
MOV [oldoff],AX
RET
ENDP
REDRAWCURSOR PROC NEAR
MOV BX,[oldmy]
SHR BX,4
MOV AX,160
MUL BX
MOV BX,[oldmx]
SHR BX,3
SHL BX,1
ADD BX,AX
ADD BX,[VID_OFFS]
MOV DX,ES ; XCHG
MOV AX,[VID_SEG]
MOV ES,AX
MOV AX,ES:[BX]
ROL AH,4
MOV ES:[BX],AX
MOV ES,DX
RET
ENDP
HideMouse PROC NEAR
CMP [showm],1
JNE @@ENDE
CALL REDRAWCURSOR
MOV [showm],0
@@ENDE: RET
ENDP
ShowMouse PROC NEAR
CMP [showm],0
JNE @@ENDE
MOV AX,[mousex]
MOV [oldmx],AX
MOV AX,[mousey]
MOV [oldmy],AX
CALL REDRAWCURSOR
MOV [showm],1
@@ENDE: RET
ENDP
DeInstallMouse PROC NEAR
XOR BX,BX
MOV ES,BX
MOV BX,(COM1INTR*4)
MOV EAX,[oldmousehandler]
MOV ES:[BX],EAX
RET
DeInstallMouse ENDP
BEGIN:
MOV AX,CS
MOV DS,AX
MOV SS,AX
MOV SP,20000
CALL InstallMouse
CALL ResetMouse
CALL ShowMouse
@@again:
MOV AH,01
INT 16H
JZ @@check
CALL HideMouse
MOV AH,01
INT 21h
CMP AL,13
JNE @@ok
MOV AH,02
MOV DL,10
INT 21H
@@ok:
CALL ShowMouse
@@check:
MOV AL,[mousek]
OR AL,AL
JZ @@again
@@ende:
CALL HideMouse
CALL DeInstallMouse
MOV ax,4c00h
INT 21h
ENDS CODE
END START