 

; some global variables 
BITS_STATUS EQU 0x20 ; bits` process statuses 
; delay counters 
BIT0_DELAY  EQU 0x21 
BIT1_DELAY  EQU 0x22 
BIT2_DELAY  EQU 0x23 
BIT3_DELAY  EQU 0x24 
BIT4_DELAY  EQU 0x25 
BIT5_DELAY  EQU 0x26 
BIT6_DELAY  EQU 0x27 
BIT7_DELAY  EQU 0x28 

START: 
; initialize all delays to base scan values (BITx_DELAY) 
; clear all bits` statuses (BITS_STATUS) 
  CALL INIT_BIT_PROC
;
MAIN_LOOP: 
; wait for timer quanta (via timer or simple DJNZ loops for needed time)
  CALL WAIT_QUANTA
;
  MOV R7,#0           ; process bits from 0... 
NEXT_BIT: 
  CALL PROCESS_BIT 
  INC  R7 
  CJNE R7,#8,NEXT_BIT ; ...to 7 
; ... 

; bit processor 
; R7 - bit number 
PROCESS_BIT: 
; locate corresponded structure 
  MOV DPTR,#BITS_LOOKUP 
  MOV  A,R7 
  ADD  A,R7 
  ADD  A,DPL 
  MOV  DPL,A 
  JNC  PROCESS_BIT_0 
  INC  DPH 
PROCESS_BIT_0: 
; get descriptor pointer into DPTR 
  MOV  A,#1 
  MOVC A,@A+DPTR ; low byte of its address 
  PUSH ACC 
  CLR  A 
  MOVC A,@A+DPTR ; high byte 
  MOV  DPH,A 
  POP  DPL 
; now DPTR contains the address of bit process descriptor - let start to process 
; a) check if delay done 
  MOV  A,#1 
  MOVC A,@A+DPTR ; delay holder address 
  MOV  R0,A 
  MOV  A,@R0 ; delay value 
  DEC  A 
  JZ   PROCESS_BIT_1 
; still need to wait: 
  MOV  @R0,A 
  RET 
PROCESS_BIT_1: 
b) check real bit state in port 
  CLR  A 
  MOVC A,@A+DPTR 
  MOV  R1,A ; bit mask 
  ANL  A,P2 ; check bit state in port 
  MOV  C,P ; c is equ bit state 
; c) process bit state depending on process status 
  MOV  A,R1 
  ANL  A,BITS_STATUS 
  JNZ  PROCESS_BIT_R ; state: repeat_scan... 
; state: initial_scan 
  JNC  PROCESS_BIT_L ; low level detected... 
; still in high state: reload initial scan delay 
  MOV  @R0,#1 ; check bit again at next cycle 
  RET 

PROCESS_BIT_L: 
; first_low_state detected
; - change process status
  MOV  A,R1
  ORL  BITS_STATUS,A ; set status (repeat scan)
; - change delay value
  MOV  @R0,#DELAY_5_SEC ; depends on time quanta
; - send data byte via P1
  MOV  A,#2
  MOVC A,@A+DPTR  ; first_low_state
  MOV  P1,A  
  RET

PROCESS_BIT_R: 
; state: repeat_scan
  JNC  PROCESS_BIT_H ; back-to-high level detected...
; continue_low_state detected:
; - keep delay value
  MOV  @R0,#DELAY_5_SEC
; - send data byte via P1
  MOV  A,#3
  MOVC A,@A+DPTR  ; continue_low_state
  MOV  P1,A
  RET

PROCESS_BIT_H:
; back-to-high level detected:
; - restore process status
  MOV  A,R1
  CPL  A
  ANL  BITS_STATUS,A ; reset status (initial scan)
; - restore delay value
  MOV  @R0,#1
; - send data byte via P1
  MOV  A,#4
  MOVC A,@A+DPTR  ; back_to_high_state
  MOV  P1,A
  RET

; ...
; ...
; ...

; structure for process bit 0: 
BIT0_DESCRIPTOR: 
    DB 00000001b      ; mask for both input port and process status 
    DB BIT0_TIMER     ; delay holder address
    DB 0xA0,0xB0,0xC0 ; data to be sent

; structure for process bit 1: 
BIT1_DESCRIPTOR: 
    DB 00000010b
    DB BIT1_TIMER
    DB 0xA1,0xB1,0xC1  

; etc  for rest bits you need to control
; .... 

; common table of all descriptors` addresses
BITS_LOOKUP: 
    DW BIT0_DESCRIPTOR 
    DW BIT1_DESCRIPTOR 
    DW BIT2_DESCRIPTOR 
    DW BIT3_DESCRIPTOR 
    DW BIT4_DESCRIPTOR 
    DW BIT5_DESCRIPTOR 
    DW BIT6_DESCRIPTOR 
    DW BIT7_DESCRIPTOR 
