Skip to content

Instantly share code, notes, and snippets.

@iProgramMC
Created May 27, 2020 20:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save iProgramMC/6b4ed765dfbbb02a949db62634cddfc8 to your computer and use it in GitHub Desktop.
Save iProgramMC/6b4ed765dfbbb02a949db62634cddfc8 to your computer and use it in GitHub Desktop.
// SANiK source code adaptation
// ReadPort = inb, WritePort = outb
// Kinda hackish, I know, I only want the OS to register mouse movement
#define WorkAreaW 640
#define WorkAreaH 480
#define MousePort 0x60
#define MouseStatus 0x64
#define MouseABit 0x02
#define MouseBBit 0x01
#define MouseWriteC 0xd4
#define MouseFBit 0x20
#define MouseVBit 0x08
#define MouseDefault 0
#define MouseScrollWheel 1
#define MouseButtons 2
int MousePosX = 0;
int MousePosY = 0;
#define Cursor struct cursor_t
Cursor
{
int64_t bitmap[12 * 21];
uint8_t w, h;
};
#define X 0xffffff,
#define B 0x000000,
#define o (-1),
Cursor cursor = {
{
B o o o o o o o o o o o
B B o o o o o o o o o o
B X B o o o o o o o o o
B X B B o o o o o o o o
B X X X B o o o o o o o
B X X X X B o o o o o o
B X X X X X B o o o o o
B X X X X X X B o o o o
B X X X X X X X B o o o
B X X X X X X X X B o o
B X X X X X X X X X B o
B X X X X X X B B B B B
B X X X B X X B o o o o
B X X B B X X B o o o o
B X B o o B X X B o o o
B B o o o B X X B o o o
B o o o o o B X X B o o
o o o o o o B X X B o o
o o o o o o o B X X B o
o o o o o o o B X X B o
o o o o o o o o B B o o
},
12, 21
};
#undef X
#undef B
#undef o
uint8_t ps2_mouse_cycle = 0;
int8_t ps2_mouse_byte[3];
int8_t ps2_mouse_x = 0;
int8_t ps2_mouse_y = 0;
bool discard_packet = false;
#define MousePacket struct nsio_mouse_packet_t
MousePacket { // packets yay
uint8_t flags;
uint8_t x_mov;
uint8_t y_mov;
uint8_t dev_id;
};
bool MouseAvailable = true;
bool MouseInitted = false;
void InitMouse();
/*
#define KEYBOARD_DATA_PORT 0x60
#define KEYBOARD_STATUS_PORT 0x64
*/
uint8_t MouseRead();
void MouseWrite(uint8_t write);
void MouseWait(uint8_t type);
MousePacket currentPacket;
bool IsMouseFullyInittedYet = false;
int resetStages = 0;
uint8_t deviceId = 0;
uint8_t runningWhatCommand = 0;
#define CURRENT_COMMAND_RUNNING_NONE 0
#define CURRENT_COMMAND_RUNNING_RESET 1
#define CURRENT_COMMAND_RUNNING_SET_DEFAULT 2
#define CURRENT_COMMAND_RUNNING_SET_REPORT 3
#define CURRENT_COMMAND_RUNNING_GET_DEVID 4
#define CURRENT_COMMAND_RUNNING_READ_DATA 5
void MouseHandlerMain()
{
if (!MouseAvailable) puts("HOW");
/* acknowledge interrupt */
uint8_t b = MouseRead();
printf("Got byte %x from interrupt\n", b);
if (runningWhatCommand != 0) {
switch (runningWhatCommand) {
case CURRENT_COMMAND_RUNNING_RESET: {
if (b == 0xFA) // acknowledge
{
// we are on good terms, return
puts("[Mouse] Got acknowledge byte (reset)");
if (resetStages <= 3) {
puts(", moving on to next stage\n");
resetStages++; // next stage
goto return_send_ack;
} else puts("\n");
}
else if (b == 0xAA && resetStages <= 1) {
puts("[Mouse] Got self-test-done byte, moving on to next stage\n");
// got 0xAA (self test complete)
resetStages = 2;
goto return_send_ack;
}
else if (resetStages == 2) {
puts("[Mouse] Got 0xFA and 0xAA before, this must be a device ID.\n");
resetStages = 3;
// here we have the device id
deviceId = b;
goto return_send_ack;
}
else if (resetStages == 3) {
// some extra shit that we don't care about
puts("[Mouse] Got extra shit we don't care about\n");
resetStages = 4;
runningWhatCommand = 0;
}
}
break;
case CURRENT_COMMAND_RUNNING_SET_DEFAULT: {
if (b == 0xFA) {
puts("[Mouse] Got acknowledge byte (set defaults)");
} else {
printf("[Mouse] Got unknown response byte for set defaults (%x = %d)", b, b);
}
runningWhatCommand = 0;
}
break;
case CURRENT_COMMAND_RUNNING_SET_REPORT: {
if (b == 0xFA) {
puts("[Mouse] Got acknowledge byte (set reporting)");
} else {
printf("[Mouse] Got unknown response byte for set reporting (%x = %d)", b, b);
}
runningWhatCommand = 0;
}
break;
case CURRENT_COMMAND_RUNNING_GET_DEVID: {
if (b == 0xFA) {
puts("[Mouse] Got acknowledge byte (get devID)");
} else {
printf("[Mouse] Got device ID (%x = %d)", b, b);
deviceId = b;
}
runningWhatCommand = 0;
}
break;
case CURRENT_COMMAND_RUNNING_READ_DATA: {
printf("[Mouse] Byte read out is %x (%d)\n", b, b);
switch (ps2_mouse_cycle) {
case 0:
currentPacket.flags = b;
ps2_mouse_cycle++;
if (currentPacket.flags & (1 << 6) || currentPacket.flags & (1 << 7))
discard_packet = 1; // discard rest of packet
if (!(currentPacket.flags & (1 << 3)))
discard_packet = 1; // discard rest of packet
break;
case 1:
currentPacket.x_mov = b;
ps2_mouse_cycle++;
/*if (!IsMouseFullyInittedYet) {
printf("\nGot mouse packet before full init F:%x X:%x Y:None\n", currentPacket.flags, currentPacket.x_mov);
ps2_mouse_cycle = 0;
goto return_send_ack;
}*/
break;
case 2:
currentPacket.y_mov = b;
ps2_mouse_cycle = 0;
runningWhatCommand = 0;
// report the packet
printf("\nGot mouse packet F:%x X:%x Y:%x Discard:%d\n", currentPacket.flags, currentPacket.x_mov, currentPacket.y_mov, discard_packet);
if (discard_packet) {
discard_packet = false;
goto return_send_ack;
}
break;
default:
printf("ERROR: Got stuck inside of %d ps2 mouse cycle, please report.", ps2_mouse_cycle);
ps2_mouse_cycle = 0;
runningWhatCommand = 0;
break;
}
}
break;
}
}
return_send_ack:
WritePort(0x20, 0x20);
WritePort(0xA0, 0x20); // irq 12!!!
}
void MouseWait(uint8_t type)
{
if (!MouseAvailable) return;
uint32_t _time_out=100000; //unsigned int
//unsigned long long int gtms = globalTimeMS;
if (type == 0)
{
while (_time_out--)
{
if ((ReadPort(0x64) & 1) == 1) return;
}
}
else
{
while (_time_out--)
{
if ((ReadPort(0x64) & 2) == 0) return;
}
}
MouseAvailable = false;
printf("Mouse timeout reached, guessed that the mouse is unavailable.\n");
return;
}
void MouseWrite(uint8_t write)
{
if (!MouseAvailable) return;
MouseWait(1);
WritePort(0x64, 0xD4);
MouseWait(1);
WritePort(0x60, write);
}
uint8_t MouseRead()//int line)
{
if (!MouseAvailable) return 0xff;
//printf("|Reading from mouse from line %d|\n", line);
MouseWait(0);
return ReadPort(0x60);
}
void InitMouse()
{
puts("[INIT] Initializing Mouse...\n");
uint8_t _status;
// Enable the auxiliary mouse device.
MouseWait(1);
WritePort(0x64, 0xA8);
// Enable the interrupts
MouseWait(1);
WritePort(0x64, 0x20);
//MouseWait(0);
_status = (ReadPort(0x60) | 2);
MouseWait(1);
WritePort(0x64, 0x60);
MouseWait(1);
WritePort(0x60, _status);
// Reset Mouse
runningWhatCommand = CURRENT_COMMAND_RUNNING_RESET;
MouseWrite(0xFF);
for (int i = 0; i < 20; i++) {
WritePort(0x80, 0x00); // wait a few seconds to make sure all the interrupts went through
}
while (resetStages < 2) hlt;
runningWhatCommand = 0;
// halt for 3 bytes because we are supposed to be getting them :)
resetStages = 0x4;
runningWhatCommand = CURRENT_COMMAND_RUNNING_SET_DEFAULT;
// Tell the mouse to use default settings
MouseWrite(0xF6);
while (runningWhatCommand) hlt;
// Enable data reporting
runningWhatCommand = CURRENT_COMMAND_RUNNING_SET_REPORT;
MouseWrite(0xF4);
while (runningWhatCommand) hlt;
runningWhatCommand = CURRENT_COMMAND_RUNNING_GET_DEVID;
MouseWrite(0xF2);
while (runningWhatCommand) hlt;
while (ReadPort(0x64) & 2)
ReadPort(0x60);
if (MouseAvailable) {
MouseInitted = true;
puts("[INIT] Init finished.\n");
}
else
puts("Mouse failed to initialize.\n");
}
void MouseOnReadData() {
// send read data packet and wait for a response back
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment