; BELL10.A
 ;
 ; a bell clock software for
 ; mini Z80 board & dedicated I/O
 ; (16[12] input  for keyboard,
 ;   4[ 4] output for bell, led
 ;   & additional 74164 ser-par
 ;   with 7-segment display)
 ;
 ; rev. 0.65
 ;  XD. '96
 ;
 ;      +-----------+
 ;      |  EQUATES  |
 ;      +-----------+
 ;
 ; EQU list RE-EDIT !
 ; VALUE dependent
XDLEN   EQU 32 ; len of pattern
 ;
SIXTY   EQU 0
SEC     EQU 1
MIN     EQU 2
HOUR    EQU 3
DAYOW   EQU 4
DAYOM   EQU 5
MONTH   EQU 6
YEAR    EQU 7
 ;
PRGNUM  EQU 10
 ;
 ; keyboard equates
K0      EQU 00
K1      EQU 01
K2      EQU 02
K3      EQU 03
K4      EQU 04
K5      EQU 05
K6      EQU 06
K7      EQU 07
K8      EQU 08
K9      EQU 09
K10     EQU 10 ; *
K11     EQU 11 ; #
 ;
 ; reg D  1st LS244
KEY10   EQU 0 ; key '*'
KEY7    EQU 1
KEY4    EQU 2
KEY1    EQU 3
KEY0    EQU 4
KEY8    EQU 5
KEY5    EQU 6
KEY2    EQU 7
 ; reg E  2nd LS244
KEY11   EQU 0 ; key '#'
KEY9    EQU 1
KEY6    EQU 2
KEY3    EQU 3
 ;
 ; ERROR IN SCHEMATIC
 ; A0 AND A1 OF LS139 IS SWAPPED
 ; I/O port equates
 ;IN0   EQU 0FCH ; A1=0 A0=0
 ;IN1   EQU 0FDH ; A1=0 A0=1
 ;OUT0  EQU 0FEH ; A1=1 A0=0
 ;OUTSP EQU 0FFH ; A1=1 A0=1
 ;
 ;IN0   EQU 0FCH ; A0=0 A1=0
 ;IN1   EQU 0FEH ; A0=0 A1=1
 ;OUT0  EQU 0FDH ; A0=1 A1=0
 ;OUTSP EQU 0FFH ; A0=1 A1=1
 ;          76543210
IN0     EQU 11111100B
IN1     EQU 11111110B
OUT0    EQU 11111101B
OUTSP   EQU 11111111B
 ;
 ; RAM dependent
 ; this equates must be redefined
XDRAM   EQU 8780H ; n str ram of ptrn
IXBASE  EQU 8080H
INITSP  EQU 8400H ; 8780H
 ;
 ;
 ;      +-------------+
 ;      |  VARIABLES  |
 ;      +-------------+
 ;
 ;
WDOG    EQU 8000H ; .B 1
DELV    EQU 8001H ; .B 1
BELLDL  EQU 8002H ; .W 2
OSTORE  EQU 8004H ; .B 1
TIMETB  EQU 8005H ; .W 2
DMASK   EQU 8007H ; .B 1
 ;TEMP  EQU 8008H ; .B 1
 ;
 ;
 ;      +---------------------+
 ;      | start of EPROM code |
 ;      +---------------------+
 ;
 ;
 ; RESET 0000H
 ; compara laROM con la RAM
 ; se sõ salta all'inzio del programma
 ; se no setta stack pointer
 ;       fai i settagi iniziali
 ;       aspetta il tasto start
 ;
 ; la EPROM parte da quõ
	ORG 0000H
RESET:  DI  ; disabilita le interruzioni
	    ; le INT non sono mai usate 
 ;
 ; set di registri = scratch
 ;
 ; 4.25 sec watch dog time up
        LD A,0FFH
	LD (WDOG),A
 ; ci dovrebbe stare un ritrdo qu&245
        XOR A        ; spegni i leds 
        OUT (OUT0),A ; latcha le uscite
 ; resetta la locazione ostore
        LD (OSTORE),A
 ; spegni il display  quick & dirty
	LD B,8
 ;
DS0:    LD A,0FFH
        OUT (OUTSP),A
 ;
        LD A,7FH
	OUT (OUTSP),A
 ;
        DJNZ DS0
 ;
        LD HL,7FFFH  ; 32767 volte
DEL00:  DEC HL       ; loop di ritardo
        LD A,H
	OR L
	JR NZ,DEL00  ; 26 cicli
 ;
        LD A,0FFH    ; accendi i leds
        OUT (OUT0),A ; latcha le uscite
 ;
	LD HL,7FFFH  ; 32767 volte
DEL01:  DEC HL       ; loop di ritardo
        LD A,H
        OR L
        JR NZ,DEL01  ; 26 cicli
 ;
	XOR A        ; spegni i leds
        OUT (OUT0),A ; latcha le uscite
 ; le chiamate forse non sono permesse quõ
 ; maybe replace with the code
 ; THIS CALL IS HIGHLY DANGEROUS
 ; THE STACK POINTER MAYBE NOT IN
 ; USER RAM SO NO RETURN IS MADE
 ; the are 2 solution:
 ; 1) set before the Stack Pointer
 ;    this can do problem ? if
 ; 2) replace the call with total
 ;    code of the routine
 ;      this is the right case
 ;      CALL XDCHK
 ; XD CHecK routine
 ; compare rom with ram pattern
 ;      EXX ; save usd reg
 ;
	LD B,XDLEN
	LD DE,XDRAM
	LD HL,XDROM
 ;
PTRFD2: LD A,(HL) ; fetch rom
	INC HL    ; inc rom
	EX DE,HL  ; ex rom,ram
	CP (HL)   ; comp ram
	EX DE,HL  ; ex ram,rom
	INC DE    ; inc ram
 ;
	JR NZ,NOPTRN ; jump if n eq
 ; flag Z is reset (0)
 ;
	DJNZ PTRFD2  ; repeat
 ;
 ;      XOR A ; set Z flag
 ; stringa valida trovata in RAM
 ; vai a main loop
 ;      EXX ; restore usd reg
 ;
	JR SJ0
 ;
	DEFS 3
 ; salta a programma utente dopo
 ; le locazioni di settaggio orologio
 ;
SJ0:    JP MAINLP
 ;
 ; questo é un reset a freddo
 ; fai 
