;  ------ Processor: ATMEL AT89C2051 PC24 ------
;  ------ Code is timed for 10 MHz clock  ------

#INCLUDE "LIBREG.ASM"	;8051 SFR set

;  ------ Constantes ------

STACK	.EQU 056H		;stack location
;SYS	.EQU 01EH		;RC5 system
SYS	.EQU 0H		;RC5 system
VMIN	.EQU 100		;/10 V min limit
RTCVL	.EQU 0E6H		;20mS timer load value
RTCVH	.EQU 0BEH
V1S	.EQU 50		;program timer RTPCS value 1S/20mS=50
INDLTMV	.EQU 4		;x1S indication timer value
CYCSTMV	.EQU 25		;x20mS cycle timer
CNTSTMV	.EQU 50		;x20mS control timer
SNDSTMV	.EQU 10		;x20mS sound timer
ALSTMV	.EQU 5		;x20mS alarm sound timer

;  ------ Ports ------

SER	.EQU INT0		;RC-5 Line

THERM1	.EQU P1.4		;1-Wire thermometer 1
THERM2	.EQU P1.3		;1-Wire thermometer 2
THERM3	.EQU P1.2		;1-Wire thermometer 3
THERM4	.EQU T0		;1-Wire thermometer 4

DATA	.EQU RXD		;Serial Port Data
CLK	.EQU TXD		;Serial Port Clock
CS1	.EQU P1.7		;LCD-Driver 1 CS Line
CS2	.EQU P1.6		;LCD-Driver 2 CS Line
RST	.EQU INT1		;Real Time Clock RST Line

COMP	.EQU P3.6		;Comparator Out
RC	.EQU P1.5		;RC Network

SND	.EQU T1		;Sound Beeper Line

;  ------ Variables ------

;  Bit addressing memory

RTPC	.EQU 020H		;Real time program counter
T040M	.EQU M_20H.0	;40mS  period bit
T080M	.EQU M_20H.1	;80mS  period bit
T160M	.EQU M_20H.2	;160mS period bit
T320M	.EQU M_20H.3	;320mS period bit
T640M	.EQU M_20H.4	;640mS period bit
T1S28 	.EQU M_20H.5	;1.28S period bit
T2S56	.EQU M_20H.6	;2.56S period bit
T5S12	.EQU M_20H.7	;5.12S period bit

RTPCS	.EQU 021H		;Real time program counter (1S part)

DPS	.EQU 022H		;decimal points
DP1	.EQU M_22H.0	;decimal point 1
DP2	.EQU M_22H.1	;decimal point 2
DP3	.EQU M_22H.2	;decimal point 3
DP4	.EQU M_22H.3	;decimal point 4
DP5	.EQU M_22H.4	;decimal point 5
DP6	.EQU M_22H.5	;decimal point 6
DP7	.EQU M_22H.6	;decimal point 7
DP8	.EQU M_22H.7	;decimal point 8

CNT1	.EQU 023H		;control byte for LCD driver 1
SEG1	.EQU M_23H.0	;segment 1
SEG2	.EQU M_23H.1	;segment 2
SEG3	.EQU M_23H.2	;segment 3
SEG4	.EQU M_23H.3	;segment 4

CNT2	.EQU 024H		;control byte for LCD driver 2
SEG5	.EQU M_24H.0	;segment 5
SEG6	.EQU M_24H.1	;segment 6
SEG7	.EQU M_24H.2	;segment 7
SEG8	.EQU M_24H.3	;segment 8

MINUS	.EQU M_25H.0	;minus temperature
SEC	.EQU M_25H.1	;second bit
BIT_LK	.EQU M_25H.2	;bit LOCK
EDBEG	.EQU M_25H.3	;begin edit flag
TOV	.EQU M_25H.4	;T overflow flag
ALENB	.EQU M_25H.5	;alarm enable flag
ALS	.EQU M_25H.6	;alarm sound flag
VCLK	.EQU M_25H.7	;voltmeter clock

ED_FLAGS	.EQU 026H
ED_TM	.EQU M_26H.0	;timer edit flag
ED_AL	.EQU M_26H.1	;alarm edit flag
ED_CL	.EQU M_26H.2	;clock edit flag

VMF	.EQU M_27H.0	;voltmeter min flag

;  Internal data memory

DIG1	.EQU 030H
DIG2	.EQU 031H
DIG3	.EQU 032H
DIG4	.EQU 033H
DIG5	.EQU 034H
DIG6	.EQU 035H
DIG7	.EQU 036H
DIG8	.EQU 037H

CODE	.EQU 038H
INDPH	.EQU 039H		;indication phase (0-T1,1-T2,2-T3,3-TM,4-VOLT)
POS	.EQU 03AH

CL1	.EQU 03BH
CL2	.EQU 03CH
CL3	.EQU 03DH
CL4	.EQU 03EH

TM1	.EQU 03FH
TM2	.EQU 040H
TM3	.EQU 041H
TM4	.EQU 042H

AL1	.EQU 043H
AL2	.EQU 044H
AL3	.EQU 045H
AL4	.EQU 046H

VL1	.EQU 047H
VL2	.EQU 048H
VL3	.EQU 049H

CTMV	.EQU 04AH
VCNT	.EQU 04BH
VH	.EQU 04CH
VL	.EQU 04DH
HR	.EQU 04EH

INDLTM	.EQU 04FH
CYCSTM	.EQU 050H
CNTSTM	.EQU 051H
SNDSTM	.EQU 052H

;  ------ Vectors Area ------

	.ORG 0000H	;reset vector
	LJMP INIT
	.ORG 0003H	;INT0 vector
	LJMP RC5
INIT:	MOV SP,#STACK
	SJMP INIT1
	.ORG 000BH	;INT TIMER 0 vector
	LJMP RTC

;  ------ Main Program ------

