Clock Module
This module controls the real time clock, audio signals, and the indicator lamp. C_update is called every millisecond via an interrupt, and controls the real time clock, the menu timer "menutime", and the password timeout "PW_timer". If PW_timer is either 0 or FF, it is not decremented.
The audio and visual indicator handlers are very similar to each other. There are a number of different modes defined in an array for each. Each mode consists of eight different codes corresponding to an audio frequency or light on/off state, and the sequence to change to when the current sequence is completed. Every 0.25 seconds the driver is called via the timer and the next sound or light code in the sequence is activated.
Download:
; ///////////////////////////////////////////////////////////
; // Clock module
; // (c) 1999 Geoff Knagge, Andrew Carr, Mark Lynn
; // last modified : 22/10/1999
; //
; ///////////////////////////////////////////////////////////
c_mlsec: .word 0
c_sec: .byte 0
c_mins:
c_min: .byte 0
c_hours:
c_hour: .byte 0D
ccaatt:.byte 0
;c_ascii: .ascii "00:00.00"
;//////////////// audio driver
au_modes: ; bytes 1-8 = sounds 1-8, byte 9 = next mode
; 0FF = silence, 00=500Hz, 01=1KHz, etc
.byte 0FF,0FF,0FF,0FF,0FF,0FF,0FF,0FF,000; mode 0 - silence
.byte 000,0FF,000,0FF,000,0FF,000,0FF,001 ; mode 1 - 500Hz, 0.5Sec
.byte 001,0FF,001,0FF,001,0FF,001,0FF,002 ; mode 2 - 1KHz, 0.5Sec
.byte 002,0FF,002,0FF,002,0FF,002,0FF,003 ; mode 3 - 2KHz, 0.5Sec
.byte 003,0FF,003,0FF,003,0FF,003,0FF,004 ; mode 4 - 4KHz, 0.5Sec
.byte 004,004,004,004,004,004,004,004
al3tm: .byte 000 ; mode 5 - 3KHz, 2 Sec
.byte 003,004,003,004,003,004,003,004,006 ; mode 6
.byte 004,0FF,0FF,0FF,0FF,0FF,0FF,0FF,007 ; mode 7
.byte 4,4,4,4,4,4,4,4,8
.byte 4,4,0,0,4,4,0,0,9
AL_panic = 09
AL_smoke = 06
AL_zone = 08
AL_time = 07
AL_3times = 05
au_setting: .byte 0
au_cnt: .byte 0
au_mode: ; input c= mode
push af
mov a,c
sta au_setting
mvi a,0
sta au_cnt
pop af
ret
au_next:
push hl
push de
push af
push bc
lda au_cnt
mov d,a ; d = count
lda au_setting
mov c,a ; c = mode number
mvi b,0
lxi hl,au_modes
dad bc
dad bc
dad bc
dad bc
dad bc
dad bc
dad bc
dad bc
dad bc ; HL = HL + 9 * C
mov c,d ; c = count
dad bc ; HL = HL + count
mov e,m ; e should hold the right code
mov a,c
inr a ; increment the counter
inx hl
mov c,m ; if counter too high, c will be next mode
sta au_cnt ; save counter
cpi 08 ; is it too high?
jnz aun3
call au_mode ; if so, set next mode
aun3: mov a,e
cpi 0FF
jnz aun2
call nosound ; if code was FF, no sound
jmp aun1
aun2: call setsound ; if not, set that sound
aun1: pop bc
pop af
pop de
pop hl
ret
;////////////////
bl_modes: ; bytes 1-8 = status, byte 9 = next mode
; 00 = off, FF=on,
.byte 000,000,000,000,000,000,000,000, 0; mode 1
.byte 0FF,0FF,0FF,0FF,0FF,0FF,0FF,0FF, 1; mode 0
.byte 000,000,000,000,0F0,0F0,0F0,0F0, 2; mode 2
.byte 0F0,0F0,000,000,0F0,0F0,000,000, 3; mode 3
.byte 0F0,000,0F0,000,0F0,000,0F0,000, 4; mode 4
.byte 0FF,0FF,0FF,0FF,0FF,0FF,0FF,0FF, 0; mode 5
.byte 0F0,0F0,0F0,0F0,000,000,000,000, 0; mode 6
.byte 0F0,0F0,000,000,000,000,000,000, 0; mode 7
.byte 0F0,000,000,000,000,000,000,000, 0; mode 8
FL_panic = 04
FL_smoke = 04
FL_zone = 04
FL_time = 03
bl_setting: .byte 0
bl_cnt: .byte 0
bl_mode: ; input c= mode
push af
mov a,c
sta bl_setting
mvi a,0
sta bl_cnt
pop af
ret
bl_next:
push hl
push de
push af
push bc
lxi hl,bl_cnt
mov d,m ; d = count
lxi hl,bl_setting
mov c,m ; c = mode number
mvi b,0
lxi hl,bl_modes ; HL = mode table
dad bc
dad bc
dad bc
dad bc
dad bc
dad bc
dad bc
dad bc
dad bc ; HL = HL + 9 * C
mov c,d ; c = count
dad bc ; HL = HL + count
mov e,m ; e should hold the right code
mov a,c
inr a ; increment the counter
inx hl
mov c,m ; if counter too high, c will be next mode
sta bl_cnt ; save counter
cpi 08 ; is it too high?
cz bl_mode ; if so, set next mode
mov a,e
xri 0FF ; invert bits
call io_WtID
pop bc
pop af
pop de
pop hl
ret
;////////////////
c_quartersec: ; called every 250ms
call au_next
call bl_next
ret
c_refresh:
call c_shhr
call c_shmin
call c_shsec
ret
c_update:
Lhld c_mlsec ; load HL with the miliseconds count
Inx HL ; increment it
Shld c_mlsec ; save it
Mov A,H
cpi 00 ; compare HL with 00FA (250 decimal)
Jnz c_d1
Mov A,L
cpi 0FA
Jnz c_d1
call c_quartersec
jmp c_exit
c_d1: Mov A,H
cpi 02 ; compare HL with 02EE (750 decimal)
Jnz c_d2
Mov A,L
cpi 0EE
Jnz c_d2
call c_quartersec
jmp c_exit
c_d2: Mov A,H
cpi 01 ; compare HL with 01F4 (500 decimal)
Jnz c_j1
Mov A,L
cpi 0F4
Jnz c_j1
call c_tcolon ; if milliseconds = 500
jmp c_exit
c_j1: ; compare milliseconds to 1000
Mov A,H
cpi 3
Jnz c_exit
Mov A,L
cpi 0E8
Jnz c_exit
mvi H,0
mvi L,0
Shld c_mlsec ; resets milliseconds to 0
call c_incsec
c_exit: ret
c_incsec:
push HL
push Af
call c_pcolon
Lxi HL, c_sec
Mov A,M
inr A ; increment seconds
cpi 3C ; compare with 60 seconds = 1 minute
Jnz c_j3
call c_incmin ; increment minutes
mvi A,0 ; reset seconds
c_j3: mov M,A
call c_shsec
;///////////// Decrement password timeout counter
lxi hl,PW_timer
mov a,m
cpi 00
jz c_j9
cpi 0FF
jz c_j9
dcr a
mov m,a
c_j9: ;////////////// increment menu counter
lda menutime
inr a
sta menutime
;//////////////
pop Af
pop HL
ret
c_incmin:
push HL
push Af
mvi a,1
sta ccaatt ; tell auto armer to do new check
Lxi HL, c_min
Mov A,M
inr A ; increment minutes
cpi 3C ; compare with 60 minutes = 1 hour
Jnz c_j4
call c_inchr ; increment hours
mvi A,0 ; reset minutes
c_j4: mov M,A
call c_shmin
pop Af
pop HL
ret
c_inchr:
push HL
push Af
Lxi HL, c_hour
Mov A,M
inr A ; increment hours
cpi 18 ; compare with 24 hours = 1 day
Jnz c_j5
mvi A,0 ; reset minutes
c_j5: mov M,A
call c_shhr
pop Af
pop HL
ret
c_tcolon: ; take away colon
push HL
push Af
call c_quartersec
Lxi HL, c_ascii
inx HL
inx HL ;now points to colon
mvi A,20 ;20H = ascii for space
mov M,A
call LCD_reset
pop Af
pop HL
ret
c_pcolon: ; put colon in
push HL
push Af
call c_quartersec
Lxi HL, c_ascii
inx HL
inx HL ;now points to colon
mvi A,3A ;3A = ascii for colon
mov M,A
call LCD_reset
pop Af
pop HL
ret
c_decode: ; input : A=number, HL=address to store at
push af
push bc
push hl
mvi b,0 ; b= counter of 10's
c_dj1: inr b
sui 0A
jnc c_dj1
dcr b ; b holds number of 10's, a holds number of 1's
adi 3A ; add ascii code for 0 to A
mov c,a ; c holds 1's
mov a,b
adi 30 ; add ascii code for 0 to A
mov m,a ; store 10's
inx hl
mov m,c; store 1's
pop hl
pop bc
pop af
ret
c_shsec:
push af
push hl
lxi hl,c_sec
mov a,m
lxi hl,c_ascii
inx hl
inx hl
inx hl
inx hl
inx hl
inx hl
call c_decode
pop hl
pop af
ret
c_shmin:
push af
push hl
lxi hl,c_min
mov a,m
lxi hl,c_ascii
inx hl
inx hl
inx hl
call c_decode
pop hl
pop af
ret
c_shhr:
push af
push hl
lxi hl,c_hour
mov a,m
lxi hl,c_ascii
call c_decode
pop hl
pop af
ret
|