NOPTRN: ; do the start stuff
 ; THIS CALL IS HIGHLY DANGEROUS
 ; THE STACK POINTER MAYBE NOT IN
 ; USER RAM SO NO RETURN IS MADE
 ; replace with real code
 ;      CALL RESWDG
 ; setta l'ambiente
	LD SP,INITSP ; setta stack pointer
	LD IX,IXBASE ; setta IX base
 ; memorizza la stringa in RAM
	LD BC,32     ; lunghezza
	LD HL,XDROM  ; partenza
	LD DE,XDRAM  ; arrivo
	LDIR         ; copia tutto
 ; fai le altre init
 ; questo é un reale reset a freddo
 ; salta a INIT prima MAILP
 ; salta a NOPROGrammato stato
	JR SJ1
 ;
	DEFS 3
 ;
SJ1:    JP NOPROG
 ;
 ;	JP INIT
 ;
	DEFS 3
 ;
 ;
 ;      +---------------+
 ;      |  NMI routine  |
 ;      +---------------+
 ;
 ;
 ; DEVE ESSERE PIAZZATA A 0066H
 ;
NMI66H: EX AF,AF ; salva i registri
	EXX      ;
 ; controlla la locazione watchdog
 ; (decrementa, se zero esegui il RESET)
	LD A,(WDOG)  ; load
	CP 00H       ; compare f sec
	JR Z,ZCOUNT  ; jump if zero
 ;
	DEC A        ; decrement
	LD (WDOG),A  ; store
	JR Z,ZCOUNT  ; jump if zero
 ;
	JR NM1
 ;
ZCOUNT: EXX      ; ripristina i registri
	EX AF,AF ;
 ; this jump will be take when
 ; zero count watch dog is reach
 ; probably jump at MAINLP
	JP 0FFFFH ; spare jump
	DEFS 3    ; another s jp
 ; aggiorna le locazioni dell'orologio
NM1:    INC (IX+SIXTY)
        LD A,60
	CP (IX+SIXTY)
	JR NZ,NMI0
        LD (IX+SIXTY),0 ; +1 secondo
        INC (IX+SEC)
	LD A,60
	CP (IX+SEC)
	JR NZ,NMI0
	LD (IX+SEC),0   ; +1 minuto
        INC (IX+MIN)
        LD A,60
        CP (IX+MIN)
        JR NZ,NMI0
	LD (IX+MIN),0   ; +1 ora
        INC (IX+HOUR)
	LD A,24
        CP (IX+HOUR)
	JR NZ,NMI0
	LD (IX+HOUR),0  ; +1 giorno
        INC (IX+DAYOW)
        LD A,8
	CP (IX+DAYOW)
	JR NZ,NMI1
        LD (IX+DAYOW),1 ; +1 settimano (non utile)
NMI1:   ; PUSH HL
	LD HL,MLEN-1
	LD A,(IX+MONTH)
 ; this is a new version
 ; the MLEN can be placed anywhere
	ADD A,L
        LD L,A
        JR NC,NM0
 ;
	INC H
 ;
NM0:    LD A,(HL)
        INC A
	; POP HL
        INC (IX+DAYOM)
        CP (IX+DAYOM)
        JR NZ,NMI0
	LD (IX+DAYOM),1 ; +1 mese
	INC (IX+MONTH)
        LD A,13
        CP (IX+MONTH)
        JR NZ,NMI0
	LD (IX+MONTH),1 ; +1 anno
	INC (IX+YEAR)
	LD A,100
        CP (IX+YEAR)
	JR NZ,NMI0
        LD (IX+YEAR),0  ; +1 secolo
 ; se (ring) decrementa contatore ring
NMI0:   LD HL,(BELLDL) ; carica il contatore
 ;
        LD A,H
	OR L
	JR Z,BL0 ; ritardo 0 non fare niente
 ;
	DEC HL ; decremta contatore
        LD (BELLDL),HL ; memorizza
 ; se (delay) decrementa contatore ritardo
BL0:    LD A,(DELV)
        CP 00H
        JR Z,DL0 ; se 0 non fare niente
 ;
	DEC A
	LD (DELV),A
 ;
DL0:    EXX      ; ripristina i registri
        EX AF,AF ;
 ;
        RETN ; ritorna da un non
	     ; maskable interrupt
 ;
 ;
 ;      +----------------+
 ;      |  MAIN PROGRAM  |
 ;      +----------------+
 ;
 ;
 ; aspetta il tasto start
 ; segnala non programmato stato
 ; led=0
 ; aspetta 30
 ; led=1
 ; aspetta 30
 ; salta attesa st...
 ;
 ; esegui la routine di inizializzazione
 ;
 ; 1/2 sec lampeggio led 
 ; fino al tasto start
 ;
NOPROG: JR SJ2
 ;
	DEFS 3
 ; d    -
 ; i
 ; s    -
 ; p
 ; lay  -
 ; segment   pgfedcba
SJ2:	LD A,10110110B
	CALL PARSR2
 ;
NP99:   CALL LEDON
 ;
	LD A,30 ; 1/2 sec ritardo
	LD (DELV),A
 ;
NP0:    CALL KEYPRS
 ;
	CP K10+80H ; key '*'
	JR Z,NP9
 ;
NP1:    LD A,(DELV)
	CP 0
	JR NZ,NP0 ; ritardo non zero
 ;
	CALL LEDOFF
 ;
	LD A,30 ; 1/2 sec ritardo
	LD (DELV),A
 ;
NP2:    CALL KEYPRS
 ;
	CP K10+80H ; key '*'
	JR Z,NP9
 ;
NP3:    LD A,(DELV)
	CP 0
	JR NZ,NP2 ; ritardo non zero
 ;
	JR NP99   ; salta indietro
 ; aspetta il rilascio del tasto
NP9: ;	CALL KEYREL
 ; lampeggio del led
	CALL BLINK
 ; display spento
	CALL DSPOFF
 ;
 ; set up ora/data e numro programma
 ; la sequenza di input é :
 ; decine ORE      unitõ ORE
 ; decine MINUTI   unitõ MINUNTI
 ; decine YEAR     unitò ANNO
 ; decine MONTH    unitó MESE
 ; decine GIORNODM unitô GIORNODM
 ;        ZERO     unitõ GIORNODS
 ; decine PRGNUM   unitõ PRGNUM
 ; numero totale tasti : 14
 ;
 ; i secondi e i sessantesimi di secondi sono
 ; azzerati dopo l'introduzione dei dati
INIT:	JR SJE
 ;
	DEFS 3
 ;