INIT1:	CLR RST
	CLR CLK		;clock line init

	CLR A
	MOV VH,A
	MOV VL,A
	MOV R37,A
	MOV CODE,A
	MOV VCNT,A
	MOV INDPH,A	;set indication phase 0
	MOV INDLTM,A	;indication timer clear
	MOV CYCSTM,A	;cycle timer clear
	MOV CNTSTM,A	;control timer clear
	MOV ED_FLAGS,A
	CPL A
	MOV CTMV,A
	MOV HR,A
	MOV R3,#99	;set T limit

	CLR BIT_LK	;lock off
	SETB ALENB	;alarm enable
	CLR ALS		;clear alarm sound flag

	LCALL GET_VOLT
	CLR VMF		;clear voltmeter min flag

;  LCD clear

	MOV A,#CH_BL
	MOV DIG1,A
	MOV DIG2,A
	MOV DIG3,A
	MOV DIG4,A
	MOV CNT1,#0F0H
	MOV DIG5,A
	MOV DIG6,A
	MOV DIG7,A
	MOV DIG8,A
	MOV CNT2,#0H
	MOV DPS,#0H
	LCALL LCD

	SETB DP3

	LCALL GET_CL

;  Get alarm values from RTC

	MOV A,#11000001B
	LCALL SHRD
	MOV AL1,A
	MOV A,#11000011B
	LCALL SHRD
	MOV AL2,A
	MOV A,#11000101B
	LCALL SHRD
	MOV AL3,A
	MOV A,#11000111B
	LCALL SHRD
	MOV AL4,A

;  Get timer values from RTC

	MOV A,#11001001B
	LCALL SHRD
	MOV TM1,A
	MOV A,#11001011B
	LCALL SHRD
	MOV TM2,A
	MOV A,#11001101B
	LCALL SHRD
	MOV TM3,A
	MOV A,#11001111B
	LCALL SHRD
	MOV TM4,A

	LCALL START_T1
	LCALL START_T2
	LCALL START_T3

	MOV TMOD,#11H    	;timer 0 and timer 1 init
	CLR TR0          	;timer 0 stop
	CLR TR1          	;timer 1 stop
	MOV TL0,#RTCVL   	;timer 0 load
	MOV TH0,#RTCVH
	MOV RTPC,#0H     	;program counter load
	MOV RTPCS,#V1S   	;1S value load

	SETB PX0          	;high   INT0 priority
	SETB IT0         	;fall   INT0 activating
	SETB EX0		;enable INT0
	CLR PT0          	;timer 0 int low priority
	SETB ET0         	;timer 0 int enable
	SETB TR0         	;timer 0 start
	SETB EA          	;interrupts enable

MAIN:     CLR EX0		;RC int disable
	MOV A,R37		;command code load
	ANL R37,#0C0H	;clear com. bits
	SETB EX0		;RC int enable
	MOV R0,A
	ANL A,#3FH	;control bits clear
	JNZ PRESS
	SJMP MAIN1	;no press or unused code

PRESS:	MOV A,R0
	CJNE A,CODE,DIF	;jump if new command
	SJMP MAIN1

DIF:	MOV CODE,A	;new press, store code
	ANL A,#3FH	;control bits clear
	MOV R7,A
	LCALL SOUND

;Control Functions Analysis and Processing

	CJNE R7,#COD_EN,LB2
	ACALL ENTER		;enter function
	SJMP LB1
LB2:	JNC LB1
	ACALL NUM			;0..9 functions
LB1:	CJNE R7,#COD_ES,$+5H
	ACALL ESCAPE
	CJNE R7,#COD_BK,$+5H
	ACALL BACK
	CJNE R7,#COD_LK,$+5H
	ACALL LOCK
	CJNE R7,#COD_LS,$+5H
	ACALL LIST
	CJNE R7,#COD_AL,$+5H
	ACALL ALARM
	CJNE R7,#COD_TM,$+5H
	ACALL TIMER
	CJNE R7,#COD_TC,$+5H
	ACALL TCLEAR
	CJNE R7,#COD_AD,$+5H
	ACALL ALDS
	CJNE R7,#COD_CL,$+5H
	ACALL CLOCK

MAIN1:    JNB VCLK,SKIPV
	CLR VCLK
	MOV A,VCNT
	JZ SKIPV

;  Analog to digital conversion

	CLR A
	CLR RC
	MOV R0,#10
	DJNZ R0,$
V_UP:	INC A
	JZ OUTOFR
	JB COMP,V_UP
OUTOFR:	DEC A
	SETB RC
	ADD A,VL
	MOV VL,A
	MOV A,VH
	ADDC A,#0H
	MOV VH,A
	DEC VCNT

SKIPV:	MOV A,CYCSTM
	JNZ MAIN3
	MOV CYCSTM,#CYCSTMV		;cycle timer load
	MOV A,INDLTM
	JNZ SPHASE
	MOV INDLTM,#INDLTMV		;indication timer load
	MOV A,INDPH
	JB BIT_LK,PHM5
	INC A
	CJNE A,#5H,PHM5
	CLR A
PHM5:	MOV INDPH,A
SPHASE:	CLR DP5
	JB ED_TM,IDTM
	MOV A,ED_FLAGS
	JNZ MAIN2
	MOV A,INDPH
	JZ IDT1
	DEC A
	JZ IDT2
	DEC A
	JZ IDT3
	DEC A
	JZ IDCL

IDVL:     SETB DP5
	MOV A,#CH_BL
	MOV DIG1,A
	MOV DIG2,#CH_U
	MOV DIG4,VL1
	MOV DIG5,VL2
	MOV DIG6,VL3
	MOV DIG7,A
	MOV DIG8,A
	SJMP MAIN2

IDCL:	CPL SEC
	MOV DIG1,#CH_C
	MOV DIG2,#CH_L
	MOV DIG4,CL1
	MOV DIG5,CL2
	MOV DIG6,#CH_MN
	JB SEC,INDCL1
	MOV DIG6,#CH_BL
INDCL1:	MOV DIG7,CL3
	MOV DIG8,CL4
	SJMP MAIN2

IDT3:	ACALL INDT3
	SJMP MAIN2
IDT2:	ACALL INDT2
	SJMP MAIN2
