$NOMOD51
$include (C8051F98x.inc)     
            
CS_MIN		EQU 1183		; calibration values
CS_RANGE		EQU 225		

RTC0CN_Local 	EQU 0x80		; default SmaRTClock cfg. value
PMU0CF_Snapshot 	EQU R5
Period_low		EQU 0xFE		; 0x00 for 1 sek
Period_high		EQU 0xFF		; 0x80 for 1 sek
Light_TH		EQU 0x10		; ambient light intensity threschold

	DSEG 	AT 0x20			; data segment in direct addressable space
Status:	DS 1				; status bits for circular buffer
Counter:	DS 1				; counter for the # of measurements

	ORG	0x30
bufTemp: 	DS 16				; circular buffer for temperature (8x 2-byte entries)
tempAve_lo:	DS 1				; storage for temperature average sum
tempAve_hi:	DS 1

	ORG 	0x50
bufHumi:	DS 8				; curcular buffer for humidity
humiAve_lo: DS 1				; storage for humidity average sum
humiAve_hi: DS 1

	CSEG 	AT 0				; interrupt vectors
	ljmp 	Main  			; reset

	ORG	0xB3
	USING    0                    ; specify register bank 

main:       
	anl   PCA0MD, #NOT(0x40)      ; disable the WDT
	mov	SP, #0x79			; setup stack

	acall	Ports_Setup
	acall	Clock_Setup
	acall	Debug_Trap			; debug trap !!!

	acall	RTC_Setup			; initialize hardware
	acall	ADC_Setup
	acall	CS0_Setup

	mov	Counter, #1			; initialize conversion counter
	mov	Status, #3			; request circ buffer initialization
	sjmp	measure

loop: 					; MAIN LOOP
	acall	LPM   			; enter sleep until next alarm
	mov	A, PMU0CF_Snapshot
	anl	A, #RTCAWK			; RTC_Alarm ?
	jz	loop				; NO - back to sleep	

measure:					; YES - do measurements
	acall	getTempHumi			; update temp & Humi values on display
;	sjmp	loop				; uncomment this line if no light sensor present

	mov	A, Counter			
	cjne	A, #0, loop			; time to check light? 
	acall getLight			; YES - is light ON ?		
	jnc	loop				; YES - continue the main loop

	acall	display_OFF			; NO - disable LCD oscillator 
wait4light:					; and check for light periodically
	acall	LPM				; sleep till the next light test
	acall	getLight			; is it dark yet ?
	jc	wait4light			; YES - keep waiting

	mov	Status, #3			; NO - request circ buffer initialization
	setb	P0.4				; turn on LCD oscillator
	sjmp	measure			; back to the main loop

;-------------------PROCEDURES-------------------------------------------
Ports_Setup:
	mov  	P0MDIN,    #0xF1		; analog input on P0[3:1] 	
	mov  	P0MDOUT,   #0xF1		; push-pull out on P0[0] and P0[7:4]
	mov  	P1MDIN,    #0xFF		; digital I/O on P1
    	mov  	P1MDOUT,   #0x7F		; digital input out on P1.7
    	mov  	P0SKIP,    #0xFF		; CS input on P0.3
    	mov  	P1SKIP,    #0xFF		; I/O function on P1
    	mov   XBR2,      #0x40		; enable XBar and weak pull-ups	
	mov	P0, 	     #0x1E
	mov	P1, 	     #0xA0		; initialize port pins
	ret

;-----------------------------------------------------------------------
Clock_Setup:
	mov	RTC0ADR, #(0x10 OR RTC0XCN)	
	mov	RTC0DAT, #RTC0AEN		; enable LFO
	nop
   	mov	RTC0ADR, #(0x10 OR RTC0CN)	; enable SmaRTClock
	mov	RTC0DAT, #(RTC0CN_Local OR RTC0TR)  

	mov	SFRPAGE, #0xF		; switch to SFR page 0xF
	mov	PMU0MD,  #0			; enable POR supply monitor
	mov	SFRPAGE, #0			; switch to default SFT page
	mov 	RSTSRC,  #0x06		; enable MCD and VDD monitor
	anl	OSCICN,  #NOT(0x80)	; disable internal precision oscillator
	mov	REG0CN,  #0			; disable precision oscillator bias
	mov	OSCXCN,  #0			; disable external oscillator
	mov	CLKSEL,  #0x03		; select SmaRTClock with 1:1 clock divider
	mov	A, CLKSEL			; wait for the divider setting to be applied
	anl	A, #0x80		
	jz	$-4		
	ret