SJE:	XOR A
	LD (IX+SEC),A
	LD (IX+SIXTY),A
 ; set ore
	CALL GET2DC
 ;
	CP 24 ; max ore + 1
	JR C,SE5
	XOR A ; ore = 0
SE5:    LD (IX+HOUR),A
 ; set minuti
	CALL GET2DC
 ;
	CP 60 ; max minuti + 1
	JR C,SE6
	XOR A ; minuti == 0
SE6:    LD (IX+MIN),A
 ;
	JR SEA
 ; set anno
SEA:    CALL GET2DC
 ;
	LD (IX+YEAR),A
 ; set mese
	CALL GET2DC
 ;
	CP 0   ; mese == 0 ?
	JR Z,SE0
	CP 13  ; max mese + 1
	JR C,SE1
SE0:    LD A,1 ; set gennaio
SE1:    LD (IX+MONTH),A
 ; set giorno del mese
	CALL GET2DC
 ;
	CP 0  ; giorno == 0 ?
	JR Z,SE3
	CP 32 ; max dayom + 1
	JR C,SE4
SE3:    LD A,1 ; set giorno 1 
SE4:    LD (IX+DAYOM),A
 ; set giorno della settimana
	CALL GET2DC
 ;
	CP 0  ; giorno d s == 0 ?
	JR Z,SE8
	CP 8 ; max giorno d s  + 1
	JR C,SE9
SE8:    LD A,1 ; set lunedñ
SE9:    LD (IX+DAYOW),A
 ; set numero programma
	CALL GET2DC
 ; nessun controllo
	LD (IX+PRGNUM),A
 ; trova l'inizio della tabella di tempo
 ; designata dal numero programma
 ;      LD A,(IX+PRGNUM)
 ; trova inizio tabella
	LD HL,TABLE
 ; compara numero programma con 0
	CP 00H
	JR Z,PR1
 ; doppio incremento dell'inizio tabella
PR0:    INC HL
	INC HL
 ; decrementa numero programma e cicla
	DEC A
	JR NZ,PR0
 ; ora HL punta alla tabella tempo
PR1:    LD E,(HL) ; get ttblXX lo
	INC HL
	LD D,(HL) ; get ttblXX hi
	EX DE,HL  ; ex DE <-> HL
	LD (TIMETB),HL ; store
 ; lampeggia led per significare stato programmato
	CALL BLINK
 ;
 ; ciclo principale :
 ; compara tabella tempo
 ; se c'é un hit fai suonare la campanella
 ; butta fuori sul display l'orologio
 ; tasto start schiacciato ?
 ; se si controlla codice d'accesso
 ; vai a ciclo principale
 ;
 ; main loop
MAINLP: JR SJ3
 ;
	DEFS 3
 ;
SJ3:	CALL RESWDG
 ; esegui comparazione tabella tempo
	CALL TTCOMP
 ; display informazioni orologio
	CALL CLKOUT
 ; esegui key press
	CALL KEYPRS
 ; nessun tasto ?
	BIT 7,A
	JR NZ,MA0 ; un tasto é stato premuto
	JR MAINLP
 ; controlla tasto start
MA0:    CP K10+80H ; tasto '*'
	JR NZ,MAINLP ; non tasto '*'
 ; esegui rilascio tasto
 ;	CALL KEYREL
 ; sequenza controllo codice
 ; d
 ; i   |
 ; s
 ; p   |
 ; lay
 ;           pgfedcba
	LD A,11001111B
	CALL PARSR2
 ;
	CALL BLINK
 ; controlla il primo tasto del codice
	LD A,K4
 ; esegui controllo tasto
	CALL CHKKEY
 ; flag Z on, tasto richiesto premuto
	JR NZ,MAINLP
 ; d    -
 ; i   |
 ; s
 ; p   |
 ; lay
 ;           pgfedcba
	LD A,11001110B
	CALL PARSR2
 ; controlla secondo tasto del codice
	LD A,K5
 ; esegui controllo tasti
	CALL CHKKEY
 ; flag Z on, tasto richiesto premuto
	JR NZ,MAINLP
 ; d    -
 ; i   |
 ; s    -
 ; p   |
 ; lay
 ;           pgfedcba
	LD A,10001110B
	CALL PARSR2
 ; controlla terzo tasto del codice
	LD A,K6
 ; esegui controllo tasti
	CALL CHKKEY
 ; flag Z on, tasto richiesto premuto
	JR NZ,MAINLP
 ; d    -
 ; i   |
 ; s    -
 ; p   |
 ; lay  -
 ;           pgfedcba
	LD A,10000110B
	CALL PARSR2
 ; controlla tasto finale del codice
	LD A,K10 ; *
 ; esegui controllo tasti
	CALL CHKKEY
 ; flag Z on, tasto richiesto premuto
	JR NZ,MAINLP
 ; d    -
 ; i   | |
 ; s    -
 ; p   | |
 ; lay  -
 ;           pgfedcba
	LD A,10000000B
	CALL PARSR2
 ; ora il codice di sicurezza é stato 
 ; verificato lampeggia 1/2 sec
	CALL BLINK
 ; salta a INIT
	JP INIT
 ;
	DEFS 3
 ;
 ;
 ;      +----------------+
 ;      |  SUB-ROUTINEs  |
 ;      +----------------+
 ;
 ;
 ; tabella codici tasto
 ;  key   code
 ;   0  -  00
 ;   1  -  01
 ;   2  -  02
 ;   3  -  03
 ;   4  -  04
 ;   5  -  05
 ;   6  -  06
 ;   7  -  07
 ;   8  -  08
 ;   9  -  09
 ;   *  -  10
 ;   #  -  11 ( per ragioni 
 ;              pratiche é = 10 )
 ;
 ; '#' key equal '*' key
 ; KEY SCaN routine
 ; IN:  nessuno
 ; OUT: reg B ultimo codice tasto
 ;      reg C contatore tasto
 ;      ex. C = 0 no key hit
 ;          C = 1 one key hit (OK)
 ;          C = 2 two key hit (WRONG)
 ; sporca AF
 ;
KEYSCN: PUSH DE
 ;
	CALL RESWDG
 ;
        LD BC,0000H
 ; reg B ultimo tasto = 0
 ; reg C contatore tasto = 0
 ;
        IN A,(IN0)
	LD D,A ; reg D 1st LS244
 ;
	IN A,(IN1)
	LD E,A ; reg E 2nd LS244
 ;
        BIT KEY0,D
	JR NZ,KK0
 ; tatso 0 premuto
        LD B,K0 ; memorizza codice
	INC C   ; incrementa contatore
 ;