IDT1:	ACALL INDT1
	SJMP MAIN2
IDTM:	ACALL INDTM

MAIN2:    LCALL LCD

MAIN3:	MOV A,CNTSTM
	JNZ MAIN4
	MOV CNTSTM,#CNTSTMV

	CLR TOV
	MOV R3,#55	;set T1 limit 55
	LCALL READ_T1
	MOV R3,#99	;set T2,T3 limits 99
	LCALL READ_T2
	LCALL READ_T3
	LCALL GET_VOLT
	LCALL GET_CL	;get time from clock
	LCALL TINC	;timer INC and alarm check

MAIN4:    JNB ALS,MAIN5
	MOV A,SNDSTM
	JNZ MAIN5
	MOV SNDSTM,#ALSTMV
	SJMP DOSND

MAIN5:    MOV C,TOV
	ORL C,VMF
	JNC MAIN6
	MOV A,SNDSTM
	JNZ MAIN6
	MOV SNDSTM,#SNDSTMV

DOSND:	CLR A
	LCALL SOUND

MAIN6:	LJMP MAIN

;  ------ Subroutines Area ------
;  ------ Keys Functions ------

;  Numeric keys

NUM:      MOV C,ED_CL
	ORL C,ED_AL
	JNC NUM1
	MOV R00,R7
	DEC R0		;perform digit value
	MOV A,POS		;position check
	DEC A
	JZ ND1
	DEC A
	JZ ND2
	DEC A
	JZ ND3
	DEC A
	JZ ND4
	JB EDBEG,NUM1
	SETB EDBEG
	MOV DIG6,#CH_BL
	MOV A,#CH_MN
	MOV DIG4,A
	MOV DIG5,A
	MOV DIG7,A
	MOV DIG8,A
	MOV POS,#1H

ND1:      MOV A,R0		;POS=1
	ADD A,#0FDH
	JC NUM1		;jump if R0>2
	MOV DIG4,R0
	SJMP NUME

ND2:      MOV A,DIG4	;POS=2
	XRL A,#2H
	JNZ ND21		;jump if DIG4<2
	MOV A,R0
	ADD A,#0FCH
	JC NUM1		;jump if DIG4=2 and R0>3
ND21:	MOV DIG5,R0
	SJMP NUME

ND3:      MOV A,R0		;POS=3
	ADD A,#0FAH
	JC NUM1		;jump if R0>5
	MOV DIG7,R0
	SJMP NUME

ND4:	MOV DIG8,R0	;POS=4

NUME:	INC POS		;next position
NUM1:	MOV CYCSTM,#0H	;display changes

	RET

;  Clock set function

CLOCK:    MOV A,ED_FLAGS
	JNZ CLRET
	SETB ED_CL	;set clock edit flag
	CLR EDBEG
	MOV DIG1,#CH_P	;perform DIGs
	MOV DIG2,#CH_C
	MOV DIG3,#CH_BL
	MOV DIG4,CL1
	MOV DIG5,CL2
	MOV DIG6,#CH_MN
	MOV DIG7,CL3
	MOV DIG8,CL4
	MOV POS,#5H
	MOV CYCSTM,#0H	;display changes
	LCALL SET_CL
CLRET:	RET

;  Alarm time set function

ALARM:    MOV A,ED_FLAGS
	JNZ ALRET
	SETB ED_AL
	CLR EDBEG
	MOV DIG1,#CH_P
	MOV DIG2,#CH_A
	MOV DIG3,#CH_BL
	MOV DIG4,AL1
	MOV DIG5,AL2
	MOV DIG6,#CH_MN
	MOV DIG7,AL3
	MOV DIG8,AL4
	MOV POS,#5H
	MOV CYCSTM,#0H
ALRET:	RET

;  Backspace function

BACK:	MOV C,ED_CL
	ORL C,ED_AL
	JNC BRET
	SETB EDBEG
	MOV DIG6,#CH_BL
	MOV A,POS
	DEC A
	JZ BRET		;jump if POS=1
	DEC POS
	DEC A
	JNZ BPN2
	MOV DIG4,#CH_MN
BPN2:	DEC A
	JNZ BPN3
	MOV DIG5,#CH_MN
BPN3:	DEC A
	JNZ BPN4
	MOV DIG7,#CH_MN
BPN4:	MOV DIG8,#CH_MN
	MOV CYCSTM,#0H	;display changes
BRET:	RET

;  Enter function

ENTER:	JBC ED_TM,ENTM
	MOV A,POS
	CJNE A,#5H,ENRET
	JBC ED_CL,ENCL
	JBC ED_AL,ENAL
ENRET:	RET

ENCL:	MOV CL1,DIG4
	MOV CL2,DIG5
	MOV CL3,DIG7
	MOV CL4,DIG8
	LCALL SET_CL	;set clock
	MOV CYCSTM,#0H
	MOV INDLTM,#0H
	RET

ENAL:	MOV AL1,DIG4
	MOV AL2,DIG5
	MOV AL3,DIG7
	MOV AL4,DIG8

SET_AL:	MOV R0,AL1	;save alarm values in RTC
	MOV A,#11000000B
	LCALL SHWR
	MOV R0,AL2
	MOV A,#11000010B
	LCALL SHWR
	MOV R0,AL3
	MOV A,#11000100B
	LCALL SHWR
	MOV R0,AL4
	MOV A,#11000110B
	LCALL SHWR

	SETB ALENB
	SETB DP3

ENTM:	MOV CYCSTM,#0H
	RET

;  Escape function

ESCAPE:   JBC ED_TM,ES1
	JBC ED_AL,ES1
	JBC ED_CL,ES1
	RET

ES1:	MOV CYCSTM,#0H
	RET

;  Timer function

TIMER:    SETB ED_TM
	MOV CYCSTM,#0H
	RET

;  Timer clear function

TCLEAR:   JNB ED_TM,TCRET