;-----------------------------------------------------------------------
Debug_Trap:
	mov	R2, #0xFF
	mov	A,  #0xFF

del_loop:					; nested loops for approx. 10 sec delay
	dec	A
	nop
	nop
	jnz	$-3

	mov	A, R2
	dec	A
	mov	R2, A
	jnz	del_loop	

	jnb	P1.7, $			; additional debug trap !!!

	mov	CLKSEL, #0x04		; select LPO with 1:1 clock divider
	orl	FLSCL, #BYPASS		; set the one-shot bypass bit
	mov	A, CLKSEL			; wait for the divider setting to be applied
	anl	A, #0x80		
	jz	$-4
	mov 	PMU0CF, #CLEAR
	ret

;-----------------------------------------------------------------------
RTC_Setup:
	mov 	RTC0ADR, #(0x10 + CAPTURE0)	; clear RTC timer
	mov 	RTC0DAT, #0				; autoincrement address
	nop						; feature does not work!
	mov 	RTC0ADR, #(0x10 + CAPTURE1)
	mov 	RTC0DAT, #0
	nop
	mov 	RTC0ADR, #(0x10 + CAPTURE2)
	mov 	RTC0DAT, #0
	nop
	mov 	RTC0ADR, #(0x10 + CAPTURE3)
	mov 	RTC0DAT, #0
	nop
	mov	RTC0ADR, #RTC0CN		; set timer value
	mov	RTC0DAT, #(RTC0CN_Local OR RTC0SET) 
	nop
	mov 	RTC0ADR, #(0x90 OR RTC0CN)
	nop
	nop
	nop
	mov 	A, RTC0DAT			
	anl	A, #RTC0SET			; verify that timer is set
	jnz	$-10

	mov	R6, #Period_low
	mov	R7, #Period_high
ALARM_Setup:
   	mov	RTC0ADR, #(0x10 OR RTC0CN)	; disable alarm while
   	mov	RTC0DAT, #(RTC0CN_Local AND NOT(RTC0AEN)) ; updating the regs      
   	nop
	mov 	RTC0ADR, #(0x10 OR ALARM0)	; load alarm regs       
	mov   RTC0DAT, R6
	nop
	mov 	RTC0ADR, #(0x10 OR ALARM1)
	mov	RTC0DAT, R7
	nop
	mov 	RTC0ADR, #(0x10 OR ALARM2)
	mov	RTC0DAT, #0 
	nop
	mov 	RTC0ADR, #(0x10 OR ALARM3)
	mov	RTC0DAT, #0
	nop
   	mov	RTC0ADR, #(0x10 OR RTC0CN)	; enable SmaRTClock
	mov	RTC0DAT, #(RTC0CN_Local OR RTC0TR OR RTC0AEN OR ALRM)  
	ret

;-----------------------------------------------------------------------
ADC_Setup:
   	mov	ADC0CN, #0			; ADC0 disabled, Burst Mode disabled 
	mov 	ADC0CF, #0x11 		; SAR clock = 6.6MHz, gain = 1
   	mov	ADC0AC, #0              ; right-justify results
	ret

;-----------------------------------------------------------------------
CS0_Setup:
	mov	CS0CN,   #0x80		; enable Capacitive Sense module CS0
	mov	CS0CF,   #0x00		; accumulate no samples
	mov	CS0MD1,  #0x00		; gain = 1x
	mov	CS0MD2,  #0x28		; set 12-bit resolution, discharge time 3 usec 
	mov	CS0MX,   #0x03		; select channel P0.3
	mov	CS0THH,  #0x00		; set-up digital comparator
	mov	CS0THL,  #0xFF		; for waking up the CPU from SUSPEND
	mov	CS0CN,   #0x00		; turn the module off
	ret

;-----------------------------------------------------------------------
getLight:
	mov	ADC0MX, #1			; select P0.1 as ADC input
	mov	REF0CN, #0x18           ; enable high-speed ref
	mov	ADC0CN, #0x80		; enable ADC

	mov	A, #10			; 10 usec delay		
	dec	A				; 1 cycle
	nop					; 1 cycle
	nop					; 1 cycle
	jnz	$-3				; 2 cycles

	orl	ADC0CN, #0x10		; start conversion
	nop
	nop	
	mov	A, ADC0CN			; poll BUSY flag
	anl	A, #0x10
	jnz	$-5    	

	mov	ADC0CN, #0			; turn off ADC
	mov	REF0CN, #0			; turn off reference

	clr	C
	mov	A, ADC0L			; get conversion result
	subb	A, #Light_TH
	mov	A, ADC0H
	subb	A, #0

	ret