KK0:    BIT KEY1,D
	JR NZ,KK1
 ; tasto 1 premuto
	LD B,K1 ; memorizza codice
        INC C   ; incrementa contatore
 ;
KK1:    BIT KEY2,D
	JR NZ,KK2
 ; tasto 2 premuto
        LD B,K2 ; memorizza codice
	INC C   ; incrementa contatore
 ;
KK2:    BIT KEY3,E
        JR NZ,KK3
 ; tatso 3 premuto
	LD B,K3 ; store code
	INC C   ; inc count
 ;
KK3:    BIT KEY4,D
	JR NZ,KK4
 ; key 4 pressed
        LD B,K4 ; store code
        INC C   ; inc count
 ;
KK4:    BIT KEY5,D
        JR NZ,KK5
 ; key 5 pressed
        LD B,K5 ; store code
        INC C   ; inc count
 ;
KK5:    BIT KEY6,E
	JR NZ,KK6
 ; key 6 pressed
        LD B,K6 ; store code
	INC C   ; inc count
 ;
KK6:    BIT KEY7,D
        JR NZ,KK7
 ; key 7 pressed
	LD B,K7 ; store code
	INC C   ; inc count
 ;
KK7:    BIT KEY8,D
	JR NZ,KK8
 ; key 8 pressed
        LD B,K8 ; store code
        INC C   ; inc count
 ;
KK8:    BIT KEY9,E
        JR NZ,KK9
 ; key 9 pressed
	LD B,K9 ; store code
	INC C   ; inc count
 ;
KK9:    BIT KEY10,D
	JR NZ,KK10
 ; key * pressed
	LD B,K10 ; store code
	INC C    ; inc count
 ;
KK10:   BIT KEY11,E
	JR NZ,KK11
 ; key # pressed
	LD B,K10 ; store code
		 ; equal to '*'
	INC C    ; inc count
 ;
KK11:   POP DE
 ;
	RET
 ; @
 ; mk. I+
 ; wait KEY RELease routine
 ; IN:  none
 ; OUT: flag Z on
 ; trash AF
 ;
KEYREL: PUSH BC
 ;
KY0:    CALL KEYSCN
 ; already CALL RESWDG
	XOR A
	CP C
	JR NZ,KY0 ; hit again ?
 ;
	POP BC
 ;
	RET
 ; @
 ; LED ON routine
 ; IN:  none
 ; OUT: none
 ; USD: loc (OSTORE)
 ; trash AF
 ;
LEDON:  LD A,0011B
	JR UPDOUT
 ; @
 ; LED OFF routine
 ; IN:  none
 ; OUT: none
 ; USD: loc (OSTORE)
 ; trash AF
 ;
LEDOFF: LD A,0010B
	JR UPDOUT
 ; @
 ; START Ring bell routine
 ; IN:  none
 ; OUT: none
 ; USD: loc (OSTORE)
 ; trash AF
 ;
STARTR:	LD A,1100B
	JR UPDOUT
 ; @
 ; STOP Ring bell routine
 ; IN:  none
 ; OUT: none
 ; USD: loc (OSTORE)
 ; trash AF
 ;
STOPR:	LD A,1000B
	JR UPDOUT
 ; @
 ; UPDate OUT routine
 ; IN:  reg A out mask
 ; OUT: none
 ; USD: loc (OSTORE)
 ; trash AF
 ;
 ; reg A mask specification
 ; 7654 3     2        1     0
 ; **** B enb B on/off L enb L on/off
 ;
 ; example of LED/BELL conn.
 ; d7 - BELL  d0 - LED
 ;
UPDOUT: PUSH BC
 ;
	LD C,A ; store temp
 ;
	LD A,(OSTORE) ; load out
 ;
	BIT 1,C  ; LED enable ?
	JR Z,UP0 ; no
 ;
	BIT 0,C
	JR Z,UP1
 ;
	SET 0,A ; LED out  *
	JR UP0
 ;
UP1:    RES 0,A ; LED out  *
 ;
UP0:    BIT 3,C  ; BELL enable ?
	JR Z,UP5 ; no
 ;
	BIT 2,C
	JR Z,UP4
 ;
	SET 7,A ; BELL out  *
	JR UP5
 ;
UP4:    RES 7,A ; BELL out  *
 ;
UP5:    LD (OSTORE),A ; store out
 ;
	OUT (OUT0),A ; latch out
 ;
	POP BC
 ;
	RET
 ; @
 ; KEY PReSsed routine
 ; IN:  none
 ; OUT: reg A key code
 ; trash AF
 ;
 ; example of key code
 ; 7   6 5 4  3 2 1 0
 ; hit * * *  keycode
 ; reg A = 00H if error
 ;
KEYPRS: PUSH BC
	PUSH DE
 ;
	CALL KEYSCN
 ;
	LD A,1
	CP C
	JR NZ,KE0 ; must be 1 hit
 ;
	LD D,B ; store key code
 ;
	LD A,3 ; delay 3*1/60 sec
	CALL DELAY
 ; after delay recheck key
	CALL KEYSCN
 ;
	LD A,1
	CP C
	JR NZ,KE0 ; must be 1 hit
 ;
	LD A,D
	CP B
	JR NZ,KE0 ; not equal
 ;
	LD A,B
	AND 0FH ; mask out hi nibble
	SET 7,A ; set hit flag
 ;
	JR KE2 ; jump restore & ret
 ;
KE0:    XOR A ; equal 0 error
 ;
KE2:    POP DE
	POP BC
 ;
	RET
 ; @
 ; mk. I+
 ; GET DECimal key routine
 ; IN:  none
 ; OUT: reg A decimal key
 ; trash AF
 ; key is output on display
 :
GETDEC: PUSH DE
 ;
GE0:    CALL KEYPRS
 ; reg A key code + hit
	BIT 7,A
	JR Z,GE0 ; no key
 ;
	AND 0FH ; mask out hi nibble
	CP 10 ; max dec key + 1
	LD D,A ; store dec key
	JR NC,GE0 ; beyond decimal
 ; valid decimal key
	CALL DSPOFF
 ; led flash / key release
	CALL BLINK
 ;
	LD A,D
	CALL DSPOUT
 ;
	LD A,D ; load dec key
 ;
	POP DE
 ;
	RET
 ; @
 ; DELay 10 (1/6 sec) routine
 ; IN:  none
 ; OUT: none
 ; trash AF
 ;
