/* Keyboard.c, Copyright 1998 (c) by Lukas Ruf, Swiss Federal Institute of Technology, Computer Engineering and Networks Laboratory. TOPSY -- A Teachable Operating System. Implementation of a tiny and simple micro kernel for teaching purposes. For further information, please visit http://www.tik.ee.ethz.ch/~topsy This software is provided under the terms of the GNU General Public Licence. A full copy of the GNU GPL is provided in the file COPYING found in the development root of Topsy. */ /* This copyright notice supercedes all originally or previously used copyrights being used within the source code. Author: Lukas Ruf <lr@lpr.ch> */ // ************************************************************************** // // Copyrights (c) 1998 Lukas Ruf // // ************************************************************************** // // Keyboard: Creating of KeyTable.S // // Read ASCII Text File with structure as defined in Keyboard.dok // // Create a KeyTable.S File for translation (KeyTrlTbl) // // The Compiled File represents a data block in .data section // // Position in this block equals to the KEYCODE. // // The ASCII Character (8b) is located at this position // // COMMENTS in the Input file: ';' on first position of line !! // // Special ASCII Character: // // 0x00 : No Output to Keybuffer // // 0xFF : Send Associated Message (16b) located in KeyMsgTbl // // ************************************************************************** // #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include "TextRead.hpp" #define KEYTABLEFILE "KeyTable.S" void Hello() { printf("\nKeyboard: (c) by Lukas Ruf, lr@lpr.ch\n"); //printf("Program call: \n Keyboard <KeyboardLayoutFile> [Prefix] [TruncateFlag]\n"); return; } FILE *CreateKeyTable() { FILE *lf = fopen(KEYTABLEFILE,"w"); char *H1 = "/* KeyTable.S : Keycode to ASCII Character Table */\n", *H2 = "/* THIS FILE IS AUTOMATICALLY CREATED BY KEYBOARD */\n", *H3 = "/* KEYBOARD (c) 1998 Lukas Ruf, lr@lpr.ch */\n", *H4 = ".data\n.align 4,0x9090\n\n"; if (lf) { fwrite((void *)H1,1,strlen(H1),lf); fwrite((void *)H2,1,strlen(H2),lf); fwrite((void *)H3,1,strlen(H3),lf); fwrite((void *)H4,1,strlen(H4),lf); } return lf; } void CloseKeyTable(FILE *pf) { char *H1 = "/* End of KeyTable.S : Created for Topsy386 */\n"; if (pf) { fwrite((void *)H1,1,strlen(H1),pf); fclose(pf); } return; } int GetKeyCode(unsigned char *pkey) { // printf("Processing %s",pkey); int xret = -1; if (!pkey || !*pkey) return xret; int i = 0; bool ldec = true; while (pkey[i]) { // is KEYCODE a decimal number ? if (!(pkey[i] >= '0' && pkey[i] <= '9')) ldec = false; i++; } if (ldec) xret = atoi((const char*)pkey); // literals are not handled yet (TIME) else { // like ENTER, A, UP, etc. } return xret; } unsigned char GetASCIICode(unsigned char *pasc) { // printf(" -- ASCII Code %s \n",pasc); unsigned char xret = 0x00; if (!pasc || !*pasc) return xret; int i = 0; bool ldec = true; while (pasc[i]) { // is ASCIICODE a decimal number ? if (!(pasc[i] >= '0' && pasc[i] <= '9')) ldec = false; i++; } if (ldec) xret = (unsigned char)atoi((const char*)pasc); // literals are not handled yet (TIME) else if (*pasc == '#') // Message to be sent when key is pressed xret = 0xFF; else if (*pasc == '\'') // Normal ASCII code is specified xret = *(pasc+1); else { // DESCRIPTION OF ASCII like ENTER etc. } // not handled yet return xret; } ushort GetMsgNo(unsigned char *pasc) { ushort xret = 0x0000; if (!pasc || !*pasc) return xret; unsigned char *lc = new unsigned char[32]; int i = 0; if (*pasc++ == '#') { while (*pasc >= '0' && *pasc <= '9') { lc[i++] = *pasc; pasc++; } if (i) xret = (ushort)atoi((const char*)lc); } delete lc; return xret; } void Hexer(char *po, ushort pi, unsigned char pl) { char lHex[] = "0123456789ABCDEF"; po[pl+2] = 0x00; // make ASCIIZ po[0] = '0'; po[1] = 'x'; for (;(pl > 0);) { po[--pl+2] = lHex[pi%16]; pi /= 16; } return; } int ConvertInputToKeyTable(unsigned char *pi, unsigned char *ppref, bool pt) { int xret = 0, ik, ia, lmaxT = 0, lmaxM = 0; unsigned char *lkey = new unsigned char[32]; // KEYCODE unsigned char *lasc = new unsigned char[32]; // ASCII CODE unsigned char *ltbl = new unsigned char[1024]; // KeyTrlTbl ushort *lmsg = new ushort[1024]; // KeyMsgTbl memset(ltbl,0,1024); memset(lmsg,0,1024*2); printf("Convert %s using prefix %s\n",(char*)pi,(char*)ppref); TextReadC *tr = new TextReadC((char*)pi); while (!tr->EoF()) { unsigned char *lLine = tr->GetNextLine(); memset(lkey,0,32); ik = 0; memset(lasc,0,32); ia = 0; if (lLine && *lLine != ';') { // if not empty line or comment while (*lLine == ' ') lLine++; // skip leeding spaces while (*lLine && *lLine != ' ' && ik < 32-1) { lkey[ik++] = *lLine; lLine++; } while (*lLine == ' ') lLine++; // skip spaces between while (*lLine && *lLine != ' ' && ia < 32-1) { lasc[ia++] = *lLine; lLine++; } if (ik && ia) { /* Now: KEYCODE and TRANSLATED CODE (ASCII) are filled in */ int lkeypos = GetKeyCode(lkey); unsigned char lascii = GetASCIICode(lasc); if (lkeypos > lmaxT) lmaxT = lkeypos; if (lkeypos > -1) ltbl[lkeypos] = lascii; else xret = 1; if (lascii == 0xFF && lkeypos > -1) { if (lkeypos > lmaxM) lmaxM = lkeypos; ushort lmsgno = GetMsgNo(lasc); lmsg[lkeypos] = lmsgno; } } else xret = 1; } } if (!xret) { FILE *lo = CreateKeyTable(); if (lo) { char *lobuff = new char[256]; *lobuff = 0x00; char tmp[12]; tmp[0] = 0x00; if (!(pt && !lmaxT)) { lmaxT++; if (!pt) lmaxT = 1024; lmaxT = ((lmaxT >> 3)+1) << 3; fwrite(".globl ",1,7,lo); if (ppref) strcpy(lobuff,(char*)ppref); strcat(lobuff,"KeyTrlTbl"); fwrite(lobuff,1,strlen(lobuff),lo); fwrite("\n\n",1,2,lo); strcat(lobuff,":"); for (int i = 0; (i < lmaxT); i++) { if (i % 8 == 0x00) { sprintf(tmp," // %.3X\n",i); strcat(lobuff,tmp); fwrite((void *)lobuff,1,strlen(lobuff),lo); memset(lobuff,0,256); strcat(lobuff,".byte "); } Hexer(tmp,ltbl[i],2); strcat(lobuff,tmp); tmp[0] = 0x00; if ((i+1) % 8 != 0x00) strcat(lobuff,", "); } } strcat(lobuff,"\n\n"); fwrite((void *)lobuff,1,strlen(lobuff),lo); *lobuff = 0x00; tmp[0] = 0x00; if (!(pt && !lmaxM)) { lmaxM++; if (!pt) lmaxM = 1024; lmaxM = (lmaxM >> 3) << 3; fwrite(".globl ",1,7,lo); if (ppref) strcpy(lobuff,(char*)ppref); strcat(lobuff,"KeyMsgTbl"); fwrite(lobuff,1,strlen(lobuff),lo); fwrite("\n\n",1,2,lo); strcat(lobuff,":"); for (int i = 0; (i < lmaxM); i++) { if (i % 8 == 0x00) { sprintf(tmp," // %.3X\n",i); strcat(lobuff,tmp); fwrite((void *)lobuff,1,strlen(lobuff),lo); memset(lobuff,0,256); strcat(lobuff,".byte "); } Hexer(tmp,lmsg[i],4); strcat(lobuff,tmp); tmp[0] = 0x00; if ((i+1) % 8 != 0x00) strcat(lobuff,", "); } } strcat(lobuff,"\n\n"); fwrite((void *)lobuff,1,strlen(lobuff),lo); delete lobuff; CloseKeyTable(lo); } else xret = 1; } delete tr; delete ltbl; delete lmsg; delete lasc; delete lkey; return xret; } int main(int argc, char **argv) { Hello(); if (argc > 3) return ConvertInputToKeyTable((unsigned char*)argv[1],(unsigned char*)argv[2],true); if (argc > 2) return ConvertInputToKeyTable((unsigned char*)argv[1],(unsigned char*)argv[2],false); if (argc > 1) return ConvertInputToKeyTable((unsigned char*)argv[1],NULL ,false); return 1; }