;-----------------------------------------------------------------------
display_OFF:
	mov	A, #0x0A			; turn off display
	mov	DPTR, #table7seg		; initialize 7-seg table pointer
	movc	A, @A+DPTR			; get blank code 
	mov	P1, A
	nop
	nop
	nop
	setb	P1.0				; latch it into all digits
	setb	P0.6
	nop
	nop
	nop
	clr	P1.0
	clr	P0.6
	clr	P0.4				; stop LCD oscillator
	setb	P1.5				; clear units symbol
	setb	P1.6
	ret

;-----------------------------------------------------------------------
getTempHumi:
	inc	Counter
	jnb	Counter.0, getTemp
	ajmp	getHumi

getTemp:
	setb	P0.0				; turn sensor on
	mov	R6, #0x20			; use RTC clock to perform a
	mov	R7, #0x00			; 1 msec delay, which is needed
	acall	ALARM_Setup			; for sensor to set up
	acall	LPM   			; enter sleep mode until next alarm
	nop
	mov	R6, #Period_low		; reassign RTC clock to its regular
	mov	R7, #Period_high		; wake-up time
	acall	ALARM_Setup

	mov	ADC0MX, #2			; select P0.2 as ADC input
	mov	REF0CN, #0x18           ; enable high-speed ref
	mov	ADC0CN, #0x80		; enable ADC

	mov	A, #10			; 10 usec delay		
	dec	A				; 1 cycle
	nop					; 1 cycle
	nop					; 1 cycle
	jnz	$-3				; 2 cycles

	orl	ADC0CN, #0x10		; start conversion
	nop
	nop	
	mov	A, ADC0CN			; poll BUSY flag
	anl	A, #0x10
	jnz	$-5    	

	mov	ADC0CN, #0			; turn off ADC
	mov	REF0CN, #0			; turn off reference
	clr	P0.0				; turn off sensor
	mov	R2, ADC0L			; save ADC values in registers
	mov	R3, ADC0H

	jnb	Status.0, average_TEMP	; init circ buffer ?
	clr	Status.0			; YES
	mov	R0, #bufTemp		; initialize buffer pointer		
	mov	bufTemp+0, R2		; fill the buffer with
	mov	bufTemp+2, R2		; temp reading (lower byte)
	mov	bufTemp+4, R2
	mov	bufTemp+6, R2
	mov	bufTemp+8, R2
	mov	bufTemp+10, R2
	mov	bufTemp+12, R2
	mov	bufTemp+14, R2
	
	mov	bufTemp+1, R3		; fill the buffer with 
	mov	bufTemp+3, R3		; temp reading (upper byte)
	mov	bufTemp+5, R3
	mov	bufTemp+7, R3
	mov	bufTemp+9, R3
	mov	bufTemp+11, R3
	mov	bufTemp+13, R3
	mov	bufTemp+15, R3	

	mov	A, R2
	mov	B, #8				; compose the average sum by
	mul	AB				; multilpying current temp by 8
	mov	tempAve_lo, A
	mov	tempAve_hi, B
	mov	B, #8
	mov	A, ADC0H
	mul	AB
	add	A, tempAve_hi
	mov	tempAve_hi, A
	ajmp	process_TEMP

average_TEMP:
	mov	A, tempAve_lo		; subtract the oldest temp value
	clr	C				; in circular buffer from the 
	subb	A, @R0			; average temp sum
	mov	tempAve_lo, A
	inc	R0				; advance pointer to higher-order byte
	mov	A, tempAve_hi
	subb	A, @R0
	mov	tempAve_hi, A
	
	dec	R0
	mov	@R0, ADC0L			; save new temp in circular buffer
	inc	R0				; update circ buffer pointer
	mov	@R0, ADC0H
	inc	R0
	cjne	R0, #0x40, $+5		; jump over the next instruction
	 mov	R0, #0x30			; take pointer R0 mod 16

	mov	A, tempAve_lo		; update average temp sum
	add	A, ADC0L
	mov	tempAve_lo, A
	mov	A, tempAve_hi
	addc	A, ADC0H
	mov	tempAve_hi, A		; at this point C = 0

	mov	A, tempAve_lo		; average temp sum (div. by 8)	
	rlc	A				; for that we multiply it by 2 
	swap	A				; and swap the nibbles
	anl	A, #0x0F
	mov	R2, A				; R2 contains the lower nibble
	mov	A, tempAve_hi
	rlc	A				; C is not modified since the
	swap	A				; last add
	mov	B, A
	anl	A, #0xF0
	add	A, R2
	mov	R2, A
	mov	A, B				
	anl	A, #0x0F
	mov	R3, A