DEL10:  LD A,10
	JR DELAY
 ; @
 ; DELay 20 (1/3 sec) routine
 ; IN:  none
 ; OUT: none
 ; trash AF
 ;
DEL20:  LD A,20
	JR DELAY
 ; @
 ; DELay 30 (1/2 sec) routine
 ; IN:  none
 ; OUT: none
 ; trash AF
 ;
DEL30:  LD A,30
	JR DELAY
 ; @
 ; DELay 40 (2/3 sec) routine
 ; IN:  none
 ; OUT: none
 ; trash AF
 ;
DEL40:  LD A,40
 ;	JR DELAY
 ;
 ; @
 ; DELAY routine & reset wdog
 ; IN:  reg A delay value
 ;      (0-255) 1/60 sec
 ; OUT: none (reg A 00H , Z)
 ; trash AF
 ;
DELAY:  LD (DELV),A
 ;
DE0:    CALL RESWDG
 ;
	LD A,(DELV)
	CP 0
	JR NZ,DE0 ; delay not zero
 ;
	RET
 ;
 ; @
 ; RESet WatchDoG routine
 ; reset wdog at 1/6 sec
 ; IN:  none
 ; OUT: none
 ; USD: (WDOG)
 ; trash AF
 ;
RESWDG: LD A,10 ; 1/6 sec watchdog
	LD (WDOG),A ; store wdog
 ;
	RET
 ; @
 ; mk. II+
 ; Time Table COMPare routine
 ; IN:  none
 ; OUT: none
 ; USD: (TIMETB).W
 ; trash AF
 ;
TTCOMP: JR SJ4
 ;
	DEFS 3
 ;
SJ4:	PUSH BC
	PUSH HL
 ; compute day mask
	LD B,(IX+DAYOW)
	LD A,80H ; 1000 0000
 ;
CT0:    RLCA     ; rotate <<
	DJNZ CT0
 ; reg A day mask
	LD C,A ; reg C day mask
 ; get actual time table pointer
	LD HL,(TIMETB)
 ;
CT1:    LD A,(HL)
	CP 0FFH
	JR Z,CT5 ; end of list
 ;
	LD A,(IX+HOUR) ; get sys hour
	CP (HL) ; compare with table
	JR NZ,CT2 ; skip 3 item
 ;
	INC HL
 ;
	LD A,(IX+MIN) ; get sys min
	CP (HL) ; compare with table
	JR NZ,CT3 ; skip 2 item
 ;
	INC HL
 ;
	LD A,(HL) ; get tbl day item
 ; the reg A must be saved for
 ; full/half bell ring time
	LD (DMASK),A
 ;
	AND C ; and with day mask
 ; now reg A contains the day bit
	CP C  ; comp with day mask
 ;
	JR Z,RINGB ; the bell ring !
	JR CT4
 ; remember pop bc
 ; must be a exit or re-enter loop
 ; use also (DMASK).B
CT2:    INC HL
CT3:    INC HL
CT4:    INC HL
 ;
	JR CT1 ; jump back
 ; end list reached do ret
CT5:   	CALL STOPR ; for safe
 ;
	POP HL
	POP BC
 ;
	RET
 ;
 ; RING Bell
RINGB:  CALL STARTR ; ring bell
 ;
	PUSH HL
 ;
	LD A,(DMASK)
	BIT 7,A
 ;
	JR Z,RI0
 ;
	LD HL,360 ; 6 sec delay
 ;
	JR RI1
 ;
RI0:    LD HL,180 ; 3 sec delay
 ;
RI1:    CALL BDELAY
 ;
	CALL STOPR ; stop ring
 ; now is safe wait 58 seconds
 ; before go back
 ; 58+3 -> 1:01
 ; 58+6 -> 1:04
 ; resolve multiplication
 ;      LD HL,58*60
	LD HL,3480
	CALL BDELAY
 ;
	POP HL
 ; back to the end of TTCOMP
	JR CT5
 ; @
 ; Bell DELAY routine
 ; IN:  reg HL value in 1/60 sec
 ; OUT: reg HL = 0000H, flag Z
 ; trash AF
 ;
BDELAY: LD (BELLDL),HL
 ;
BLD0:   CALL RESWDG
 ;
	LD HL,(BELLDL)
 ;
	LD A,H
	OR L
	JR NZ,BLD0 ; (BELLDL).W==0 ?
 ;
	RET
 ;
 ; @
 ; mk. I+
 ; BLINK led/keyrel routine
 ; IN:  none
 ; OUT: none
 ; trash AF
BLINK:  LD A,10 ; 1/6+1/6 sec
	PUSH AF
 ; wait key release
	CALL KEYREL
 ; led flash
	CALL LEDON
 ;
	POP AF
	PUSH AF
 ; reg A delay value in 1/60 sec
	CALL DELAY
 ;
	CALL LEDOFF
 ; reg A delay value in 1/60 sec
	POP AF
	CALL DELAY
 ;
	RET
 ; @
 ; mk. I+
 ; CHecK KEY routine
 ; IN:  reg A key code required
 ; OUT: flag Z on if the key req
 ;      was pressed
 ;  the routine return only when
 ;  a key was pressed
 ;  no output on display
 ; trash AF
 ;
CHKKEY: PUSH AF
 ; do key pressed scan
CH0:    CALL KEYPRS
 ; test if a key was pressed
	BIT 7,A
 ; jump if not a hit
	JR Z,CH0
 ; get req key code
	RES 7,A
	LD B,A
 ;
	POP AF
	CP B
	RET NZ ; ret if not key
 ; do led blink / key release
	CALL BLINK
 ; do key release
 ;	CALL KEYREL
	XOR A ; set Z flag
 ;
	RET
 ; @
 ; mk. I+
 ; GET 2 DeCimal key routine
 ; IN:  none
 ; OUT: reg A equal
 ;      ((1st key) * 10) + (2nd key)
 ; trash AF
 ;
GET2DC: PUSH BC
	PUSH DE
 ;
	CALL GETDEC
 ;
 ; multiply by 10
	LD D,A ; store A
	ADD A,A ; *2
	LD E,A ; store A*2
	LD A,D ; load A
	RLCA ; *2
	RLCA ; *4
	RLCA ; *8
	ADD A,E ; *8 + *2 = *10
 ; reg A = reg A * 10
	LD E,A ; store 1st key *10
 ;
	CALL GETDEC
 ;
	ADD A,E ; add 2nd key
 ; little led flash
 ;	CALL BLI10 error AF
 ;	DEFW 0
 ;	DEFB 0
 ;
	POP DE
	POP BC
 ;
	RET
 ;
 ; @
 ; mk. II
 ; PAR SeR 2 routine
 ; IN:  reg A data out serial
 ; OUT: none
 ; trash AF
 ;
 ; bit 0 serial data
 ; bit 7 serial clock
 ;
