/*
  */

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

#define CLRSCR "\033[;H\033[2J"
#define CURHOME "\033[;H"

#define LCDX1 (5 * 12)
#define LCDX2 (5 * 16)

#define LCD1 0x7000
#define LCD2 0x703c
#define LCD3 0x7068
#define LCD4 0x707c

#define ROMFONT 0x806c

#define EOS '\0'

#define XMAX 80

#define log2phy(x) ((x) + (x) / 5)

/* アドレスからx座標に変換 */
#define add2x(a) \
    (((a) < LCD2) ? ((a) - LCD1) : (LCD4 - 1 - (a) + 60))

/* x座標からアドレスに変換 */
#define x2add(x) \
    (((x) < (LCD2 - LCD1)) ? ((x) + LCD1) : (LCD4 - (x) + LCD1 - LCD2))

#define showbyadd(a) {int x; x = add2x(a); showone(log2phy(x), mainram[a]);}

/* static int a2x[100]; */
static int x2a[100];

void lcdinit()
{
    int x;

    /* x座標とメモリアドレスの対応表の作成 */
    for (x = 0; x < LCDX1; x++) {
	x2a[x] = LCD1 + x;
    }
    for (x = LCDX1; x < LCDX2; x++) {
	x2a[x] = LCD3 + (LCDX2 - x - 1);
    }
}

char *sym1[] = {"KANA", "S/K", "SML", "STAT"};
char *sym2[] = {"BUSY", "DEF", "SHIFT", "HYP", "PRO", "RUN", "CAL"};
char *sym3[] = {"E", "M", "()", "RAD", "G", "DE", "PRINT"};
#define SYM1 0x703c
#define SYM2 0x703d
#define SYM3 0x707c

void symdisp()
{
    int i, j;

    j = 1;
    for (i = 0; i < 7; i++) {
	printf("%-5s ", (mainram[SYM2] & j) ? sym2[i] : "");
	j *= 2;
    }
    j = 1;
    for (i = 0; i < 4; i++) {
	printf("%-4s ", (mainram[SYM1] & j) ? sym1[i] : "");
	j *= 2;
    }
    j = 1;
    for (i = 0; i < 3; i++) {
	printf("%-3s ", (mainram[SYM3] & j) ? sym3[i] : "");
	j *= 2;
    }
    printf("%-2s", (mainram[SYM3] & 0x20) ? sym3[5] : "");
    printf("%-1s", (mainram[SYM3] & 0x10) ? sym3[4] : "");
    printf("%-3s ", (mainram[SYM3] & 0x08) ? sym3[3] : "");
    printf("%-5s", (mainram[SYM3] & 0x40) ? sym3[6] : "");
    printf("\r\n");
    fflush(stdout);
}


char lcdtochar(int addr)
{
    int i;
    int ch;

    for (ch = 0x20; ch < 0x7f; ch++) {
	for (i = 0; i < 5; i++) {
	    if (mainram[ROMFONT + (ch - 0x20) * 5 + (4 - i)]
		!= mainram[addr + i]) {
		break;
	    }
	}
	if (i >= 5) {
	    return(ch);
	}
    }
    return(' ');
}


char lcdtochar2(int addr)
{
    int i;
    int ch;

    for (ch = 0x20; ch < 0x7f; ch++) {
	for (i = 0; i < 5; i++) {
	    if (mainram[ROMFONT + (ch - 0x20) * 5 + i] != mainram[addr + i]) {
		break;
	    }
	}
	if (i >= 5) {
	    return(ch);
	}
    }
    return(' ');
}


char *lcdtostr()
{
    int i;
    int addr;
    static char s[17];

    for (i = 0; i < 12; i++) {
	addr = 5 * i + LCD1;
	s[i] = lcdtochar(addr);
    }
    for (i = 12; i < 16; i++) {
	addr = LCD4 + 5 * (11 - i);
	s[i] = lcdtochar2(addr);
    }
    s[i] = EOS;
    return(&s[0]);
}


void clearall()
{
    printf(CLRSCR);
}


void displayall()
{
    int x;
    int b;

    printf(CURHOME);
    symdisp();
    for (b = 1; b < 0x80; b *= 2) {
	for (x = 0; x < XMAX; x++) {
	    if ((mainram[x2a[x]] & b) != 0) {
		putchar('#');
	    }
	    else {
		putchar('.');
	    }
	    if (x % 5 == 4) {
		putchar(' ');
	    }
	}
	putchar('\r');
	putchar('\n');
    }
    printf("%s\r\n", lcdtostr());
}


void busy()
{
    printf(CURHOME);
    printf("BUSY\r");
}




#ifdef MAIN
main()
{
    int x;

    lcdinit();
    for (x = 0; x < 80; x++) {
	printf("%04x ", x2a[x]);
	if (x % 5 == 4) {
	    putchar('\n');
	}
    }
}
#endif