process_TEMP:
	mov	B, #165			; multiply ADC by 165 (2 bytes x 1 byte)
	mov	A, R2
	mul	AB
	mov	R2, B
	mov	B, #165
	mov	A, R3
	mul	AB
	add	A, R2				; A = lower byte, B = higher byte
	mov	R2, A
      mov  	A, B
      addc	A,  #0
	mov	R3, A				; R3:R2 = ADC_temp * 165 / 256

	mov	A, R2				; subtract 50*4-2 = 198 and round off
	add	A, #0x3A			; 198 = 0xFF3A
	mov	R2, A
	mov	A, R3
	addc	A, #0xFF
	mov	R3, A				; R3:R2 = ADC_temp * 165 / 256 - 200

	mov	C, ACC.7			; divide R3:R2 by 4 (signed) 
	rrc	A
	mov	R3, A
	mov	A, R2
	rrc	A
	mov	R2, A
	mov	A, R3
	mov	C, ACC.7
	rrc	A
	mov	R3, A
	mov	A, R2
	rrc	A				
	mov	R2, A				; R3:R2 = ADC_temp * 165 / 1024 - 50

	mov	A, R3				; check computed data range	
	jnb	ACC.7, $+6			; if R3:R2 < 0, set R2=0
	clr	A
	sjmp	display_TEMP		

	clr	C				; if R3:R2 > 99, set R2=99 
	mov	A, R2
	subb	A, #100
	mov	A, R3
	subb	A, #0
	jc	display_TEMP
	mov	R2, #99			

display_TEMP:
	mov	A, R2
	mov	B, #10
	div	AB				; A = tens of temp, B = units of temp
	cjne	A, #0, $+5			; skip over the next instruction
	 mov	A, #10			; load blank code
	mov	DPTR, #table7seg		; initialize 7-seg table pointer
	movc	A, @A+DPTR			; get code of dig1
	mov	P1, A
	nop
	nop
	nop
	setb	P1.0				; latch in the first digit
	nop
	nop
	nop
	clr	P1.0
	
	mov	A, B
	movc	A, @A+DPTR			; get code of dig2
	mov	P1, A
	nop
	nop
	nop
	setb	P0.6				; latch in the second digit
	nop
	nop
	nop
	clr	P0.6

	setb	P1.5				; display units (degrees C)
	clr	P1.6				
	ret

;-----------------------------------------------------------------------
getHumi:
	mov	CS0CN,   #0x88		; enable Capacitive Sense module CS0
	nop
	orl	CS0CN, #0x10		; start conversion
	acall	wait4CS0			; enter SUSPEND mode till the end of conversion        	
	mov	CS0CN, #0x00		; power-off CS0 module

	mov	A, CS0DL			; shift Humi value 4 bits to the left 
	swap	A				; needed for 12-bit CS0 resolution
	anl	A, #0x0F
	mov	R2, A				; R2 = lower nibble
	mov	A, CS0DH
	swap	A
	mov	B, A
	anl	A, #0xF0
	orl	A, R2
	mov	R2, A
	mov	A, B
	anl	A, #0x0F
	mov	R3, A

	clr	C				; subtract ADC offset
	mov	A, R2
	subb	A, #(CS_MIN MOD 256)
	mov	R2, A
	mov	A, R3
	subb	A, #(CS_MIN / 256)
	mov	R3, A

	jnc	gh1				; index >= 0 ? YES - proceed
	mov	R2, #0			; NO - set index=0
	sjmp	gh2

gh1:
	clr	C
	mov	A, R2	
	subb	A, #CS_RANGE		; index in range ?
	jc	gh2				; YES - proceed
	mov	R2, #CS_RANGE		; NO - set index=MAX