PARSR2: PUSH BC
	PUSH DE
 ;
	LD C,A ; save in
 ; eight bit xnfer
	LD B,8
 ; extract 1 bit
PA8:    LD A,C ; restore in
	RLCA   ; rotate left
	LD C,A ; save
 ;
	JR NC,PA2
 ;
	LD D,1 ; bit 0 data
 ;
	JR PA3
 ;
PA2:    LD D,0 ; bit 0 data
 ; trasmit 1 bit
PA3:    LD A,D
	SET 7,A ; bit 7 clock
 ; clock high
	OUT (OUTSP),A
 ;
	LD A,D
 ; clock low
	OUT (OUTSP),A
 ;
	LD A,D
	SET 7,A ; bit 7 clock
 ; clock high
	OUT (OUTSP),A
 ;
	DJNZ PA8
 ;
	POP DE
	POP BC
 ;
	RET
 ; @
 ; mk. II+
 ; SeGment OUT 2 routine
 ; IN:  reg A
 ; OUT: none
 ; trash AF
 ; in this 2nd version STABLE
 ; can placed anywhere
 ;
SGOUT2: PUSH HL
 ; load HL with segment table
	LD HL,STABLE
	ADD A,L
	LD L,A
	JR NC,SG0
 ;
	INC H
 ; get segment
SG0:    LD A,(HL)
 ; led out
	CALL PARSR2
 ;
	POP HL
 ;
	RET
 ; @
 ; DiSPlay OFF routine
 ; IN:  none
 ; OUT: none
 ; trash AF
 ;
DSPOFF: LD A,0FFH
 ;
	CALL PARSR2
 ;
	RET
 ; @
 ; mk. I+
 ; DiSPlay OUT routine
 ; IN:  reg A lo nibble (0-9)
 ; OUT: none
 ; trash AF
 ;
DSPOUT: CALL SGOUT2
 ;
 ;	CALL BLI20
 ;	CALL DEL30
	CALL DEL40
 ;
	CALL DSPOFF
 ;
 ;	CALL BLI10
	CALL DEL10
 ;
	RET
 ; @
 ; DIVide by 10 routine
 ; IN:  reg A value
 ; OUT: C=A/10 A=A%10
 ; trash AF
 ;
DIV10:  LD C,0
 ;
DV0:    INC C
	SUB 10
	JR NC,DV0
 ;
	ADD A,10
	DEC C
 ;
	RET
 ; @
 ; DiSPlay Out 4 routine
 ; and a trail byte on display
 ; IN:  reg A 2 BCD digit
 ;      reg C byte
 ; OUT: none
 ; trash AF
 ;
DSPO4:  PUSH BC
	PUSH AF
 ;
	CALL DIV10
 ;
	LD A,C
	CALL DSPOUT
 ;
	POP AF
 ;
	CALL DIV10
 ;
	CALL DSPOUT
 ;
 ;	CALL BLI10
	CALL DEL10 ; ?
 ; call time table compare
	CALL TTCOMP
 ;
	POP BC
	LD A,C
	CALL PARSR2
 ;
	CALL DEL30 ; ?
 ;
	CALL DSPOFF
 ;
	CALL DEL10 ; ?
 ;
	RET
 ; @
 ; CLocK location OUT routine
 ; IN:  none
 ; OUT: none
 ; trash AF
 ;
CLKOUT: JR SJ6
 ;
	DEFS 3
 ;
SJ6:	PUSH BC
	PUSH HL
 ;
 ; do little intro
	LD B,ENDLID-LIDATA
	LD HL,LIDATA
LI0:	LD A,(HL)
	CALL PARSR2
	CALL DEL20 ; ?
	INC HL
	JR NC,LI1
 ;
	INC H
 ;
LI1:	DJNZ LI0
 ; hour out
	LD A,(IX+HOUR)
 ; d
 ; i
 ; s
 ; p
 ; lay  -
 ; segment   pgfedcba
	LD C,11110111B
	CALL DSPO4
 ; min out
	LD A,(IX+MIN)
 ; d
 ; i
 ; s    -
 ; p
 ; lay  -
 ; segment   pgfedcba
	LD C,10110111B
	CALL DSPO4
 ; sec out
	LD A,(IX+SEC)
 ; d    -
 ; i
 ; s    -
 ; p
 ; lay  -
 ; segment   pgfedcba
	LD C,10110110B
	CALL DSPO4
 ;
 ;	CALL BLI20 ; ?
 ; day of month out
	LD A,(IX+DAYOM)
 ; d    -
 ; i
 ; s
 ; p
 ; lay
 ; segment   pgfedcba
	LD C,11111110B
	CALL DSPO4
 ; month out
	LD A,(IX+MONTH)
 ; d    -
 ; i
 ; s    -
 ; p
 ; lay
 ; segment   pgfedcba
	LD C,10111110B
	CALL DSPO4
 ; year out
	LD A,(IX+YEAR)
 ; d    -
 ; i
 ; s    -
 ; p
 ; lay  -
 ; segment   pgfedcba
	LD C,10110110B
	CALL DSPO4
 ; day of week out
	LD A,(IX+DAYOW)
 ; d    -
 ; i   | |
 ; s    -
 ; p   |
 ; lay
 ; segment   pgfedcba
	LD C,10001100B
	CALL DSPO4
 ; program number out
	LD A,(IX+PRGNUM)
 ; d
 ; i
 ; s
 ; p
 ; lay
 ; segment   pgfedcba
	LD C,11111111B
	CALL DSPO4
 ;
	POP HL
	POP BC
 ;
	RET
 ;
 ;
 ;
 ;      +----------+
 ;      |  TABLEs  |
 ;      +----------+
 ;
 ;
 ; magic pattern
 ;            0123456789012345
XDROM:  DEFM "Bell Z80 Clock v"
	DEFM "7.77 by XD. 1996"
 ;
	DEFB 31 ;
 ; standard month len table
MLEN:   DEFB 31,28,31,30,31,30
	DEFB 31,31,30,31,31,31
 ;
 ;       aaa
 ;      f   b
 ;      f   b
 ;       ggg
 ;      e   c
 ;      e   c
 ;       ddd  p
 ;
	DEFB 11000000B ; 0
 ;           pgfedcba
