/*
 * Example for LCD and Keyboard from MCT-Mail 03/1995
 */

#include <stdio.h>
#include "target.h"


/* Define macros to access the hardware */
/* OUT0 ... OUT4, RS, R/W, E */
#define OUT1   (((volatile unsigned char*)TLX_1) [1])
/* LCD0 ... LCD7 */
#define OUT2   (((volatile unsigned char*)TLX_1) [3])
/* IN0 ... IN7 */
#define IN     (((volatile unsigned char*)TLX_1) [3])

/* Define macro to set or reset the output latches */
/* out_1 is a shadowregister                       */
unsigned char out_1;
#define R_OUT1(x)    out_1 &= (x); OUT1 = out_1;
#define S_OUT1(x)    out_1 |= (x); OUT1 = out_1;

#define IR 0            /* IR = Instruction register of LCD */
#define DR 1            /* DR = Data register of LCD        */

/*
 * Write one char to the LCD (instruction or data)
 */
void
lcd_wr(char zei, unsigned char adr){
        
    R_OUT1(~0xe0);
    S_OUT1((adr << 5) & 0xe0);      /* Set RS           */
    _delay(5000);
    S_OUT1(0x80);                   /* = 10XX XXXX      */
    OUT2 = zei;
}

/*
 * Initialize the LCD
 */
void
lcd_init(void){
    static int init;

    if(!init){
        /* Function set DL = 8 bit */
        lcd_wr(0x38, IR);    
        /* Display clear */
        lcd_wr(0x01, IR);
        /* Display/cursor home */
        lcd_wr(0x02, IR);
        /* Entry mode set */
        lcd_wr(0x06, IR);
        /* Display ON , Cursor ON, Character at cursor position unblinks */
        lcd_wr(0x0e, IR);
        /* Display/cursor shift */
        lcd_wr(0x14, IR);
        init = 1;
    }
}

/*
 * Write one char to the LCD in order to the position
 */
void
lcd_write(char zei){
    static int x_pos = 0, y_pos = 0;
    lcd_init();
    
    lcd_wr(zei, DR);
    x_pos++;
    if(x_pos == 16){
        x_pos = 0;
        lcd_wr(0xC0, IR);       /* Set line two */
        y_pos = 1;
    }
}

/*
 * Write a string to the LCD, than scan the keyboard for everytime
 * and display the pressed key on the hostmonitor.
 */
void
main(void){
    int i, z, value, taste = 0;
    unsigned char spalte[4] = {~0x01, ~0x02, ~0x04, ~0x08};
    char tabelle[16] = {'*','0','.','\n','1','2','3','C',
                        '4','5','6','B','7','8','9','A'};
    char    ch[32] = "MCT Paul &         Scherer GmbH ";

    /* Write the string to the LCD */
    for(i = 0; i < 32; lcd_write(ch[i++]));

    /* Scan the keyboard */
    while(1){
        for(z = 0; z < 4; z++){
            S_OUT1(0x1f);
            R_OUT1(spalte[z]);
            value = IN & 0x0f;
            if(value < 0x0f){
                switch(value){
                    case 0x0e: taste = 1 + (z * 4);
                               break;
                    case 0x0d: taste = 2 + (z * 4);
                               break;
                    case 0x0b: taste = 3 + (z * 4);
                               break;
                    case 0x07: taste = 4 + (z * 4);
                               break;
                    default: taste = 0;
                }
            }
            if(taste) printf("%c", tabelle[taste - 1]);
            fflush(stdout);
            taste = 0;
            _delay(70000);
        }
    }
}

