Created
April 8, 2022 19:26
-
-
Save mifritscher/fe8058a9ec294522a88d3d62fb9f6498 to your computer and use it in GitHub Desktop.
ps/2 for rosco68k
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright (c) 2020 You ([email protected]) | |
*/ | |
// Some function copied from dua_gpi_spi.h | |
// Part of the PS/2 algorithm borrowed from http://www.technoblogy.com/show?1GYR | |
#include <stdio.h> | |
#include <machine.h> | |
// HI/LO refer to physical pin state, these ports are active | |
// low, so they appear reversed here... | |
static volatile uint8_t *DUART_OUTLOPORT = (uint8_t*)DUART_W_OPR_SETCMD; | |
static volatile uint8_t *DUART_OUTHIPORT = (uint8_t*)DUART_W_OPR_RESETCMD; | |
static volatile uint8_t *DUART_INPUTPORT = (uint8_t*)DUART_R_INPUTPORT; | |
static bool clockOld = true; | |
static uint16_t ScanCode = 0; | |
static uint16_t ScanBit = 1; | |
static uint16_t Break = 0; | |
static uint16_t Modifier = 0; | |
static uint16_t Shift = 0; | |
static uint16_t currentChar = 0; | |
static uint32_t oldTimer = 0; | |
#define KBD_DATA 4 | |
#define KBD_CLOCK 5 | |
#define KBD_DATA_PIN (1 << KBD_DATA) | |
#define KBD_CLOCK_PIN (1 << KBD_CLOCK) | |
#define KeymapSize 132 | |
static const char Keymap[] = | |
// Without shift | |
" \011` q1 zsaw2 cxde43 vftr5 nbhgy6 mju78 ,kio09" | |
" ./l;p- \' [= \015] \\ \010 1 47 0.2568\033 +3-*9 " | |
// With shift | |
" \011~ Q! ZSAW@ CXDE$# VFTR% NBHGY^ MJU&* <KIO)(" | |
" >?L:P_ \" {+ \015} | \010 1 47 0.2568\033 +3-*9 "; | |
static void digitalWrite(uint8_t pinmask, bool value) { | |
if (value) { | |
*DUART_OUTHIPORT = pinmask; | |
} else { | |
*DUART_OUTLOPORT = pinmask; | |
} | |
} | |
static bool digitalRead(uint8_t pinmask) { | |
return ((*DUART_INPUTPORT) & pinmask); | |
} | |
static void turnOnRedLed() { | |
// Turn on Red LED | |
*DUART_OUTLOPORT = 8; | |
} | |
static void turnOffRedLed() { | |
// Turn off Red LED | |
*DUART_OUTHIPORT = 8; | |
} | |
static void handleNewDataBit(bool dataBit) { | |
uint16_t s; | |
//Timeout during recieving one byte | |
if (oldTimer + 10 < _TIMER_100HZ && ScanBit != 1) { | |
printf("timeout receiving the remaining bits 0x%x, ScanCode 0x%x-> reseting!\n", ScanBit, ScanCode); | |
ScanCode = 0; | |
ScanBit = 1; | |
} | |
oldTimer = _TIMER_100HZ; | |
if (dataBit) { | |
ScanCode = ScanCode | ScanBit; | |
} | |
ScanBit = ScanBit << 1; | |
if (ScanBit != 0x800) { | |
return; | |
} | |
// Process scan code | |
if ((ScanCode & 0x401) != 0x400) { // Invalid start/stop bit | |
printf("invalid start/stop bit! ScanCode: 0x%x\n", ScanCode); | |
ScanCode = 0; | |
ScanBit = 1; | |
return; | |
} | |
s = (ScanCode & 0x1FE) >> 1; | |
ScanCode = 0; | |
ScanBit = 1; | |
if (s == 0xAA) { // BAT completion code | |
return; | |
} | |
if (s == 0xF0) { | |
Break = 1; | |
return; | |
} | |
if (s == 0xE0) { | |
Modifier = 1; | |
return; | |
} | |
if (Break) { | |
if ((s == 0x12) || (s == 0x59)) { | |
Shift = 0; | |
} | |
Break = 0; | |
Modifier = 0; | |
return; | |
} | |
if ((s == 0x12) || (s == 0x59)) { | |
Shift = 1; | |
} | |
if (Modifier) { | |
return; | |
} | |
currentChar = s; | |
printf("New rawChar: %d\n",currentChar); | |
char c = Keymap[s + KeymapSize*Shift]; | |
if (c == 32 && s != 0x29) { | |
return; | |
} | |
currentChar = c; | |
printf("New Char: %c\n",currentChar); | |
} | |
void kmain() { | |
printf("Hello, world! 😃\r\n"); | |
bool clockNew = true; | |
bool dataBit = true; | |
printf("Hello, world2! 😃\r\n"); | |
// When this function returns, the machine will reboot. | |
// | |
// In a real program, you probably wouldn't return from | |
// this function! | |
turnOnRedLed(); | |
printf("Input adress: %p Data: %d Clock: %d\n", DUART_INPUTPORT, digitalRead(KBD_DATA_PIN), digitalRead(KBD_CLOCK_PIN)); | |
turnOffRedLed(); | |
while (true) { | |
clockNew = digitalRead(KBD_CLOCK_PIN); | |
dataBit = digitalRead(KBD_DATA_PIN); | |
// printf("Old: %d new: %d\n", clockOld, clockNew); | |
//Detect falling edge | |
if (clockOld && !clockNew) { | |
/* | |
turnOnRedLed(); | |
printf("Data: %d \n", dataBit); | |
turnOffRedLed(); | |
*/ | |
handleNewDataBit(dataBit); | |
} | |
clockOld = clockNew; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment