
$XREF
$PL(78) PW(119)
$DEBUG
$SYMBOLS
$NOMOD51

#define CYGNAL_DEBUG  1             // set non-zero for enable of code mode for
                                    // cygnal debug platform.

#if CYGNAL_DEBUG
$include(c8051f200.inc)             ; register definitions compatible
                                    ; with Cygnal C8051F200
#else
$include(REG51FX.INC)               ; register definitions compatible 
                                    ; with standard Intel architecture FX cpu
#endif

;***************************************************
; SETUP THE NAMES OF THE SEGMENTS
;---------------------------------------------------

BITS_SEG    SEGMENT     BIT
DATA_SEG    SEGMENT     DATA
BUFF_SEG    SEGMENT     IDATA
CODE_SEG    SEGMENT     CODE

;***************************************************
; DATA ALLOCATIONS AND BUFFER SPACES
;---------------------------------------------------
;
;
; Variables and buffers
;
        RSEG    BITS_SEG        
TEST_BIT:
        DBIT    1                   ; sample bit declaration
;
        RSEG    DATA_SEG
PREV_VAL:
        DS      1                   ; previously sampled port value
;
BIT0_VAL:
        DS      1                   ; bit 0 of the counters (LSB)
BIT1_VAL:
        DS      1                   ; bit 1 of the counters
BIT2_VAL:
        DS      1                   ; bit 2 of the counters
BIT3_VAL:
        DS      1                   ; bit 3 of the counters
BIT4_VAL:
        DS      1                   ; bit 4 of the counters
BIT5_VAL:
        DS      1                   ; bit 5 of the counters
BIT6_VAL:
        DS      1                   ; bit 6 of the counters
BIT7_VAL:
        DS      1                   ; bit 7 of the counters
;
;
; stack support
;
        RSEG    BUFF_SEG
STACK:
        DS      10                  ; reserve 10 bytes of space

;***************************************************
; INTERRUPT VECTOR DEFINITIONS
;---------------------------------------------------

CSEG    AT      0000H               ; reset vector
        JMP     POWER_UP            ; power-on entry point

CSEG    AT      0003H               ; intr 0 vector
        CLR     EX0                 ; external int 0
        RETI                        ; not used

CSEG    AT      000BH               ; timer 0 vector
        RETI                        ; not used

CSEG    AT      0013H               ; intr 1 vector
        CLR     EX1                 ; external int 1
        RETI                        ; not used

CSEG    AT      001BH               ; timer 1 vector
        RETI                        ; not used

CSEG    AT      0023H               ; UART vector
        RETI                        ; not used

;***************************************************
; BASE OF CODE AREA
;---------------------------------------------------

        RSEG    CODE_SEG    

        USING   0                   ; use register block 0

;***************************************************
; MAIN PROGRAM INITIALIZATION
;---------------------------------------------------

POWER_UP:
        MOV     SP, #STACK          ; set stack pointer

#if CYGNAL_DEBUG
        ; disable watch dog timer
        MOV     WDTCN, #0DEh        ; Disable the WDT. 
        MOV     WDTCN, #0ADh        ; 2nd move to WDTCN must be within 
                                    ; 4 clocks of first so watch IRQs
        ; Configure the PRTnMX Registers
        MOV     PRT0MX, #005h       ; PRT0MX: Initial Reset Value
                                    ; bit 2="1" enables /INT0 pin
                                    ; bit 0="1" enables TxD and RxD pins
        MOV     PRT1MX, #000h       ; PRT1MX: Initial Reset Value
        MOV     PRT2MX, #000h       ; PRT2MX: Initial Reset Value

        ; Select Pin I/0
        ; Port configuration (1 = Push Pull Output)
        MOV     PRT0CF, #001h       ; Output configuration for P0
                                    ; bit 0="1" enables TxD pin as push pull output
        MOV     PRT1CF, #000h       ; Output configuration for P1 
        MOV     PRT2CF, #000h       ; Output configuration for P2 
        MOV     PRT3CF, #000h       ; Output configuration for P3 

        MOV     P0MODE, #0FFh       ; Input Configuration for P0
        MOV     P1MODE, #0FFh       ; Input Configuration for P1
        MOV     P2MODE, #0FFh       ; Input Configuration for P2
        MOV     P3MODE, #0FFh       ; Input Configuration for P3

        ; enable the external oscillator
        MOV     OSCXCN, #067h       ; External Oscillator Control Register  
        CLR     A
        DJNZ    ACC, $              ; wait for
        DJNZ    ACC, $              ; at least 1ms

OX_WAIT:
        MOV     A, OSCXCN
        JNB     ACC.7, OX_WAIT      ; poll XTLVLD
;
        MOV     A, OSCICN           ; Internal Oscillator Control Register
        SETB    ACC.3               ; set for external clock to be used
        MOV     OSCICN, A

        CLR     A
        MOV     CKCON, A            ; ensure timers T0, T1 & T2 run with /12 clocks

#endif
;
;
; main loop to poll 8 inouts from a port (P3) and increment counters for
; inputs that have a change in the input state. The counters are implemented
; as vertical bit slices in a series of 8 bytes.
;
; The main loop uses the B register to hold the edge detect and carry bits
; during the computational algorithm.
;
        MOV     A, P3               ; initialize the initial NOT prev_val
        CPL     A
        MOV     PREV_VAL, A     
