;
 ; HDLG-2416 4 char 7x5 clock
 ; versione minima
 ;
 ; HDLG Clock
 ; by Mariani Antonio
 ; ( Z-tech by XD. )
 ; zantaz@libero.it
 ; http://digilander.libero.it/zantaz/
 ; on Internet may 2011
 ;
 ; This program is licensed under the GNU General Public License.
 ; See the file `COPYING' for details
 ;
 ; integrati usati :
 ; - microcontrollore Z86E04 ( 1K rom )
 ; - display intelligente ( 4 char alfanumerici )
 ;
 ; scritto interamente in Assembler Z8@
 ;
 ; HDLGCLK.S
 ;
 ; rev. 1  tc: 0
 ;
 ; tu23oct01 XD.
 ; may11 XD. Z-tech inc. online version
 ;
 ; Z8	dir	outside
 ; P00	o	A0
 ; P01	o	A1
 ; P02	o	/WR
 ; P20	o	DB0
 ; P21	o	DB1
 ; P22	o	DB2
 ; P23	o	DB3
 ; P24	o	DB4
 ; P25	o	DB5
 ; P26	o	DB6
 ; P27	o	CU
 ; P31	i	hour plus button
 ; P32	i	min plus button
 ; P33	i	min minus button
 ;
WORKREG	.equ 10H
CLOCKRG	.equ 20H
 ;
DELAYRH	.equ R4
DELAYRL	.equ R5
 ;
TEMP	.equ R6
TEMPLC	.equ %26
 ;
HOUR   	.equ R7
MIN    	.equ R8
SEC    	.equ R9
SEC10  	.equ R10
COUNT40	.equ R11
 ;
HOURLC	.equ %27
MINLC	.equ %28
SECLC	.equ %29
SEC10LC	.equ %2a
CNT40LC	.equ %2b
 ;
 ; keys macro
THPLUS	macro
       	TM P3,#00000010B ; P31
       	macend
TMPLUS	macro
       	TM P3,#00000100B ; P32
       	macend
TMMINUS	macro
       	TM P3,#00001000B ; P33
       	macend
TMIPL	macro
        TM P3,#00001100B ; P32 & P33
        macend
 ;
 ;	+---------+
 ;	| OTP ROM |
 ;	+---------+
 ;
 ; 6 words table for int ...
       	.org 0000H
 ;        	
	.word INIT	; P32INT
        .word INIT	; P33INT
        .word INIT	; P31INT
        .word INIT	;
        .word T0INT	; 0FFFFH
        .word INIT	; T1INT
 ;
        .org 000CH
 ; start here from reset
 ; disable int
INIT 	DI
 ; set ports
	LD P2M,#00H		; P20-P27o
	LD P3M,#11B		; P3 digital P2 active
	LD P01M,#100B		; P0 out SP internal
 ; set timer
	LD T0,#50		; 2.5 ms t0
	LD PRE0,#11001001B	; div 50
	LD TMR,#3		; load enbl t0
 ; irq4 enabl  max pri
	LD IMR,#00010000B
	CLR IRQ
	LD IPR,#00000011B
 ; set stack pointer
	CLR SPH		; SP at 0080H
	LD SPL,#80H		;
 ; setta i parametri dell'orologio
 ; tutti i dati sono in formato BCD 
	SRP #CLOCKRG
 ;
	LD HOUR,#12H	; hour
	LD MIN, #34H	; min
	CLR SEC		; sec
	CLR SEC10	; 0.1 sec * 10 = 1 sec
	CLR COUNT40	; 2.5 ms * 40 = 0.1 sec
 ;
	SRP #WORKREG
 ;
 ; setta la luminosita' dei quattro dsp
 ; ore & minuti a 100 % di lumonosita'
 ; pulizia dsp
 	LD P0,#100B
	LD P2,#00H	
 ;
	LD P2,#00000010B; ext function enable, do not blank chr, no cursor
 ; 
	LD P0,#011B	; digit 3 left most chr
	LD P0,#111B
	LD P0,#010B	; digit 2
	LD P0,#110B
	LD P0,#001B	; digit 1
	LD P0,#101B
	LD P0,#000B	; digit 0 right most chr
	LD P0,#100B
 ;
 ; ciclo principale
LOOP	EI	; abilita le int.
 ;
	CALL DISPLAY
 ; testa hour plus button	
LP03	THPLUS
	JR NZ,LP00
 ;
LP02	ADD HOURLC,#1
	DA HOURLC
	CP HOURLC,#24H   ; hour
	JR ULT,LP01
	CLR HOURLC
 ;
LP01	CALL DISPLAY
 ;
	CALL DELAYLP
 ;
	JR LP03
 ; testa min plus button
LP00	TMPLUS
	JR NZ,LP04
 ;
	ADD MINLC,#1
	DA MINLC
	CP MINLC,#60H    ; min
	JR ULT,LP06
	CLR MINLC
LP06
 ; resetta cnt40 & sec10 & sec
	CLR CNT40LC
	CLR SEC10LC
	CLR SECLC
 ;
	CALL DISPLAY
 ;
	CALL DELAYLP
 ;
	JR LP00
 ; testa min minus button
LP04	TMMINUS
	JR NZ,LP08
 ;
	SUB MINLC,#1
	DA MINLC
	CP MINLC,#00H    ; min
	JR Z,LP05
	LD MINLC,#59
LP05
 ; resetta cnt40 & sec10 & sec
	CLR CNT40LC
	CLR SEC10LC
	CLR SECLC
 ;
	CALL DISPLAY
 ;
	CALL DELAYLP
 ;
	JR LP04
 ;
LP08	JR LOOP
 ;
 ;
 ;     +-------------+
 ;     | sub-ROUTINE |
 ;     +-------------+
 ;
 ; display l'orologio su i 4 display alfanumerici
 ;
DISPLAY
 ; digit 3 left most chr
 ; decine ore
 ; se decine == 0 stampa spazio
	LD TEMPLC,MINLC
	CP TEMPLC,#0
	JR NZ,L00
	LD TEMPLC,#' '
	JR L01
L00	SWAP TEMPLC
	AND TEMPLC,#0FH
	ADD TEMPLC,#'0'
L01	OR TEMPLC,#80H
	LD P2,TEMPLC
	LD P0,#011B
	LD P0,#111B
 ; digit 2
 ; unita' ore
	LD TEMPLC,MINLC
 	AND TEMPLC,#0FH
 	ADD TEMPLC,#'0'
 	OR TEMPLC,#80H
 	LD P2,TEMPLC
 	LD P0,#010B
 	LD P0,#110B
 ; digit 1
 ; decine minuti
 	LD TEMPLC,SECLC
 	SWAP TEMPLC
 	AND TEMPLC,#0FH
 	ADD TEMPLC,#'0'
 	OR TEMPLC,#80H
 	LD P2,TEMPLC
 	LD P0,#001B
 	LD P0,#101B
 ; digit 0 right most chr
 ; unita' minuti
 	LD TEMPLC,SECLC
 	AND TEMPLC,#0FH
 	ADD TEMPLC,#'0'
 	OR TEMPLC,#80H
 	LD P2,TEMPLC
 	LD P0,#000B
 	LD P0,#100B
 ;
	RET
 ;
 ; delay loop  65536 iterazioni
 ; usa solo registri per la djnz ...
DELAYLP	CLR DELAYRH
D01	CLR DELAYRL
D00	DJNZ DELAYRL,D00
	DJNZ DELAYRH,D01
	RET
 ;
 ;
 ;	+-------------------+
 ; 	| Interrupt Routine |
 ;	+-------------------+
 ;
 ;
 ; 2.5 ms on every interrupt call
 ; 2.5 ms * 40 = 0.1 sec
 ;
 ; CLOCKRG	20H
 ; R6		temp loc
 ; R7		ore loc   
 ; R8		minuti loc
 ; R9		secondi loc
 ; R10		decimi di sec loc
 ; R11		contatore 40 loc
 ;
T0INT	PUSH RP		; salva regiaster pointer
	SRP #CLOCKRG
 ; contatore 40
	INC COUNT40
	CP COUNT40,#40	; contatore 40
	JR ULT,ENDCL
	CLR COUNT40
 ; decimi di secondo
	INC SEC10
	CP SEC10,#10	; 1/10 sec
	JR ULT,ENDCL
	CLR SEC10
 ; secondi
	ADD SEC,#1
	DA SEC
	CP SEC,#60H	; secondi
	JR ULT,ENDCL
	CLR SEC
 ; minuti
	ADD MIN,#1
	DA MIN
	CP MIN,#60H	; minuti
	JR ULT,ENDCL
	CLR MIN
 ; ore
	ADD HOUR,#1
	DA HOUR
	CP HOUR,#24H	; ore
	JR ULT,ENDCL
	CLR HOUR
 ;
ENDCL	POP RP		; ripristina register pointer
	IRET		; torna al main
 ;
 ;
	.end
 ;
 ;