SET_TM:   MOV R0,CL1	;save timer values in RTC
	MOV TM1,R0
	MOV A,#11001000B
	LCALL SHWR
	MOV R0,CL2
	MOV TM2,R0
	MOV A,#11001010B
	LCALL SHWR
	MOV R0,CL3
	MOV TM3,R0
	MOV A,#11001100B
	LCALL SHWR
	MOV R0,CL4
	MOV TM4,R0
	MOV A,#11001110B
	LCALL SHWR

	MOV CYCSTM,#0H
TCRET:	RET

;  Alarm disable function

ALDS:	CLR ALENB
	CLR ALS
	CLR DP3
	RET

;  Lock function

LOCK:	CPL BIT_LK
	MOV CYCSTM,#0H
	RET

;  List function

LIST:     CLR BIT_LK
	MOV CYCSTM,#0H
	MOV INDLTM,#0H
	RET

;  ------ End Of Keys Functions ------

;  T1 indication

INDT1:    ACALL INDT
	MOV DIG2,#1
	LCALL READ_T1
	ACALL INDTA
	LCALL ST_T1	;start T1 conversion
	RET

INDT2:    ACALL INDT
	MOV DIG2,#2
	LCALL READ_T2
	ACALL INDTA
	LCALL ST_T2	;start T2 conversion
	RET

INDT3:    ACALL INDT
	MOV DIG2,#3
	LCALL READ_T3
	ACALL INDTA
	LCALL ST_T3	;start T3 conversion
	RET

INDTA:	JNC FAIL
	JNB MINUS,TPL1
	MOV DIG4,#CH_MN
TPL1:	MOV DIG5,R2
	MOV DIG6,R1
	RET
FAIL:	MOV DIG4,#CH_BL
	MOV DIG5,#CH_F
	MOV DIG6,#CH_A
	MOV DIG7,#CH_I
	MOV DIG8,#CH_L
	RET

INDT:	MOV DIG1,#CH_T
	MOV DIG4,#CH_BL
	MOV DIG7,#CH_GR
	MOV DIG8,#CH_C
	RET

INDTM:	MOV DIG1,#CH_BL
	MOV DIG2,#CH_C
	MOV DIG6,#CH_MN

	CLR C
	MOV A,CL4
	SUBB A,TM4
	JNC IDMT1
	SUBB A,#5H
	ANL A,#0FH
	SETB C
IDMT1:	MOV DIG8,A
	MOV A,CL3
	SUBB A,TM3
	JNC IDMT2
	SUBB A,#9H
	ANL A,#0FH
	SETB C
IDMT2:	MOV DIG7,A
	MOV A,CL2
	SUBB A,TM2
	JNC IDMT3
	SUBB A,#5H
	ANL A,#0FH
	SETB C
IDMT3:	MOV R0,A
	MOV A,CL1
	SUBB A,TM1
	JNC IDMT4
	SUBB A,#0CH
	ANL A,#0FH
	SWAP A
	ORL A,R0
	ADD A,#094H
	DA A
	MOV R0,A
	ANL A,#0FH
	XCH A,R0
	SWAP A
	ANL A,#0FH
IDMT4:    MOV DIG5,R0
	MOV DIG4,A

	RET

;  ------ 1-Wire thermometers support ------

;  Start conversion in 1-wire thermometer DS1821.
;  1-wire port line called as THERM1.
;  Calls TRESET1, TOUCHBY1

START_T1:	LCALL TRESET1	;Issue reset pulse.
	JNC ACSRET1         ;Fail if no part on bus.
	MOV A,#0CH	;Write status command.
	LCALL TOUCHBY1	;Send command byte.
	MOV A,#00H	;Continuously conversion.
	LCALL TOUCHBY1	;Send command byte.
ST_T1:	LCALL TRESET1	;Issue reset pulse.
	JNC ACSRET1         ;Fail if no part on bus.
	MOV A,#0EEH	;Start convert command.
	LCALL TOUCHBY1	;Send command byte.
	SETB C
ACSRET1:	RET

;  This procedure transmits the Reset signal to the 1-Wire
;  device and watches for a presence pulse. On return,
;  the Carry bit is set if a presence pulse was detected,
;  otherwise the Carry is cleared. The code is timed for
;  an 10 MHz crystal.

TRESET1:	MOV  A,#4        	;Load outer loop variable.
	CLR  THERM1      	;Start the reset pulse.
	MOV  B,#200      	;  2.  Set time interval.
	DJNZ B,$         	;400.  Wait with Data low.
	SETB THERM1       	;  1.  Release Data line.
	MOV  B,#6        	;  2.  Set time interval.
	CLR  C           	;  1.  Clear presence flag.
WAITL1:	JB   THERM1,WH1    	;Exit loop if line high.
	DJNZ B,WAITL1   	;Hang around for 3360
	DJNZ ACC,WAITL1 	;us if line is low.
	SJMP SHORT1       	;Line could not go high.
WH1:	MOV  B,#101      	;Delay for presence detect.
HL1:	ORL  C,/THERM1    	;202.  Catch presence pulse.
	DJNZ B,HL1        	;202.  Wait with Data high.
SHORT1:	RET              	;Return.

;  This procedure sends the byte in the accumulator
;  to the 1-Wire device, and returns a byte from the
;  1-Wire device in the accumulator. Note that the NOPs
;  in the following code are intended to give the
;  optimum performance when using a 10 MHz crystal.

TOUCHBY1:	PUSH B           	;Save the B register.
	MOV  B,#8        	;Setup for 8 bits.
B_LOOP1:	RRC  A           	;1. Get bit in carry.
	LCALL TOUCHB1   	;2. Send bit.
	DJNZ B,B_LOOP1  	;2. Get next bit.
	RRC  A           	;   Get final bit in ACC.
	POP  B           	;Restore B register.
	RET              	;Return to caller.

TOUCHB1:	CLR THERM1       	; 1.  Start the time slot.
	INC DPTR            ; 2.
	INC DPTR            ; 2.
	MOV THERM1,C    	; 2.  Send out the data bit.
	INC DPTR            ; 2.
	INC DPTR            ; 2.
	INC DPTR            ; 2.
	MOV  C,THERM1     	; 1.  Sample input data bit.
	PUSH B           	; 2.  Save B register.
	MOV  B,#16      	; 2.  Delay until the end
	DJNZ B,$         	;32.    of the time slot.
	POP  B           	;Restore B register.
	SETB THERM1       	;Terminate time slot.
	RET              	;Return to caller.

