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

This is page designed, maintained and
(C)opyright 1999 by Geoff Knagge