gh2:
	mov	A, R2				; ACC = humi index (8 bit)
	jnb	Status.1, average_HUMI	; init circ buffer ?
	clr	Status.1			; YES
	mov	R1, #bufHumi		; YES - initialize buffer pointer
	mov	bufHumi, A			; fill the buffer with the
	mov	bufHumi+1, A		; temp reading
	mov	bufHumi+2, A
	mov	bufHumi+3, A
	mov	bufHumi+4, A
	mov	bufHumi+5, A
	mov	bufHumi+6, A
	mov	bufHumi+7, A

	mov	R2, A				; save ACC
	mov	B, #8				; compose the average sum by
	mul	AB				; multilpying the current temp
	mov	humiAve_lo, A		; by 8
	mov	humiAve_hi, B
	mov	A, R2				; restore ACC
	ajmp	display_HUMI

average_HUMI:
	mov	B, A				; save humi value
	mov	A, humiAve_lo		; subtract the oldest humi value
	clr	C				; in circular buffer from the 
	subb	A, @R1			; average humi sum
	mov	humiAve_lo, A
	mov	A, humiAve_hi
	subb	A, #0
	mov	humiAve_hi, A
	
	mov	@R1, B			; save new humi in circular buffer
	inc	R1				; update circ buffer pointer
	anl	1, #0xF7			; take pointer R1 mod 8

	mov	A, humiAve_lo		; update average humi sum
	add	A, B
	mov	humiAve_lo, A
	mov	A, humiAve_hi
	addc	A, #0
	mov	humiAve_hi, A

	clr	C
	mov	A, humiAve_lo		; average humi sum (div. by 8)	
	rlc	A				; for that we multiply it by 2 
	swap	A				; and swap the nibbles
	anl	A, #0x0F
	mov	R2, A				; R2 contains the lower nibble
	mov	A, humiAve_hi
	rlc	A				; C is not modified since the
	swap	A				; last add
	anl	A, #0xF0
	add	A, R2				; ACC is averaged humi index

display_HUMI:
	mov	DPTR, #table_HUMI
	movc	A, @A+DPTR			; get humi value from table
	mov	R2, A
	swap	A
	anl	A, #0x0F			; extract first digit
	mov	DPTR, #table7seg		; initialize 7-seg table pointer
	movc	A, @A+DPTR			; get code of dig1
	mov	P1, A
	nop
	nop
	nop
	setb	P1.0				; latch in the first digit
	nop
	nop
	nop
	clr	P1.0
	
	mov	A, R2
	anl	A, #0x0F			; extract second digit
	mov	DPTR, #table7seg		; initialize 7-seg table pointer
	movc	A, @A+DPTR			; get code of dig2
	mov	P1, A
	nop
	nop
	nop
	setb	P0.6				; latch in the second digit
	nop
	nop
	nop
	clr	P0.6

	clr	P1.5				; display units (H)
	clr	P1.6
	ret

;-----------------------------------------------------------------------
LPM:    
	mov	PMU0CF, #(SLEEP OR RSTWK OR RTCAWK) ; wakeup sources
	nop   				; device is now awake
   	nop
	nop
	nop
  
	mov	PMU0CF_Snapshot, PMU0CF	; capture the wake-up source
   	mov 	PMU0CF, #CLEAR		; clear all wake-up source flags

	mov	RTC0ADR, #(0x90 OR RTC0CN); capture RTC events that occured
	nop					; while PMU0CF was being cleared
	nop
	nop	
	mov	A, RTC0DAT			; RTC0CN_snapshot	
	anl	A, #ALRM
	orl	A, PMU0CF_Snapshot	; add it to the old flags
	mov	PMU0CF_Snapshot, A
   
	mov	A, PMU0CF_Snapshot	; reset pin Wakeup ?
	anl	A, #RSTWK
	jnz	debug_delay1		
	ret					; NO - exit

debug_delay1:
	mov	A, #0x5			; YES - make a 20 usec delay		
	dec	A				; 1 cycle
	nop					; 1 cycle
	jnz	$-2				; 2 cycles    
	ret      

;-----------------------------------------------------------------------
wait4CS0: 
	anl	FLSCL,  #NOT(BYPASS)	; clear the one-shot bypass bit
	mov	PMU0FL, #CS0WK		; enable wake-up from CS0 module
	mov	PMU0CF, #(SUSPEND OR RSTWK) 	; wakeup sources
	nop   				; device is now awake
   	nop
	nop
	nop
  
	orl	FLSCL, #BYPASS		; set the one-shot bypass bit
	mov	PMU0CF_Snapshot, PMU0CF	; capture the wake-up source
   	mov 	PMU0CF, #CLEAR		; clear all wake-up source flags
	mov	PMU0FL, #0x00		
   
	mov	A, PMU0CF_Snapshot	; reset pin Wakeup ?
	anl	A, #RSTWK
	jnz	debug_delay2		
	ret					; NO - exit

