/* HTLCD controller */
/* Designed by Paolo Subiaco http://www.creasol.it */

#include "main.h"
#include "htlcd.h"

#pragma rambank0
const uchar	htlcd_addrNumEF[4]={14,11,0,3};
const uchar	htlcd_addrNumADG[4]={13,10,1,4};
const uchar	htlcd_addrNumBC[4]={12,8,2,5};
const uchar htlcd_charTable[10]={0x77,0x03,0x5d,0x1f,0x2b,0x3e,0x7e,0x07,0x7f,0x3f};
uchar htlcd_data[15];
uchar romchar;
#pragma norambank
unsigned htlcd_mem[19]@0x140;
#pragma rambank0

#define HTLCD_DISPLAY_ASM

#ifdef HTLCD_DISPLAY_ASM
void htlcd_display(void) {
	_emi=0;	// disable interrupts
	romchar=sizeof(htlcd_data);		
	#asm
	clr __bp		; be sure to access general purpose memory
	mov a,OFFSET _htlcd_data;
	mov __mp0,a	; mp0 access to htlcd_data[]
	mov a,040h+10	; HT49R50_48SSOP start from SEG10
	mov __mp1,a	; mp1 access to LCD memory
htlcd_display1:
	mov a,__iar0	; read from htlcdData[] RAM buffer
	inc __bp			; Bank1 (LCD memory)
	mov __iar1,a	; Write to LCD memory
	clr __bp			; Bank0 (RAM memory)
	inc __mp0
	inc __mp1
	sdz _romchar
	jmp htlcd_display1
	#endasm
	_emi=1;	// reenable interrupts
}

#else
void htlcd_display() {
	uchar romchar;
	for(romchar=0; romchar<sizeof(htlcd_data); romchar++) {
		htlcd_mem[romchar]=htlcd_data[romchar];
	}
}
#endif

void htlcd_allSegments(uchar value) {
	/*
	for (romchar=0;romchar<sizeof(htlcd_data);romchar++) {
		htlcd_data[romchar]=value;
	}
	*/
	romchar=sizeof(htlcd_data);
	#asm
	clr __bp
	mov a,OFFSET _htlcd_data
	mov __mp0,a
	mov a,htlcd_allSegments0
htlcd_allSegmentsLoop:
	mov __iar0,a
	inc __mp0
	sdz _romchar
	jmp htlcd_allSegmentsLoop	
	#endasm

	htlcd_display();
}

void htlcd_allSegmentsOff(void) {
	_emi=0;
//	for (romchar=0; romchar<HTLCD_MEMORY_LENGTH; romchar++) {
//		htlcd_mem[romchar]=0;
//	}
  romchar=HTLCD_MEMORY_LENGTH;
	#asm
	clr __bp
	mov a,040h;
	mov __mp1,a
htlcd_allSegmentsOffLoop:
	inc __bp
	clr __iar1
	clr __bp
	inc __mp1
	;sz  __mp1.6
	sdz _romchar
	jmp htlcd_allSegmentsOffLoop
  #endasm
	_emi=1;
	
	htlcd_allSegments(0);
}