MAIN_LOOP:                          ; main processing task
        ; edge detect logic
        MOV     B, P3               ; get the port value
        MOV     A, PREV_VAL
        ANL     A, B                ; edge bits
        XCH     A, B                ; save edge bits to B and get port_val to A
        CPL     A                   ; save NOT port bits to prev_val
        MOV     PREV_VAL, A
;
; perform bit serial increments into the vertical counters
;
        MOV     A, BIT0_VAL         ; compute the next stage carry bits
        ANL     A, B                ; ...CYout = BIT * CYin
        XCH     A, B                ; save the new carry and get previous 
        XRL     BIT0_VAL, A         ; compute XOR add for bits 0
;
        MOV     A, BIT1_VAL         ; compute the next stage carry bits
        ANL     A, B                ; ...CYout = BIT * CYin
        XCH     A, B                ; save the new carry and get previous 
        XRL     BIT1_VAL, A         ; compute XOR add for bits 1
;
        MOV     A, BIT2_VAL         ; compute the next stage carry bits
        ANL     A, B                ; ...CYout = BIT * CYin
        XCH     A, B                ; save the new carry and get previous 
        XRL     BIT2_VAL, A         ; compute XOR add for bits 2
;
        MOV     A, BIT3_VAL         ; compute the next stage carry bits
        ANL     A, B                ; ...CYout = BIT * CYin
        XCH     A, B                ; save the new carry and get previous 
        XRL     BIT3_VAL, A         ; compute XOR add for bits 3
;
        MOV     A, BIT4_VAL         ; compute the next stage carry bits
        ANL     A, B                ; ...CYout = BIT * CYin
        XCH     A, B                ; save the new carry and get previous 
        XRL     BIT4_VAL, A         ; compute XOR add for bits 4
;
        MOV     A, BIT5_VAL         ; compute the next stage carry bits
        ANL     A, B                ; ...CYout = BIT * CYin
        XCH     A, B                ; save the new carry and get previous 
        XRL     BIT5_VAL, A         ; compute XOR add for bits 5
;
        MOV     A, BIT6_VAL         ; compute the next stage carry bits
        ANL     A, B                ; ...CYout = BIT * CYin
        XCH     A, B                ; save the new carry and get previous 
        XRL     BIT6_VAL, A         ; compute XOR add for bits 6
;
        MOV     A, BIT7_VAL         ; compute the next stage carry bits
        ANL     A, B                ; ...CYout = BIT * CYin
        XCH     A, B                ; save the new carry and get previous 
        XRL     BIT7_VAL, A         ; compute XOR add for bits 7
;
        SJMP    MAIN_LOOP

;***************************************************
;NAME: BIT_MSK
;   Used to convert a bit number to a byte mask
;   Entry A is the 0-7 bit number
;   Exit A is the bit mask
;---------------------------------------------------

BIT_MSK:
        INC  A
        MOVC    A, @A+PC
        RET
;
        DB      00000001B           ; Bit 0    <-  0
        DB      00000010B           ; Bit 1    <-  1
        DB      00000100B           ; Bit 2    <-  2
        DB      00001000B           ; Bit 3    <-  3
        DB      00010000B           ; Bit 4    <-  4
        DB      00100000B           ; Bit 5    <-  5
        DB      01000000B           ; Bit 6    <-  6
        DB      10000000B           ; Bit 7    <-  7

;***************************************************
;NAME: GET_CNT
;   Used to extract a count value from the vertical
;   counter bytes. 
;   Entry A is the 0-7 counter number
;   Exit A is the counter value
;---------------------------------------------------

GET_CNT:
        CALL    BIT_MSK             ; get bit mask from counter #
        MOV     B, A                ; save mask in B
;
        CLR     A                   ; inital clear accumulate value
        PUSH    ACC     
        MOV     A, BIT0_VAL         
        ANL     A, B
        ADD     A, #0FFH            ; shift bit to carry
        POP     ACC
        RRC     A
;
        PUSH    ACC     
        MOV     A, BIT1_VAL         
        ANL     A, B
        ADD     A, #0FFH            ; shift bit to carry
        POP     ACC
        RRC     A
;
        PUSH    ACC     
        MOV     A, BIT2_VAL         
        ANL     A, B
        ADD     A, #0FFH            ; shift bit to carry
        POP     ACC
        RRC     A
;
        PUSH    ACC     
        MOV     A, BIT3_VAL         
        ANL     A, B
        ADD     A, #0FFH            ; shift bit to carry
        POP     ACC
        RRC     A
;
        PUSH    ACC     
        MOV     A, BIT4_VAL         
        ANL     A, B
        ADD     A, #0FFH            ; shift bit to carry
        POP     ACC
        RRC     A
;
        PUSH    ACC     
        MOV     A, BIT5_VAL         
        ANL     A, B
        ADD     A, #0FFH            ; shift bit to carry
        POP     ACC
        RRC     A
;
        PUSH    ACC     
        MOV     A, BIT6_VAL         
        ANL     A, B
        ADD     A, #0FFH            ; shift bit to carry
        POP     ACC
        RRC     A
;
        PUSH    ACC     
        MOV     A, BIT7_VAL         
        ANL     A, B
        ADD     A, #0FFH            ; shift bit to carry
        POP     ACC
        RRC     A
;
        RET                 
;
        END
