forked from Apple-2-HW/arduino-appleii
88 lines
4.0 KiB
Arduino
88 lines
4.0 KiB
Arduino
|
#include <avr/wdt.h>
|
||
|
|
||
|
#define KEYBD_DATA_PIN 4
|
||
|
|
||
|
const unsigned char scancode_to_apple[] PROGMEM = {
|
||
|
//$0 $1 $2 $3 $4 $5 $6 $7 $8 $9 $A $B $C $D $E $F
|
||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //$00
|
||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0xD1, 0xB1, 0x00, 0x00, 0x00, 0xDA, 0xD3, 0xC1, 0xD7, 0xB2, 0x00, //$10
|
||
|
0x00, 0xC3, 0xD8, 0xC4, 0xC5, 0xB4, 0xB3, 0x00, 0x00, 0xA0, 0xD6, 0xC6, 0xD4, 0xD2, 0xB5, 0x00, //$20
|
||
|
0x00, 0xCE, 0xC2, 0xC8, 0xC7, 0xD9, 0xB6, 0x00, 0x00, 0x00, 0xCD, 0xCA, 0xD5, 0xB7, 0xB8, 0x00, //$30
|
||
|
0x00, 0xAC, 0xCB, 0xC9, 0xCF, 0xB0, 0xB9, 0x00, 0x00, 0xAE, 0xAF, 0xCC, 0xBB, 0xD0, 0xAD, 0x00, //$40
|
||
|
0x00, 0x00, 0xA7, 0x00, 0x00, 0xBD, 0x00, 0x00, 0x00, 0x00, 0x8D, 0x00, 0x00, 0x00, 0x00, 0x00, //$50
|
||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0xB1, 0x00, 0xB4, 0xB7, 0x00, 0x00, 0x00, //$60
|
||
|
0xB0, 0xAE, 0xB2, 0xB5, 0xB6, 0xB8, 0x9B, 0x00, 0x00, 0xAB, 0xB3, 0xAD, 0xAA, 0xB9, 0x00, 0x00, //$70
|
||
|
// High mirror, shift modified keys
|
||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //$80 0
|
||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0xD1, 0xA1, 0x00, 0x00, 0x00, 0xDA, 0xD3, 0xC1, 0xD7, 0xC0, 0x00, //$90 1
|
||
|
0x00, 0xC3, 0xD8, 0xC4, 0xC5, 0xA4, 0xA3, 0x00, 0x00, 0xA0, 0xD6, 0xC6, 0xD4, 0xD2, 0xA5, 0x00, //$A0 2
|
||
|
0x00, 0xCE, 0xC2, 0xC8, 0xC7, 0xD9, 0xDE, 0x00, 0x00, 0x00, 0xCD, 0xCA, 0xD5, 0xA6, 0xAA, 0x00, //$B0 3
|
||
|
0x00, 0xBC, 0xCB, 0xC9, 0xCF, 0xA9, 0xA8, 0x00, 0x00, 0xBE, 0xBF, 0xCC, 0xBA, 0xD0, 0xAD, 0x00, //$C0 4
|
||
|
0x00, 0x00, 0xA2, 0x00, 0x00, 0xAB, 0x00, 0x00, 0x00, 0x00, 0x8D, 0x00, 0x00, 0x00, 0x00, 0x00, //$D0 5
|
||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0xB1, 0x00, 0xB4, 0xB7, 0x00, 0x00, 0x00, //$E0 6
|
||
|
0xB0, 0xAE, 0xB2, 0xB5, 0xB6, 0xB8, 0x9B, 0x00, 0x00, 0xAB, 0xB3, 0xAD, 0xAA, 0xB9, 0x00, 0x00 //$F0 7
|
||
|
};
|
||
|
|
||
|
// keyboard scan buffer
|
||
|
unsigned short keyboard_data[3] = {0, 0, 0};
|
||
|
unsigned char keyboard_buf_indx = 0, keyboard_mbyte = 0;
|
||
|
boolean shift_enabled = false;
|
||
|
|
||
|
// In apple II scancode format
|
||
|
volatile unsigned char keymem = 0;
|
||
|
|
||
|
unsigned char keyboard_read() {
|
||
|
return keymem;
|
||
|
}
|
||
|
|
||
|
void keyboard_strobe() {
|
||
|
keymem&=0x7F;
|
||
|
}
|
||
|
|
||
|
// clock must be on digital 3
|
||
|
void keyboard_begin() {
|
||
|
pinMode(3, INPUT_PULLUP);
|
||
|
pinMode(KEYBD_DATA_PIN, INPUT_PULLUP);
|
||
|
attachInterrupt(1, keyboard_bit, FALLING);
|
||
|
}
|
||
|
|
||
|
void keyboard_bit() {
|
||
|
if(digitalRead(KEYBD_DATA_PIN))keyboard_data[2] |= _BV(keyboard_buf_indx);
|
||
|
else keyboard_data[2] &= ~(_BV(keyboard_buf_indx));
|
||
|
if(++keyboard_buf_indx == 11) {
|
||
|
// Ignore parity checks for now
|
||
|
keyboard_data[2] = (keyboard_data[2]>>1)&0xFF;
|
||
|
|
||
|
// extended keys
|
||
|
if(keyboard_data[2] == 0xF0 || keyboard_data[2] == 0xE0) keyboard_mbyte = 1;
|
||
|
else {
|
||
|
//decrement counter for multibyte commands
|
||
|
if(keyboard_mbyte) keyboard_mbyte--;
|
||
|
// multibyte command is finished / normal command, process it
|
||
|
if(!keyboard_mbyte) {
|
||
|
if(keyboard_data[1] != 0xF0 && keyboard_data[1] != 0xE0) {
|
||
|
//Standard keys
|
||
|
if(keyboard_data[2] == 0x12 || keyboard_data[2] == 0x59) shift_enabled = true; //shift modifiers
|
||
|
else keymem = pgm_read_byte_near(scancode_to_apple+keyboard_data[2]+((shift_enabled)?0x80:0x00));
|
||
|
} else if(keyboard_data[0] != 0xF0 && keyboard_data[1] == 0xE0) {
|
||
|
//Extended keys
|
||
|
if(keyboard_data[2] == 0x6B) keymem = 0x95; //back key
|
||
|
if(keyboard_data[2] == 0x74) keymem = 0x88; //forward key
|
||
|
// Power management keys, hardware reset
|
||
|
if(keyboard_data[2] == 0x37) {
|
||
|
// enable watchdog with min timeout
|
||
|
// wait until reset
|
||
|
wdt_enable(WDTO_15MS);
|
||
|
for(;;);
|
||
|
}
|
||
|
} else if(keyboard_data[1] == 0xF0 && (keyboard_data[2] == 0x12 || keyboard_data[2] == 0x59)) shift_enabled = false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//shuffle buffer
|
||
|
keyboard_data[0] = keyboard_data[1];
|
||
|
keyboard_data[1] = keyboard_data[2];
|
||
|
keyboard_buf_indx = 0;
|
||
|
}
|
||
|
}
|