;  Read temperature from 1-wire thermometer DS1821.
;  Returns C=1 in case of valid code, else C=0.
;  Returns R1=DIG1, R2=DIG2, MINUS of themperature (-55..99).
;  1-wire port line called as THERM1.
;  Calls TRESET1, TOUCHBY1

READ_T1:	LCALL TRESET1	;Issue reset pulse.
	JNC RT1		;Fail if no part on bus.
	MOV A,#0AAH	;Read temperature command.
	LCALL TOUCHBY1	;Send command byte.
	MOV A,#0FFH	;perform read
	LCALL TOUCHBY1	;Read temperature.
	LCALL TCONV	;HEX to BCD conversion
	SETB C
RT1:	RET

;  Start conversion in 1-wire thermometer DS1821.
;  1-wire port line called as THERM2.
;  Calls TRESET2, TOUCHBY2

START_T2:	LCALL TRESET2	;Issue reset pulse.
	JNC ACSRET2         ;Fail if no part on bus.
	MOV A,#0CH	;Write status command.
	LCALL TOUCHBY2	;Send command byte.
	MOV A,#00H	;Continuously conversion.
	LCALL TOUCHBY2	;Send command byte.
ST_T2:	LCALL TRESET2	;Issue reset pulse.
	JNC ACSRET2         ;Fail if no part on bus.
	MOV A,#0EEH	;Start convert command.
	LCALL TOUCHBY2	;Send command byte.
	SETB C
ACSRET2:	RET

;  This procedure transmits the Reset signal to the 1-Wire
;  device and watches for a presence pulse. On return,
;  the Carry bit is set if a presence pulse was detected,
;  otherwise the Carry is cleared. The code is timed for
;  an 10 MHz crystal.

TRESET2:	MOV  A,#4        	;Load outer loop variable.
	CLR  THERM2      	;Start the reset pulse.
	MOV  B,#200      	;  2.  Set time interval.
	DJNZ B,$         	;400.  Wait with Data low.
	SETB THERM2       	;  1.  Release Data line.
	MOV  B,#6        	;  2.  Set time interval.
	CLR  C           	;  1.  Clear presence flag.
WAITL2:	JB   THERM2,WH2    	;Exit loop if line high.
	DJNZ B,WAITL2   	;Hang around for 3360
	DJNZ ACC,WAITL2 	;us if line is low.
	SJMP SHORT2       	;Line could not go high.
WH2:	MOV  B,#101      	;Delay for presence detect.
HL2:	ORL  C,/THERM2    	;202.  Catch presence pulse.
	DJNZ B,HL2        	;202.  Wait with Data high.
SHORT2:	RET              	;Return.

;  This procedure sends the byte in the accumulator
;  to the 1-Wire device, and returns a byte from the
;  1-Wire device in the accumulator. Note that the NOPs
;  in the following code are intended to give the
;  optimum performance when using a 10 MHz crystal.

TOUCHBY2:	PUSH B           	;Save the B register.
	MOV  B,#8        	;Setup for 8 bits.
B_LOOP2:	RRC  A           	;1. Get bit in carry.
	LCALL TOUCHB2   	;2. Send bit.
	DJNZ B,B_LOOP2  	;2. Get next bit.
	RRC  A           	;   Get final bit in ACC.
	POP  B           	;Restore B register.
	RET              	;Return to caller.

TOUCHB2:	CLR THERM2       	; 1.  Start the time slot.
	INC DPTR            ; 2.
	INC DPTR            ; 2.
	MOV THERM2,C    	; 2.  Send out the data bit.
	INC DPTR            ; 2.
	INC DPTR            ; 2.
	INC DPTR            ; 2.
	MOV  C,THERM2     	; 1.  Sample input data bit.
	PUSH B           	; 2.  Save B register.
	MOV  B,#16      	; 2.  Delay until the end
	DJNZ B,$         	;32.    of the time slot.
	POP  B           	;Restore B register.
	SETB THERM2       	;Terminate time slot.
	RET              	;Return to caller.

;  Read temperature from 1-wire thermometer DS1821.
;  Returns C=1 in case of valid code, else C=0.
;  Returns R1=DIG1, R2=DIG2, MINUS of themperature (-55..99).
;  1-wire port line called as THERM2.
;  Calls TRESET2, TOUCHBY2

READ_T2:	LCALL TRESET2	;Issue reset pulse.
	JNC RT2		;Fail if no part on bus.
	MOV A,#0AAH	;Read temperature command.
	LCALL TOUCHBY2	;Send command byte.
	MOV A,#0FFH	;perform read
	LCALL TOUCHBY2	;Read temperature.
	LCALL TCONV	;HEX to BCD conversion
	SETB C
RT2:	RET

;  Start conversion in 1-wire thermometer DS1821.
;  1-wire port line called as THERM3.
;  Calls TRESET3, TOUCHBY3

START_T3:	LCALL TRESET3	;Issue reset pulse.
	JNC ACSRET3         ;Fail if no part on bus.
	MOV A,#0CH	;Write status command.
	LCALL TOUCHBY3	;Send command byte.
	MOV A,#00H	;Continuously conversion.
	LCALL TOUCHBY3	;Send command byte.
ST_T3:	LCALL TRESET3	;Issue reset pulse.
	JNC ACSRET3         ;Fail if no part on bus.
	MOV A,#0EEH	;Start convert command.
	LCALL TOUCHBY3	;Send command byte.
	SETB C
ACSRET3:	RET

;  This procedure transmits the Reset signal to the 1-Wire
;  device and watches for a presence pulse. On return,
;  the Carry bit is set if a presence pulse was detected,
;  otherwise the Carry is cleared. The code is timed for
;  an 10 MHz crystal.