STABLE: DEFB 11000000B ; 0
	DEFB 11111001B ; 1
	DEFB 10100100B ; 2
	DEFB 10110000B ; 3
	DEFB 10011001B ; 4
	DEFB 10010010B ; 5
	DEFB 10000010B ; 6
	DEFB 11111000B ; 7
	DEFB 10000000B ; 8
	DEFB 10010000B ; 9
	DEFB 11100100B ; * symbol
 ;	DEFB 10111111B ; - symbol
 ;
	DEFS 5
 ;
 ;12301230123012301230123012301230123
 ; -   -   -   -   -
 ;    | | | | | | | | | |
 ;         -   -   -   -   -
 ;            | | | | | | | | | |
 ;                 -   -   -   -   -
 ; little intro data
 ; segment   pgfedcba
LIDATA:	DEFB 11111111B
	DEFB 11111111B
	DEFB 11111110B
	DEFB 11011100B
	DEFB 10011100B
	DEFB 10001000B
	DEFB 10000000B
	DEFB 10000001B
	DEFB 10000011B
	DEFB 11100011B
	DEFB 11110111B
	DEFB 11111111B
	DEFB 11111111B
ENDLID:
 ; time table
 ; morning  mon-sat
 ; 07:55
 ; 08:00
 ; 08:50
 ; 09:40
 ; 10:30
 ; 10:40
 ; 11:30
 ; 12:20
 ; 12:50 *
 ; 13:10
 ;
 ; afternoon  tue-fri  (0,1,2,3)
 ; 14:10
 ; 15:00
 ; 15:50
 ; 16:40
 ; 17:30
 ;
 ; FF:FF end table
 ;
 ; example of poss. day coding
 ;
 ; bit  7  6  5  4  3  2  1  0
 ; day  *  Su Sa Fr Th We Tu Mo
 ;
 ; *=0 half ring  *=1 full ring
 ;
 ; e.g. 1  0  1  1  1  1  1  1
 ;      1  0  0  1  0  0  1  0
 ;
 ; compare time&day table
 ;           hh,mm
 ;           76543210
 ;           *ssftwtm
 ;           *uarheuo
 ;           0 equ don't care
 ;           1 equ day active
 ;
 ; new table organization
 ; number 00 only morning
 ; number 01 morning-aft1/tue
 ; number 02 morning-aft1/fri
 ; number 03 morning-aft1/tuefri
 ; number 04 morning-aft2/tue
 ; number 05 morning-aft2/fri
 ; number 06 morning-aft2/tuefri
 ; number 07 morning-aft3/tue
 ; number 08 morning-aft3/fri
 ; number 09 morning-aft3/tuefri
 ;
 ; legend:
 ; aft1 -> normal time
 ; aft2 -> normal time + 5 min
 ; aft1 -> normal time - 5 min
 ;
 ; PRG number > 00 <
 ; morning mon-sat +
 ; no afternoon
 ;
 ; morning mon-sat
TTBL00: DEFB 07,55,MONSAT
	DEFB 08,00,MONSAT
        DEFB 08,50,MONSAT
        DEFB 09,40,MONSAT
        DEFB 10,30,MONSAT
	DEFB 10,40,MONSAT
        DEFB 11,30,MONSAT
	DEFB 12,20,MONSAT
        DEFB 12,50,MONSA2 ; *
        DEFB 13,10,MONSAT
 ; no afternoon
        DEFB 0FFH,0FFH,0FFH ; end tbl
 ;
 ; eventually def spare table item
 ;      DEFS XX
 ;
 ; PRG number > 01 <
 ; morning mon-sat +
 ; afternoon tue
 ;
 ; morning mon-sat
TTBL01: DEFB 07,55,MONSAT
        DEFB 08,00,MONSAT
        DEFB 08,50,MONSAT
        DEFB 09,40,MONSAT
	DEFB 10,30,MONSAT
	DEFB 10,40,MONSAT
        DEFB 11,30,MONSAT
        DEFB 12,20,MONSAT
        DEFB 12,50,MONSA2 ; *
        DEFB 13,10,MONSAT
 ; afternoon tue
        DEFB 14,10,TUE
        DEFB 15,00,TUE
        DEFB 15,50,TUE
        DEFB 16,40,TUE
	DEFB 17,30,TUE
        DEFB 0FFH,0FFH,0FFH ; end tbl
 ;
 ; eventually def spare table item
 ;      DEFS XX
 ;
 ; PRG number > 02 <
 ; morning mon-sat +
 ; afternoon fri
 ;
 ; morning mon-sat
TTBL02: DEFB 07,55,MONSAT
	DEFB 08,00,MONSAT
        DEFB 08,50,MONSAT
        DEFB 09,40,MONSAT
        DEFB 10,30,MONSAT
        DEFB 10,40,MONSAT
        DEFB 11,30,MONSAT
        DEFB 12,20,MONSAT
        DEFB 12,50,MONSA2 ; *
	DEFB 13,10,MONSAT
 ; afternoon fri
        DEFB 14,10,FRI
        DEFB 15,00,FRI
        DEFB 15,50,FRI
	DEFB 16,40,FRI
        DEFB 17,30,FRI
        DEFB 0FFH,0FFH,0FFH ; end tbl
 ;
 ; eventually def spare table item
 ;      DEFS XX
 ;
 ; PRG number > 03 <
 ; morning mon-sat +
 ; afternoon tue/fri
 ;
 ; morning mon-sat
TTBL03: DEFB 07,55,MONSAT
        DEFB 08,00,MONSAT
        DEFB 08,50,MONSAT
        DEFB 09,40,MONSAT
        DEFB 10,30,MONSAT
        DEFB 10,40,MONSAT
	DEFB 11,30,MONSAT
        DEFB 12,20,MONSAT
	DEFB 12,50,MONSA2 ; *
        DEFB 13,10,MONSAT
 ; afternoon tue/fri
        DEFB 14,10,TUEFRI
	DEFB 15,00,TUEFRI
        DEFB 15,50,TUEFRI
        DEFB 16,40,TUEFRI
        DEFB 17,30,TUEFRI
	DEFB 0FFH,0FFH,0FFH ; end tbl
 ;
 ; eventually def spare table item
 ;      DEFS XX
 ;
 ; PRG number > 04 <
 ; morning mon-sat +
 ; afternoon tue  +5min
 ;
 ; morning mon-sat