void htlcd_setNum(uchar value, uchar num) {
	if (value<=9) {
		romchar=htlcd_charTable[value];
	} else {
		romchar=value;
	}
	//ptr=htlcd_data+htlcd_addrNumBC[num];
	//*ptr&=~3;
	//*ptr|=(romchar&3);
	#asm
	clr __bp
	mov a,htlcd_setNum1;	num
	add a,OFFSET _htlcd_addrNumBC
	call OFFSET _htlcd_addrNumBC-1
	add a,OFFSET _htlcd_data
	mov __mp0,a
	mov a,__iar0
	and a,0ch
	mov __iar0,a
	mov a,_romchar
	and a,3
	orm a,__iar0
	#endasm	

	_rr(&romchar);
	_rr(&romchar);
	//ptr=htlcd_data+htlcd_addrNumADG[num];
	//*ptr&=~7;
	//*ptr|=romchar&7;
	#asm
	mov a,htlcd_setNum1;	num
	add a,OFFSET _htlcd_addrNumADG
	call OFFSET _htlcd_addrNumADG-1
	add a,OFFSET _htlcd_data
	mov __mp0,a
	mov a,__iar0
	and a,8
	mov __iar0,a
	mov a,_romchar
	and a,7
	orm a,__iar0
	#endasm

	_rr(&romchar);
	_rr(&romchar);
	_rr(&romchar);
	//ptr=htlcd_data+htlcd_addrNumEF[num];
	//*ptr&=~3;
  //*ptr|=(romchar&3);
	#asm
	mov a,htlcd_setNum1;	num
	add a,OFFSET _htlcd_addrNumEF
	call OFFSET _htlcd_addrNumEF-1
	add a,OFFSET _htlcd_data
	mov __mp0,a
	mov a,__iar0
	and a,0ch
	mov __iar0,a
	mov a,_romchar
	and a,3
	orm a,__iar0
	#endasm
}
	
void htlcd_setNum0(uchar value) {
	htlcd_setNum(value,0);
}

void htlcd_setPoint(uchar value) {
	htlcd_data[12]&=~4;
	htlcd_data[8]&=~4;
	htlcd_data[2]&=~4;
	if (value==1) {
		htlcd_data[12]|=4;
	} else if (value==2) {
		htlcd_data[8]|=4;
	} else if (value==3) {
		htlcd_data[2]|=4;
	}
}
	
void htlcd_setSymbol(uchar value) {
	htlcd_data[0]&=~4;
	htlcd_data[3]&=~4;
	htlcd_data[5]&=~4;
	htlcd_data[6]&=~3;
	htlcd_data[11]&=~4;
	if (value&SYMBOL_DEG) {
		htlcd_data[6]|=1;
	}
	if (value&SYMBOL_H) {
		htlcd_data[6]|=2;
	}
	if (value&SYMBOL_MJ) {
		htlcd_data[5]|=4;
	}
	if (value&SYMBOL_TOT) {
		htlcd_data[11]|=4;
	}
	if (value&SYMBOL_K) {
		htlcd_data[0]|=4;
	}
	if (value&SYMBOL_M) {
		htlcd_data[3]|=4;
	}
}

void htlcd_setColon(uchar value) {
	if (value==ON) {
		// turn Colon ON
		htlcd_data[7]|=1;
	} else if (value==OFF) {
		// turn Colon OFF
		htlcd_data[7]&=~1;
	} else {
		// Colon blinking
		htlcd_data[7]^=1;
	}
}

void htlcd_setWheel(uchar value) {
	if (value==ON) {
		// turn Colon ON
		htlcd_data[14]|=4;
	} else if (value==OFF) {
		// turn Colon OFF
		htlcd_data[14]&=~4;
	} else {
		// Colon blinking
		htlcd_data[14]^=4;
	}
}

void htlcd_setMC(uchar value) {
	if (value==ON) {
		// turn Colon ON
		htlcd_data[6]|=4;
	} else if (value==OFF) {
		// turn Colon OFF
		htlcd_data[6]&=~4;
	} else {
		// Colon blinking
		htlcd_data[6]^=4;
	}
}

/*
void htlcd_setBattery(uchar value) {
	if (value==ON) {
		// turn Colon ON
		htlcd_data[9]|=4;
	} else if (value==OFF) {
		// turn Colon OFF
		htlcd_data[9]&=~4;
	} else {
		// Colon blinking
		htlcd_data[9]^=4;
	}
}
*/
void htlcd_printZero() {
	htlcd_setNum(CHAR_Z,0);
	htlcd_setNum(CHAR_e,1);
	htlcd_setNum(CHAR_r,2);
	htlcd_setNum(CHAR_o,3);
}

void htlcd_printNull() {
	htlcd_setNum(CHAR_None,0);
	htlcd_setNum(CHAR_None,1);
	htlcd_setNum(CHAR_None,2);
	htlcd_setNum(CHAR_None,3);
}