TRESET3:	MOV  A,#4        	;Load outer loop variable.
	CLR  THERM3      	;Start the reset pulse.
	MOV  B,#200      	;  2.  Set time interval.
	DJNZ B,$         	;400.  Wait with Data low.
	SETB THERM3       	;  1.  Release Data line.
	MOV  B,#6        	;  2.  Set time interval.
	CLR  C           	;  1.  Clear presence flag.
WAITL3:	JB   THERM3,WH3    	;Exit loop if line high.
	DJNZ B,WAITL3   	;Hang around for 3360
	DJNZ ACC,WAITL3 	;us if line is low.
	SJMP SHORT3       	;Line could not go high.
WH3:	MOV  B,#101      	;Delay for presence detect.
HL3:	ORL  C,/THERM3    	;202.  Catch presence pulse.
	DJNZ B,HL3        	;202.  Wait with Data high.
SHORT3:	RET              	;Return.

;  This procedure sends the byte in the accumulator
;  to the 1-Wire device, and returns a byte from the
;  1-Wire device in the accumulator. Note that the NOPs
;  in the following code are intended to give the
;  optimum performance when using a 10 MHz crystal.

TOUCHBY3:	PUSH B           	;Save the B register.
	MOV  B,#8        	;Setup for 8 bits.
B_LOOP3:	RRC  A           	;1. Get bit in carry.
	LCALL TOUCHB3   	;2. Send bit.
	DJNZ B,B_LOOP3  	;2. Get next bit.
	RRC  A           	;   Get final bit in ACC.
	POP  B           	;Restore B register.
	RET              	;Return to caller.

TOUCHB3:	CLR THERM3       	; 1.  Start the time slot.
	INC DPTR            ; 2.
	INC DPTR            ; 2.
	MOV THERM3,C    	; 2.  Send out the data bit.
	INC DPTR            ; 2.
	INC DPTR            ; 2.
	INC DPTR            ; 2.
	MOV  C,THERM3     	; 1.  Sample input data bit.
	PUSH B           	; 2.  Save B register.
	MOV  B,#16      	; 2.  Delay until the end
	DJNZ B,$         	;32.    of the time slot.
	POP  B           	;Restore B register.
	SETB THERM3       	;Terminate time slot.
	RET              	;Return to caller.

;  Read temperature from 1-wire thermometer DS1821.
;  Returns C=1 in case of valid code, else C=0.
;  Returns R1=DIG1, R2=DIG2, MINUS of themperature (-55..99).
;  1-wire port line called as THERM3.
;  Calls TRESET3, TOUCHBY3

READ_T3:	LCALL TRESET3	;Issue reset pulse.
	JNC RT3		;Fail if no part on bus.
	MOV A,#0AAH	;Read temperature command.
	LCALL TOUCHBY3	;Send command byte.
	MOV A,#0FFH	;perform read
	LCALL TOUCHBY3	;Read temperature.
	LCALL TCONV	;HEX to BCD conversion
	SETB C
RT3:	RET

;  Themperature HEX to BCD conversion
;  Input A=0..0C9H
;  Returns R1=DIG1, R2=DIG2, MINUS of themperature (-55..99).

TCONV:    JNB ACC.7,TPL
	SETB MINUS
	CPL A
	INC A
	MOV R2,A
	SJMP L99
TPL:      CLR MINUS
	MOV R2,A
	CLR C
	SUBB A,R3
	JC L99
	SETB TOV		;set T overflow flag
	MOV R02,R3	;if R2>R3 then R2=R3 (R3=99 OR 55)
L99:      MOV A,R2
	MOV B,#10		;HEX to BCD conversion
	DIV AB
	MOV R1,B
	MOV R2,A
	RET

;  ------ 3-Wire Clock support ------

SET_CL:   MOV A,#10001110B	;CONTROL
	MOV R0,#00000000B
	LCALL SHWR

	MOV A,#10010000B	;TRICKLE CHARGER
	MOV R0,#10101011B	;8K, 2 DIODES
	LCALL SHWR

	MOV A,CL1
	SWAP A
	ORL A,CL2
	MOV R0,A
	MOV A,#10000100B	;HR
	LCALL SHWR

	MOV A,CL3
	SWAP A
	ORL A,CL4
	MOV R0,A
	MOV A,#10000010B	;MIN
	LCALL SHWR

	MOV A,#10000000B	;SEC
	MOV R0,#00H
	LCALL SHWR

	RET

GET_CL:	MOV A,#10000101B	;HR
	LCALL SHRD
	MOV R0,A
	SWAP A
	ANL A,#0FH
	MOV CL1,A
	MOV A,R0
	ANL A,#0FH
	MOV CL2,A

	MOV A,#10000011B	;MIN
	LCALL SHRD
	MOV R0,A
	SWAP A
	ANL A,#0FH
	MOV CL3,A
	MOV A,R0
	ANL A,#0FH
	MOV CL4,A

	RET

;Data read into serial port
;Input: A = address, Out: A = data

SHRD:     SETB RST
	MOV R1,#8H	;bit counter load
SHRD1:	RRC A
	MOV DATA,C
	SETB CLK
	CLR CLK
	DJNZ R1,SHRD1

	MOV R1,#8H	;bit counter load
SHRD2:    MOV C,DATA
	RRC A
	SETB CLK
	CLR CLK
	DJNZ R1,SHRD2
	CLR RST
	RET

;Data write via serial port
;Input: A = address, R0 = data

SHWR:     SETB RST
	MOV R1,#8H	;bit counter load
SHWR1:	RRC A
	MOV DATA,C
	SETB CLK
	CLR CLK
	DJNZ R1,SHWR1

	MOV R1,#8H	;bit counter load
	MOV A,R0
SHWR2:    RRC A
	MOV DATA,C
	SETB CLK
	CLR CLK
	DJNZ R1,SHWR2
	CLR RST
	RET

;   Timer INC

TINC:	MOV A,CL4
	CJNE A,CTMV,DOTINC
	RET		;return if CTMV=CL4

