; 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
;
-
-
-
THINK MAN/WOMAN THINK BEFORE DO IT .../FONT>
-