TTBL04: DEFB 07,55,MONSAT
        DEFB 08,00,MONSAT
	DEFB 08,50,MONSAT
        DEFB 09,40,MONSAT
        DEFB 10,30,MONSAT
        DEFB 10,40,MONSAT
        DEFB 11,30,MONSAT
        DEFB 12,20,MONSAT
        DEFB 12,50,MONSA2 ; *
	DEFB 13,10,MONSAT
 ; afternoon tue  +5min
        DEFB 14,15,TUE
        DEFB 15,05,TUE
        DEFB 15,55,TUE
        DEFB 16,45,TUE
        DEFB 17,35,TUE
        DEFB 0FFH,0FFH,0FFH ; end tbl
 ;
 ; eventually def spare table item
 ;      DEFS XX
 ;
 ; PRG number > 05 <
 ; morning mon-sat +
 ; afternoon fri  +5min
 ;
 ; morning mon-sat
TTBL05: DEFB 07,55,MONSAT
        DEFB 08,00,MONSAT
        DEFB 08,50,MONSAT
        DEFB 09,40,MONSAT
        DEFB 10,30,MONSAT
	DEFB 10,40,MONSAT
        DEFB 11,30,MONSAT
        DEFB 12,20,MONSAT
        DEFB 12,50,MONSA2 ; *
        DEFB 13,10,MONSAT
 ; afternoon fri  +5min
        DEFB 14,15,FRI
        DEFB 15,05,FRI
        DEFB 15,55,FRI
        DEFB 16,45,FRI
        DEFB 17,35,FRI
	DEFB 0FFH,0FFH,0FFH ; end tbl
 ;
 ; eventually def spare table item
 ;      DEFS XX
 ;
 ; PRG number > 06 <
 ; morning mon-sat +
 ; afternoon tue/fri  +5min
 ;
 ; morning mon-sat
TTBL06: DEFB 07,55,MONSAT
        DEFB 08,00,MONSAT
        DEFB 08,50,MONSAT
        DEFB 09,40,MONSAT
        DEFB 10,30,MONSAT
        DEFB 10,40,MONSAT
        DEFB 11,30,MONSAT
        DEFB 12,20,MONSAT
        DEFB 12,50,MONSA2 ; *
        DEFB 13,10,MONSAT
 ; afternoon tue/fri  +5min
        DEFB 14,15,TUEFRI
        DEFB 15,05,TUEFRI
        DEFB 15,55,TUEFRI
        DEFB 16,45,TUEFRI
        DEFB 17,35,TUEFRI
        DEFB 0FFH,0FFH,0FFH ; end tbl
 ;
 ; eventually def spare table item
 ;      DEFS XX
 ;
 ; PRG number > 07 <
 ; morning mon-sat +
 ; afternoon tue  -5min
 ;
 ; morning mon-sat
TTBL07: DEFB 07,55,MONSAT
        DEFB 08,00,MONSAT
        DEFB 08,50,MONSAT
        DEFB 09,40,MONSAT
	DEFB 10,30,MONSAT
        DEFB 10,40,MONSAT
        DEFB 11,30,MONSAT
        DEFB 12,20,MONSAT
        DEFB 12,50,MONSA2 ; *
        DEFB 13,10,MONSAT
 ; afternoon tue  -5min
        DEFB 14,05,TUE
        DEFB 14,55,TUE
	DEFB 15,45,TUE
        DEFB 16,35,TUE
        DEFB 17,25,TUE
        DEFB 0FFH,0FFH,0FFH ; end tbl
 ;
 ; eventually def spare table item
 ;      DEFS XX
 ;
 ; PRG number > 08 <
 ; morning mon-sat +
 ; afternoon fri  -5min
 ;
 ; morning mon-sat
TTBL08: DEFB 07,55,MONSAT
        DEFB 08,00,MONSAT
        DEFB 08,50,MONSAT
        DEFB 09,40,MONSAT
        DEFB 10,30,MONSAT
        DEFB 10,40,MONSAT
        DEFB 11,30,MONSAT
        DEFB 12,20,MONSAT
        DEFB 12,50,MONSA2 ; *
	DEFB 13,10,MONSAT
 ; afternoon fri  -5min
        DEFB 14,05,FRI
        DEFB 14,55,FRI
        DEFB 15,45,FRI
        DEFB 16,35,FRI
        DEFB 17,25,FRI
        DEFB 0FFH,0FFH,0FFH ; end tbl
 ;
 ; eventually def spare table item
 ;      DEFS XX
 ;
 ; PRG number > 09 <
 ; morning mon-sat +
 ; afternoon tue/fri  -5min
 ;
 ; morning mon-sat
TTBL09: DEFB 07,55,MONSAT
        DEFB 08,00,MONSAT
	DEFB 08,50,MONSAT
        DEFB 09,40,MONSAT
        DEFB 10,30,MONSAT
        DEFB 10,40,MONSAT
        DEFB 11,30,MONSAT
        DEFB 12,20,MONSAT
        DEFB 12,50,MONSA2 ; *
        DEFB 13,10,MONSAT
 ; afternoon tue/fri  -5min
        DEFB 14,05,TUEFRI
	DEFB 14,55,TUEFRI
        DEFB 15,45,TUEFRI
	DEFB 16,35,TUEFRI
        DEFB 17,25,TUEFRI
        DEFB 0FFH,0FFH,0FFH ; end tbl
 ;
 ; eventually def spare table item
 ;      DEFS XX
 ;
 ; equates of day constant
 ;      day *SSFTWTM
 ;          *uarheuo
FRI     EQU 10010000B ; only fri
TUE     EQU 10000010B ; only tue
TUEFRI  EQU 10010010B ; tue/fri
MONSAT  EQU 10111111B ; mon-sat
MONSA2  EQU 00111111B ; mon-sat 1/2
 ;
 ; new ring time
 ; full= 6 sec  half= 3 sec
 ;
 ; bit * 0 halfed ring bell tm (2.5)
 ; bit * 1 normal ring bell tm (5sc)
 ; normally is set to 1
 ;

 ;
TABLE:  DEFW TTBL00
        DEFW TTBL01
        DEFW TTBL02
        DEFW TTBL03
	DEFW TTBL04
        DEFW TTBL05
        DEFW TTBL06
        DEFW TTBL07
        DEFW TTBL08
        DEFW TTBL09
 ;      DEFW TTBL10
 ;      DEFW TTBL11
 ;      DEFS 16
 ;