DOTINC:	MOV CTMV,A

	MOV A,CL1
	SWAP A
	ORL A,CL2
	CJNE A,HR,DOBEEP
	SJMP GOON
DOBEEP:	MOV HR,A
	CLR A
	LCALL SOUND	;beep per HR

GOON:	SETB ALS
	JNB ALENB,NOAL

	MOV A,AL1
	CJNE A,CL1,NOAL
	MOV A,AL2
	CJNE A,CL2,NOAL
	MOV A,AL3
	CJNE A,CL3,NOAL
	MOV A,AL4
	CJNE A,CL4,NOAL

	CLR ALS

NOAL:     CPL ALS
	RET

;  Get volmeter value

GET_VOLT:	MOV A,VCNT
	JNZ GVR		;ret if voltmeter not ready
	MOV VCNT,#16
	CLR VCLK
	MOV A,VL
	SWAP A
	ANL A,#0FH
	MOV R0,A
	MOV A,VH
	SWAP A
	ANL A,#0F0H
	ORL A,R0
	CJNE A,#VMIN,GV1
GV1:	MOV VMF,C
	MOV B,#100
	DIV AB
	MOV VL1,A
	MOV A,B
	MOV B,#10
	DIV AB
	MOV VL2,A
	MOV VL3,B
	CLR A
	MOV VH,A
	MOV VL,A
GVR:	RET

;LCD driver load
;Input: DIG1..DIG8, CNT1, CNT2

LCD: 	MOV DIG3,#CH_BL
	JNB BIT_LK,NOLK
	MOV DIG3,#CH_L
NOLK:	MOV DPTR,#FONT
	CLR CS1
	CLR CS2
	MOV A,DIG1
	MOVC A,@A+DPTR
	LCALL SHIFT
	MOV A,DIG2
	MOVC A,@A+DPTR
	LCALL SHIFT
	MOV A,DIG3
	MOVC A,@A+DPTR
	MOV C,DP3
	MOV ACC.0,C
	LCALL SHIFT
	MOV A,DIG4
	MOVC A,@A+DPTR
	LCALL SHIFT
	MOV A,CNT1
	LCALL SHIFT
	SETB CS1
	SETB CS2
	NOP
	CLR CS2
	MOV A,DIG5
	MOVC A,@A+DPTR
	MOV C,DP5
	MOV ACC.0,C
	LCALL SHIFT
	MOV A,DIG6
	MOVC A,@A+DPTR
	LCALL SHIFT
	MOV A,DIG7
	MOVC A,@A+DPTR
	LCALL SHIFT
	MOV A,DIG8
	MOVC A,@A+DPTR
	LCALL SHIFT
	MOV A,CNT2
	LCALL SHIFT
	SETB CS2
	RET

;Data shift into serial port
;Input: A = data

SHIFT:	MOV R1,#8H	;bit counter load
SH1:	RRC A
	MOV DATA,C
	SETB CLK
	CLR CLK
	DJNZ R1,SH1
	RET

SOUND:	CLR EA           ;makes sound with freq. from A
	CPL A
	ANL A,#0FH
	RL A
	RL A
	ADD A,#060H
	MOV R1,#0AFH
SO1:	MOV R0,A
	DJNZ R0,$
	CPL SND
	DJNZ R1,SO1
	SETB SND
	SETB EA
	RET

;  ------ Interrupt Holders ------

;  TIMER 0 Interrupt
;  System clock 20mS

RTC:	PUSH PSW
	PUSH ACC
	CLR TR0          	;timer 0 stop
	MOV TH0,#RTCVH   	;timer 0 load for 20 mS
	MOV TL0,#RTCVL
	SETB TR0         	;timer start

	INC RTPC         	;Real Time Program Counter INC
	DJNZ RTPCS,RTC1
	MOV RTPCS,#V1S

;  1S program counters

	MOV A,INDLTM
	JZ RTC1
	DEC INDLTM

;  20mS program counters

RTC1:	MOV A,CYCSTM
	JZ RTC2
	DEC CYCSTM

RTC2:	MOV A,CNTSTM
	JZ RTC3
	DEC CNTSTM

RTC3:	MOV A,SNDSTM
	JZ RTC4
	DEC SNDSTM

RTC4:     SETB VCLK
	POP ACC
	POP PSW
	RETI

;  ------RC5 Program Decoder------
;  RC5 program decoder is interrupt holder.
;  Input - bit SER (interrupt line), low active level.
;  Out - byte R37 (register R7 in bank 3),
;                  D0-D5 - command bits
;                  D6 - control bit of local keyboard
;                 (D6 does not change)
;                  D7 - control bit RC
;  Uses register bank 3

RC5:	PUSH PSW		;RC5-code program decoding
	PUSH DPH
	PUSH DPL
	SETB RS0
	SETB RS1		;bank 3
	MOV R5,A

	MOV R6,#1H
	MOV R2,#2H
	MOV R3,#4H
WLOW:	JNB SER,WLOW
	MOV R0,#1AH
	MOV R1,#0F6H
SAMPLE:	MOV A,R6
	NOP
	JB ACC.1,THIGH
	JNB SER,TRANS
NOTRAN:	DJNZ R1,SAMPLE
NORC5: 	MOV A,R5
	POP DPL
	POP DPH
	POP PSW
	RETI

THIGH:	JNB SER,NOTRAN
TRANS:	XRL A,#2H
	MOV R6,A
	MOV A,R1
	ADD A,#46H
	JC NORC5
	MOV A,R1
	ADD A,#87H
	MOV A,R6
	JNC T2
	XRL A,#1H
	MOV R6,A
	MOV R1,#0F4H
	JB ACC.0,SAMPLE
STDATA:	CLR C
	CPL C
	JB ACC.1,DAT1
	CLR C
DAT1:	MOV A,@R0
	RLC A
	MOV @R0,A
	MOV R1,#0F3H
	JNC SAMPLE
	INC R0
	MOV A,R0
	CPL A
	MOV R1,#0F2H
	JB ACC.2,SAMPLE