debug_delay2:
	mov	A, #0x5			; YES - make a 20 usec delay		
	dec	A				; 1 cycle
	nop					; 1 cycle
	jnz	$-2				; 2 cycles    
	ret      

;========================================================================
table7seg:					; 7-seg LCD table
	DB	0x00 + 64			; code for 0
	DB	0x10 + 64			; code for 1
	DB	0x04 + 64			; code for 2
	DB	0x14 + 64			; code for 3
	DB	0x02 + 64			; code for 4
	DB	0x12 + 64			; code for 5
	DB	0x06 + 64			; code for 6
	DB	0x16 + 64			; code for 7
	DB	0x08 + 64			; code for 8
	DB	0x18 + 64			; code for 9
	DB	0x1E + 64			; blank	

table_HUMI:
	DB 	0xA0, 0xA0, 0xA1, 0xA1, 0xA1, 0xA2, 0xA2, 0xA3
	DB 	0xA3, 0xA4, 0xA4, 0xA5, 0xA5, 0xA5, 0xA6, 0xA6
	DB 	0xA7, 0xA7, 0xA8, 0xA8, 0xA9, 0xA9, 0xA9, 0x10
	DB 	0x10, 0x11, 0x11, 0x12, 0x12, 0x13, 0x13, 0x13
	DB 	0x14, 0x14, 0x15, 0x15, 0x16, 0x16, 0x16, 0x17
	DB 	0x17, 0x18, 0x18, 0x19, 0x19, 0x20, 0x20, 0x20
	DB 	0x21, 0x21, 0x22, 0x22, 0x23, 0x23, 0x24, 0x24
	DB 	0x24, 0x25, 0x25, 0x26, 0x26, 0x27, 0x27, 0x28
	DB 	0x28, 0x28, 0x29, 0x29, 0x30, 0x30, 0x31, 0x31
	DB 	0x32, 0x32, 0x32, 0x33, 0x33, 0x34, 0x34, 0x35
	DB 	0x35, 0x36, 0x36, 0x36, 0x37, 0x37, 0x38, 0x38
	DB 	0x39, 0x39, 0x40, 0x40, 0x40, 0x41, 0x41, 0x42
	DB 	0x42, 0x43, 0x43, 0x44, 0x44, 0x44, 0x45, 0x45
	DB 	0x46, 0x46, 0x47, 0x47, 0x48, 0x48, 0x48, 0x49
	DB 	0x49, 0x50, 0x50, 0x51, 0x51, 0x52, 0x52, 0x52
	DB 	0x53, 0x53, 0x54, 0x54, 0x55, 0x55, 0x56, 0x56
	DB 	0x56, 0x57, 0x57, 0x58, 0x58, 0x59, 0x59, 0x60
	DB 	0x60, 0x60, 0x61, 0x61, 0x62, 0x62, 0x63, 0x63
	DB 	0x64, 0x64, 0x64, 0x65, 0x65, 0x66, 0x66, 0x67
	DB 	0x67, 0x68, 0x68, 0x68, 0x69, 0x69, 0x70, 0x70
	DB 	0x71, 0x71, 0x72, 0x72, 0x72, 0x73, 0x73, 0x74
	DB 	0x74, 0x75, 0x75, 0x76, 0x76, 0x76, 0x77, 0x77
	DB 	0x78, 0x78, 0x79, 0x79, 0x80, 0x80, 0x80, 0x81
	DB 	0x81, 0x82, 0x82, 0x83, 0x83, 0x84, 0x84, 0x84
	DB 	0x85, 0x85, 0x86, 0x86, 0x87, 0x87, 0x88, 0x88
	DB 	0x88, 0x89, 0x89, 0x90, 0x90, 0x91, 0x91, 0x92
	DB 	0x92, 0x92, 0x93, 0x93, 0x94, 0x94, 0x95, 0x95
	DB 	0x96, 0x96, 0x96, 0x97, 0x97, 0x98, 0x98, 0x99
	DB 	0x99

END