The Security Module

The module that calculates which doors and windows should be considered secured and/or locked, and handles zone locking and settings. The conditions for things becoming secure is described in the alarms module. A summary of the routine inputs/outputs for this module are found here or downloaded in Lotus Wordpro 97 format here (50KB)

The recalculate procedure initially tries to secure all zones, doors, and windows. Any unlocked door which connects to the outside is not able to be secured. The procedure then checks all doors, and if a door is in its insecure state, and one of zones on either side of it is secure, then that zone becomes insecure. Consequently, all unlocked doors and windows in that zone also become insecure. This is repeated until all doors are checked without any changes being made.

Download:
; ///////////////////////////////////////////////////////////// ; // Security Module ; // (c) 1999 Geoff Knagge, Andrew Carr, Mark Lynn ; // last modified : 22/10/1999 ; // ; ///////////////////////////////////////////////////////////// ZoneData: ; +--------- bit 7= secure ; |+-------- bit 6= indicator for codes ; ||+------- bit 5= max window security ; ||| +-- bit 0= locked ; ||| | .byte 01100000# ; Zone 1 .byte 01100000# ; Zone 2 .byte 01100000# ; Zone 3 .byte 01100000# ; Zone 4 .byte 01100000# ; Zone 5 .byte 01100000# ; Zone 6 .byte 01100000# ; Zone 7 .byte 01100000# ; Zone 8 .byte 01100000# ; Zone 9 - outside .byte 01100000# ; Zone 10- outside SZ_unsecure: ; input A = zone cpi outZone jz SZ_uj3 push hl push af push de push bc mov e,A ;///////// For all doors, ; if (not locked) ; and (connected to zone) ; unsecure door mvi b,0 mvi c,0 SZuL1: call SDgLock cpi 0 jz SZuJ1 ; zero means locked call SDgCtZone cmp e jz SZuJ2 ; this is the controlling zone call SDgCnZone cmp e jnz SZuJ1 ; not connected to zone SZuJ2: ; we get here if the door is in the zone call SD_unsecure SZuJ1: inx bc ; next door mvi a,8 ; too many doors? cmp c jnz SZuL1 ; no, go and check it. ;/////////// End of "For all Doors" loop lxi hl,ZoneData ; point to zone status array mov c,e dad bc ; move to right cell mov a,m ; load status bit ani 7F ; clear secure bit mov m,a ; save status bit pop bc pop de pop af pop hl SZ_uj3: ret SZ_lock: ; input A = zone push hl push af push de push bc mov e,a ;///////// For all doors, ; if controlled by zone ; lock door mvi b,0 mvi c,0 SZaL1: call SDgCtZone cmp e ; is the door controlled by this zone jnz SZaJ1 ; no call SD_relock ; yes, lock it... lock it good! SZaJ1: inx bc ; next door mvi a,8 ; too many doors? cmp c jnz SZaL1 ; no, go and check it. ;/////////// End of "For all Doors" loop lxi hl,ZoneData ; point to zone status array mov c,e dad bc ; move to right cell mov a,m ; load status byte ori 01 ; set Locked bit mov m,a ; save status byte pop bc pop de pop af pop hl ret SZglock: ; input A = zone; output A=status push hl push bc lxi hl,ZoneData ; point to zone status array mov c,a dad bc ; move to right cell mov a,m ; load status byte ani 01 pop bc pop hl ret SZgMaxSecure: ; input A = zone; output A=status push hl push bc lxi hl,ZoneData ; point to zone status array mov c,a dad bc ; move to right cell mov a,m ; load status byte ani 20 pop bc pop hl ret SZ_MaxSecure: ; input A = zone; push hl push bc push af lxi hl,ZoneData ; point to zone status array mov c,a dad bc ; move to right cell mov a,m ; load status byte ori 20 ; set bit 5 mov m,a pop af pop bc pop hl ret SZ_MinSecure: ; input A = zone; push hl push bc push af lxi hl,ZoneData ; point to zone status array mov c,a dad bc ; move to right cell mov a,m ; load status byte ani 0DF ; clear bit 5 mov m,a pop af pop bc pop hl ret SZgindicator: ; input A = zone; output A=status push hl push bc lxi hl,ZoneData ; point to zone status array mov c,a dad bc ; move to right cell mov a,m ; load status byte ani 40 pop bc pop hl ret SZ_unlock: ; input A = zone push hl push af push de push bc mov e,a ;///////// For all doors, ; if controlled by zone ; unlock door mvi b,0 mvi c,0 SZbL1: call SDgCtZone cmp e ; is the door controlled by this zone jnz SZbJ1 ; no call SD_unlock ; yes, lock it... lock it good! SZbJ1: inx bc ; next door mvi a,8 ; too many doors? cmp c jnz SZbL1 ; no, go and check it. ;/////////// End of "For all Doors" loop lxi hl,ZoneData ; point to zone status array mov c,e dad bc ; move to right cell mov a,m ; load status byte ani 0FE ; clear Locked bit mov m,a ; save status byte pop bc pop de pop af call sz_unsecure pop hl ret SZ_secure: ; secures a zone. input C=zone push bc push hl push af mvi b,0 lxi hl,ZoneData ;point to zone status aray dad bc ;point to right zone mov a,m ;load zone stat byte ori 80 ;set secure bit mov m,a ;save zone status pop af pop hl pop bc ret SZgsecure: ; gets a zones secure status. input A=zone ; output A=stat push bc push hl mov c,a mvi b,0 lxi hl,ZoneData ;point to zone status aray dad bc ;point to right zone mov a,m ;load zone stat byte ani 80 pop hl pop bc ret recalculate: call SD_read ; get hardware stati call SW_read ; get hardware stati ;////////////// Try to secure all zones, doors, windows mvi c,0 mvi b,0 rc_L1: call SZ_secure ; secure zone C call SDglock ; is door locked cpi 0 jz rccl5 ; yes, automatically try to secure it call SDgCtZone ; get door's controlling zone cpi outzone ; an unlocked door connecting jz rccl4 ; to the outside is always unsecure call SDgCnZone ; get door's connecting zone cpi outzone ; an unlocked door connecting jz rccl4 ; to the outside is always unsecure rccl5: call SD_T2Secure; try to secure door C. we get here if ; the door is either unlocked or internal rccl4: call SW_T2Secure; try to secure window C inx bc ; next zone, door and window mvi a,8 ; have we counted too high? cmp c jnz rc_L1 ; no go back and do the next rc_L2: mvi e,0 ; clear "changed" flag ;//////////////////// Start of loop mvi c,0 ; for doors = 0 to 7 rc_L3: call SDgSecure ; is door secure? cpi 0 jnz rc_J1 ; yes, it won't change much... mvi d,0 ; D counts connected, secure zones call SDgCtZone ; get controlling zone in A call SZgSecure ; is this zone secure? cpi 0 jz rc_J2 ; no inr d ; yes, increment counter rc_j2: call SDgCnZone ; get connecting zone in A call SZgSecure ; is it secure? cpi 0 jz rc_J3 ; no inr d ; yes, increment counter rc_j3: mov a,d ; a = counter cpi 1 ; is it exactly 1? jnz rc_j1 ; no, don't unsecure anything call SDgCnZone ; no, unsecure both zones CALL SZ_unsecure; (input: A = zone) call SDgCtZone call SZ_unsecure mvi e,0FF ; set changed flag rc_J1: inx bc ; increment loop counter mvi a,8 cmp c ; have we counter too high jnz rc_L3 ; no, another pass needed... ;//////////////////// End of loop mvi a,0FF cmp e ; is changed flag set? jz rc_L2 ; yes, we need another pass ;////////////// Now go and unsecure eligible windows mvi c,0 ; for windows = 0 to 7 rc_L4: call SWgCtZone ; get Window's controlling zone mov e,a ; E = controlling zone call SZgSecure ; is zone secure? cpi 0 jnz rc_J4 ; yes, window shall stay secure... mov a,e call SZgLock ; is zone locked? cpi 0 jz rc_J5 ; no, so the window shan't be secured mov a,e call SZgMaxSecure; is maxsecure bit set? cpi 0 jnz rc_J4 ; yes, window stays as it is rc_J5: ; // we get here if (the zone is insecure) and ; ((zone is unlocked) or (!maxsecure)) call SW_unsecure; Window is hereby unsecured... rc_J4: inx bc ; increment loop counter mvi a,8 cmp c ; have we counter too high jnz rc_L4 ; no, another pass needed... ret ;///////////////////////////////////// ala_on: push hl push af mvi a,0 lxi hl,alar_stat mov m,a pop af pop hl ret ala_off: push hl push af mvi a,1 lxi hl,alar_stat mov m,a pop af pop hl ret ;///////////////////////////////////// .imprt "doors.asm" .imprt "windows.asm"

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