WLW:	JNB SER,WLW
	MOV R0,#0FAH
TERM:	JNB SER,NORC5
	INC DPTR
	INC DPTR
	INC DPTR
	NOP
	DJNZ R0,TERM

	MOV A,R2		;system nom. and control bit in R2
	ANL A,#1FH
	CJNE A,#SYS,NORC5	;system number check

	MOV DPTR,#RCTAB	;table address load
	MOV A,R3		;command code load
	MOVC A,@A+DPTR	;recoding
	MOV R3,A		;new code store

	MOV A,R2		;system nom. and control bit in R2
	ANL A,#20H	;control bit separating
	RL A
	RL A		;D7-control bit RC
	ORL A,R3		;combine command code and control bit
	MOV R7,A		;store

	SJMP NORC5	;go to return

T2:	JB ACC.0,NORC5
	SJMP STDATA

;RC Recoding Table

RCTAB   	.DB COD_TM	;key code 000H, key function - TIMER
	.DB COD_CL	;key code 001H, key function - CLOCK
	.DB COD_AL	;key code 002H, key function - ALARM
	.DB COD_LK	;key code 003H, key function - LOCK
	.DB 000H		;key code 004H, key function - none
	.DB 000H		;key code 005H, key function - none
	.DB 000H		;key code 006H, key function - none
	.DB 000H		;key code 007H, key function - none
	.DB COD_7		;key code 008H, key function - 7
	.DB COD_8		;key code 009H, key function - 8
	.DB COD_9		;key code 00AH, key function - 9
	.DB COD_LS	;key code 00BH, key function - LIST
	.DB 000H		;key code 00CH, key function - none
	.DB 000H		;key code 00DH, key function - none
	.DB 000H		;key code 00EH, key function - none
	.DB 000H		;key code 00FH, key function - none
	.DB COD_4		;key code 010H, key function - 4
	.DB COD_5		;key code 011H, key function - 5
	.DB COD_6		;key code 012H, key function - 6
	.DB COD_ES	;key code 013H, key function - ESCAPE
	.DB 000H		;key code 014H, key function - none
	.DB 000H		;key code 015H, key function - none
	.DB 000H		;key code 016H, key function - none
	.DB 000H		;key code 017H, key function - none
	.DB COD_AD	;key code 018H, key function - ALARM DISABLE
	.DB 000H		;key code 019H, key function - none
	.DB COD_TC	;key code 01AH, key function - TIMER CLEAR
	.DB 000H		;key code 01BH, key function - none
	.DB 000H		;key code 01CH, key function - none
	.DB 000H		;key code 01DH, key function - none
	.DB 000H		;key code 01EH, key function - none
	.DB 000H		;key code 01FH, key function - none
	.DB COD_0		;key code 020H, key function - 0
	.DB 000H	 	;key code 021H, key function - none
	.DB COD_BK	;key code 022H, key function - BACKSPACE
	.DB 000H		;key code 023H, key function - none
	.DB 000H		;key code 024H, key function - none
	.DB 000H		;key code 025H, key function - none
	.DB 000H		;key code 026H, key function - none
	.DB 000H		;key code 027H, key function - none
	.DB COD_1		;key code 028H, key function - 1
	.DB COD_2		;key code 029H, key function - 2
	.DB COD_3		;key code 02AH, key function - 3
	.DB COD_EN	;key code 02BH, key function - ENTER

;  Functions codes

COD_NO	.EQU 000H		;UNUSED
COD_0	.EQU 001H		;0
COD_1	.EQU 002H		;1
COD_2	.EQU 003H		;2
COD_3	.EQU 004H		;3
COD_4	.EQU 005H		;4
COD_5	.EQU 006H		;5
COD_6	.EQU 007H		;6
COD_7	.EQU 008H		;7
COD_8	.EQU 009H		;8
COD_9	.EQU 00AH		;9
COD_EN	.EQU 00BH		;ENTER
COD_TM	.EQU 00CH		;TIMER
COD_CL	.EQU 00DH		;CLOCK
COD_AL	.EQU 00EH		;ALARM
COD_LK	.EQU 00FH		;LOCK
COD_LS	.EQU 010H		;LIST
COD_ES	.EQU 011H		;ESCAPE
COD_BK	.EQU 012H		;BACKSPACE
COD_TC	.EQU 013H		;TIMER CLEAR
COD_AD	.EQU 014H		;ALARM DISABLE

;Font table
;             ABCDEFGH
FONT	.DB 11111100B	;code 00H, character 0
	.DB 01100000B	;code 01H, character 1
	.DB 11011010B	;code 02H, character 2
	.DB 11110010B	;code 03H, character 3
	.DB 01100110B	;code 04H, character 4
	.DB 10110110B	;code 05H, character 5
	.DB 10111110B	;code 06H, character 6
	.DB 11100000B	;code 07H, character 7
	.DB 11111110B	;code 08H, character 8
	.DB 11110110B	;code 09H, character 9
	.DB 00000000B	;code 0AH, character blank
	.DB 00000010B	;code 0BH, character -
	.DB 11000110B	;code 0CH, character Gr
	.DB 10011100B	;code 0DH, character C
	.DB 00011110B	;code 0EH, character t
	.DB 10001110B	;code 0FH, character F
	.DB 11101110B	;code 10H, character A
	.DB 00001100B	;code 11H, character I
	.DB 00011100B	;code 12H, character L
	.DB 01111100B	;code 13H, character U
	.DB 11001110B	;code 15H, character P

;  Characters Codes Table

CH_BL	.EQU 00AH		;character blank
CH_MN	.EQU 00BH		;character -
CH_GR	.EQU 00CH		;character Gr
CH_C	.EQU 00DH		;character C
CH_T	.EQU 00EH		;character T
CH_F	.EQU 00FH		;character F
CH_A	.EQU 010H		;character A
CH_I	.EQU 011H		;character I
CH_L	.EQU 012H		;character L
CH_U	.EQU 013H		;character U
CH_P	.EQU 014H		;character P

	.TEXT DEVICES
	.END
