mirror of
https://github.com/zydeco/minivmac4ios.git
synced 2024-11-26 00:49:20 +00:00
291 lines
5.8 KiB
C
291 lines
5.8 KiB
C
/*
|
|
ADBSHARE.h
|
|
|
|
Copyright (C) 2008 Paul C. Pratt
|
|
|
|
You can redistribute this file and/or modify it under the terms
|
|
of version 2 of the GNU General Public License as published by
|
|
the Free Software Foundation. You should have received a copy
|
|
of the license along with this file; see the file COPYING.
|
|
|
|
This file is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
license for more details.
|
|
*/
|
|
|
|
/*
|
|
Apple Desktop Bus SHAREd code
|
|
shared by emulation of different implementations of ADB
|
|
*/
|
|
|
|
#ifdef ADBSHARE_H
|
|
#error "header already included"
|
|
#else
|
|
#define ADBSHARE_H
|
|
#endif
|
|
|
|
|
|
/*
|
|
ReportAbnormalID unused 0x0D08 - 0x0DFF
|
|
*/
|
|
|
|
#define ADB_MaxSzDatBuf 8
|
|
|
|
LOCALVAR ui3b ADB_SzDatBuf;
|
|
LOCALVAR blnr ADB_TalkDatBuf = falseblnr;
|
|
LOCALVAR ui3b ADB_DatBuf[ADB_MaxSzDatBuf];
|
|
LOCALVAR ui3b ADB_CurCmd = 0;
|
|
LOCALVAR ui3b NotSoRandAddr = 1;
|
|
|
|
LOCALVAR ui3b MouseADBAddress;
|
|
LOCALVAR blnr SavedCurMouseButton = falseblnr;
|
|
LOCALVAR ui4r MouseADBDeltaH = 0;
|
|
LOCALVAR ui4r MouseADBDeltaV = 0;
|
|
|
|
LOCALPROC ADB_DoMouseTalk(void)
|
|
{
|
|
switch (ADB_CurCmd & 3) {
|
|
case 0:
|
|
{
|
|
MyEvtQEl *p;
|
|
ui4b partH;
|
|
ui4b partV;
|
|
blnr overflow = falseblnr;
|
|
blnr MouseButtonChange = falseblnr;
|
|
|
|
if (nullpr != (p = MyEvtQOutP())) {
|
|
if (MyEvtQElKindMouseDelta == p->kind) {
|
|
MouseADBDeltaH += p->u.pos.h;
|
|
MouseADBDeltaV += p->u.pos.v;
|
|
MyEvtQOutDone();
|
|
}
|
|
}
|
|
partH = MouseADBDeltaH;
|
|
partV = MouseADBDeltaV;
|
|
|
|
if ((si4b)MouseADBDeltaH < 0) {
|
|
partH = - partH;
|
|
}
|
|
if ((si4b)MouseADBDeltaV < 0) {
|
|
partV = - partV;
|
|
}
|
|
if ((partH >> 6) > 0) {
|
|
overflow = trueblnr;
|
|
partH = (1 << 6) - 1;
|
|
}
|
|
if ((partV >> 6) > 0) {
|
|
overflow = trueblnr;
|
|
partV = (1 << 6) - 1;
|
|
}
|
|
if ((si4b)MouseADBDeltaH < 0) {
|
|
partH = - partH;
|
|
}
|
|
if ((si4b)MouseADBDeltaV < 0) {
|
|
partV = - partV;
|
|
}
|
|
MouseADBDeltaH -= partH;
|
|
MouseADBDeltaV -= partV;
|
|
if (! overflow) {
|
|
if (nullpr != (p = MyEvtQOutP())) {
|
|
if (MyEvtQElKindMouseButton == p->kind) {
|
|
SavedCurMouseButton = p->u.press.down;
|
|
MouseButtonChange = trueblnr;
|
|
MyEvtQOutDone();
|
|
}
|
|
}
|
|
}
|
|
if ((0 != partH) || (0 != partV) || MouseButtonChange) {
|
|
ADB_SzDatBuf = 2;
|
|
ADB_TalkDatBuf = trueblnr;
|
|
ADB_DatBuf[0] = (SavedCurMouseButton ? 0x00 : 0x80)
|
|
| (partV & 127);
|
|
ADB_DatBuf[1] = /* 0x00 */ 0x80 | (partH & 127);
|
|
}
|
|
}
|
|
ADBMouseDisabled = 0;
|
|
break;
|
|
case 3:
|
|
ADB_SzDatBuf = 2;
|
|
ADB_TalkDatBuf = trueblnr;
|
|
ADB_DatBuf[0] = 0x60 | (NotSoRandAddr & 0x0f);
|
|
ADB_DatBuf[1] = 0x01;
|
|
NotSoRandAddr += 1;
|
|
break;
|
|
default:
|
|
ReportAbnormalID(0x0D01, "Talk to unknown mouse register");
|
|
break;
|
|
}
|
|
}
|
|
|
|
LOCALPROC ADB_DoMouseListen(void)
|
|
{
|
|
switch (ADB_CurCmd & 3) {
|
|
case 3:
|
|
if (ADB_DatBuf[1] == 0xFE) {
|
|
/* change address */
|
|
MouseADBAddress = (ADB_DatBuf[0] & 0x0F);
|
|
} else {
|
|
ReportAbnormalID(0x0D02,
|
|
"unknown listen op to mouse register 3");
|
|
}
|
|
break;
|
|
default:
|
|
ReportAbnormalID(0x0D03,
|
|
"listen to unknown mouse register");
|
|
break;
|
|
}
|
|
}
|
|
|
|
LOCALVAR ui3b KeyboardADBAddress;
|
|
|
|
LOCALFUNC blnr CheckForADBkeyEvt(ui3b *NextADBkeyevt)
|
|
{
|
|
int i;
|
|
blnr KeyDown;
|
|
|
|
if (! FindKeyEvent(&i, &KeyDown)) {
|
|
return falseblnr;
|
|
} else {
|
|
#if dbglog_HAVE && 0
|
|
if (KeyDown) {
|
|
dbglog_WriteNote("Got a KeyDown");
|
|
}
|
|
#endif
|
|
switch (i) {
|
|
case MKC_Control:
|
|
i = 0x36;
|
|
break;
|
|
case MKC_Left:
|
|
i = 0x3B;
|
|
break;
|
|
case MKC_Right:
|
|
i = 0x3C;
|
|
break;
|
|
case MKC_Down:
|
|
i = 0x3D;
|
|
break;
|
|
case MKC_Up:
|
|
i = 0x3E;
|
|
break;
|
|
default:
|
|
/* unchanged */
|
|
break;
|
|
}
|
|
*NextADBkeyevt = (KeyDown ? 0x00 : 0x80) | i;
|
|
return trueblnr;
|
|
}
|
|
}
|
|
|
|
LOCALPROC ADB_DoKeyboardTalk(void)
|
|
{
|
|
switch (ADB_CurCmd & 3) {
|
|
case 0:
|
|
{
|
|
ui3b NextADBkeyevt;
|
|
|
|
if (CheckForADBkeyEvt(&NextADBkeyevt)) {
|
|
ADB_SzDatBuf = 2;
|
|
ADB_TalkDatBuf = trueblnr;
|
|
ADB_DatBuf[0] = NextADBkeyevt;
|
|
if (! CheckForADBkeyEvt(&NextADBkeyevt)) {
|
|
ADB_DatBuf[1] = 0xFF;
|
|
} else {
|
|
ADB_DatBuf[1] = NextADBkeyevt;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case 3:
|
|
ADB_SzDatBuf = 2;
|
|
ADB_TalkDatBuf = trueblnr;
|
|
ADB_DatBuf[0] = 0x60 | (NotSoRandAddr & 0x0f);
|
|
ADB_DatBuf[1] = 0x01;
|
|
NotSoRandAddr += 1;
|
|
break;
|
|
default:
|
|
ReportAbnormalID(0x0D04,
|
|
"Talk to unknown keyboard register");
|
|
break;
|
|
}
|
|
}
|
|
|
|
LOCALPROC ADB_DoKeyboardListen(void)
|
|
{
|
|
switch (ADB_CurCmd & 3) {
|
|
case 3:
|
|
if (ADB_DatBuf[1] == 0xFE) {
|
|
/* change address */
|
|
KeyboardADBAddress = (ADB_DatBuf[0] & 0x0F);
|
|
} else {
|
|
ReportAbnormalID(0x0D05,
|
|
"unknown listen op to keyboard register 3");
|
|
}
|
|
break;
|
|
default:
|
|
ReportAbnormalID(0x0D06,
|
|
"listen to unknown keyboard register");
|
|
break;
|
|
}
|
|
}
|
|
|
|
LOCALFUNC blnr CheckForADBanyEvt(void)
|
|
{
|
|
MyEvtQEl *p = MyEvtQOutP();
|
|
if (nullpr != p) {
|
|
switch (p->kind) {
|
|
case MyEvtQElKindMouseButton:
|
|
case MyEvtQElKindMouseDelta:
|
|
case MyEvtQElKindKey:
|
|
return trueblnr;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
return (0 != MouseADBDeltaH) && (0 != MouseADBDeltaV);
|
|
}
|
|
|
|
LOCALPROC ADB_DoTalk(void)
|
|
{
|
|
ui3b Address = ADB_CurCmd >> 4;
|
|
if (Address == MouseADBAddress) {
|
|
ADB_DoMouseTalk();
|
|
} else if (Address == KeyboardADBAddress) {
|
|
ADB_DoKeyboardTalk();
|
|
}
|
|
}
|
|
|
|
LOCALPROC ADB_EndListen(void)
|
|
{
|
|
ui3b Address = ADB_CurCmd >> 4;
|
|
if (Address == MouseADBAddress) {
|
|
ADB_DoMouseListen();
|
|
} else if (Address == KeyboardADBAddress) {
|
|
ADB_DoKeyboardListen();
|
|
}
|
|
}
|
|
|
|
LOCALPROC ADB_DoReset(void)
|
|
{
|
|
MouseADBAddress = 3;
|
|
KeyboardADBAddress = 2;
|
|
}
|
|
|
|
LOCALPROC ADB_Flush(void)
|
|
{
|
|
ui3b Address = ADB_CurCmd >> 4;
|
|
|
|
if ((Address == KeyboardADBAddress)
|
|
|| (Address == MouseADBAddress))
|
|
{
|
|
ADB_SzDatBuf = 2;
|
|
ADB_TalkDatBuf = trueblnr;
|
|
ADB_DatBuf[0] = 0x00;
|
|
ADB_DatBuf[1] = 0x00;
|
|
} else {
|
|
ReportAbnormalID(0x0D07, "Unhandled ADB Flush");
|
|
}
|
|
}
|