ORG 00007H
; disable external interrupt
DIS I ; 0007
; disable timer/counter interrupt
DIS TCNTI ; 0008
; select memory bank 0 and register bank 0
SEL MB0 ; 0009
SEL RB0 ; 000A
; set R2, R3, R4, R6, R7 to 0x00
CLR A ; 000B
MOV R2,A ; 000C
MOV R3,A ; 000D
MOV R4,A ; 000E
MOV R6,A ; 000F
MOV R7,A ; 0010
; set R1, R5 to 0xFF
DEC A ; 0011
MOV R1,A ; 0012
MOV R5,A ; 0013
; clear flags and complement F1
CLR F0 ; 0014
CLR F1 ; 0015
CPL F1 ; 0016
; clear external ports
OUTL P1,A ; 0017
OUTL P2,A ; 0018
; initialize timer to 0xFA and start it
; timer runs at 7.457 kHz, this timer run will expire (overflow) in 6 cycles
; that is 0.8 ms
STRT T ; 0019
MOV A,#0FAH ; 001A
MOV T,A ; 001C
; 0xBF = clear P2.6
ANL P2,#0BFH ; 001D
; if F0 is set, enable P2.7 (will not happen on the first run)
JF0 0025H ; 001F
ORL P2,#080H ; 0021
JMP 029H ; 0023
; otherwise disable P2.7 and enable P2.6
ANL P2,#07FH ; 0025
ORL P2,#040H ; 0029
;;;;;;;;;;;;;;
;; this section detects if any of P1.0, P1.1, P1.2 changed their state and kept
;; it changed for around 10ms
; check if R7 is zero (will be at first run)
MOV A,R7 ; 002B
ANL A,#0FFH ; 002C
JNZ 003BH ; 002E
; if R7 is zero: if any of P1.0, P1.1, P1.2 is zero on first run or
; changed their value from the previous check
; remember which one in R2 and set R7 to 12
IN A,P1 ; 0030
XRL A,R1 ; 0031
ANL A,#007H ; 0032
JZ 0045H ; 0034
MOV R2,A ; 0036
MOV R7,#00CH ; 0037
JMP 045H ; 0039
; decrement R7, if went down to zero check if P1.0, P1.1 or P1.2
; still have the changed values, if yes store the new values in R1 and clear F1
DJNZ R7,0045H ; 003B
IN A,P1 ; 003D
XRL A,R1 ; 003E
ANL A,R2 ; 003F
JZ 0045H ; 0040
XRL A,R1 ; 0042
MOV R1,A ; 0043
CLR F1 ; 0044
; F1=0 if such event happened
;;;;;;;;;;;;;;;;
; check if P1.4 or P1.5 changed their values
IN A,P1 ; 0045
XRL A,R1 ; 0046
ANL A,#030H ; 0047
JZ 0062H ; 0049
; if yes, set F1 to 0 immediately
CLR F1 ; 004B
; restore A to P1 value
XRL A,R1 ; 004C
; replace A and R1: R1=P1 value, A=previous P1 (PP1)
XCH A,R1 ; 004D
; PP1 >> 2
RR A ; 004E
RR A ; 004F
ANL A,#00CH ; 0050
MOV R0,A ; 0052
MOV A,R1 ; 0053
; R0.3=PP1.5 R0.2=PP1.4 (rest is 0)
; here A contains P1 value again
SWAP A ; 0054
; keep only P1.4 and P1.5 on bits 0,1
ANL A,#003H ; 0055
; now we have on one nibble previous and current value of bits:
; A3-0 = PP1.5,PP1.4,P1.5,P1.4
ORL A,R0 ; 0057
; now it is 0xF(PP1.5,PP1.4,P1.5,P1.4)
ORL A,#0F0H ; 0058
MOVP A,@A ; 005A
; read a value from memory depending on previous and current values of P1.5,P1.4
; +-------+-------+------+------+-----+-----+
; | PP1.5 | PP1.4 | P1.5 | P1.4 | ADR | VAL |
; +-------+-------+------+------+-----+-----+
; | 0 | 0 | 0 | 0 | 0x0 | 0A | 1010
; | 0 | 0 | 1 | 1 | 0x3 | 0A |
; | 0 | 1 | 0 | 1 | 0x5 | 0A |
; | 0 | 1 | 1 | 0 | 0x6 | 0A |
; | 1 | 0 | 0 | 1 | 0x9 | 0A |
; | 1 | 0 | 1 | 0 | 0xA | 0A |
; | 1 | 1 | 0 | 0 | 0xC | 0A |
; | 1 | 1 | 1 | 1 | 0xF | 0A |
; 0A - both bits behave in the same way - both change or both stay the same
; it may be interpreted as P1.5 and P1.4 are in phase sync
; +-------+-------+------+------+-----+-----+
; | PP1.5 | PP1.4 | P1.5 | P1.4 | ADR | VAL |
; +-------+-------+------+------+-----+-----+
; | 0 | 0 | 0 | 1 | 0x1 | 05 | 0101
; | 0 | 1 | 1 | 1 | 0x7 | 05 |
; | 1 | 0 | 0 | 0 | 0x8 | 05 |
; | 1 | 1 | 1 | 0 | 0xE | 05 |
; 05 - P1.5 is lagging behind P1.4
; | 0 | 1 | 0 | 0 | 0x4 | 00 |
; | 0 | 0 | 1 | 0 | 0x2 | 00 | 0000
; | 1 | 1 | 0 | 1 | 0xD | 00 |
; | 1 | 0 | 1 | 1 | 0xB | 00 |
; 00 - P1.4 is lagging behind P1.5
; for 0x05 increment R3
; for 0x00 decrement R3
JB1 0062H ; 005B
INC R3 ; 005D
JB0 0062H ; 005E
DEC R3 ; 0060
DEC R3 ; 0061
;;;;;;;;;;;;;;;;;;
;; now similar with P1.6 and P1.7
IN A,P1 ; 0062
XRL A,R1 ; 0063
ANL A,#0C0H ; 0064
JZ 007FH ; 0066
CLR F1 ; 0068
; restore P1 value and store current P1 in R1 and previous P1 value in A
XRL A,R1 ; 0069
XCH A,R1 ; 006A
; shift previous P1.6 and P1.7 values to bits 2 and 3
SWAP A ; 006B
ANL A,#00CH ; 006C
; A.3=PP1.7
; A.2=PP1.6
; A.1=P1.7
; A.0=P1.6
MOV R0,A ; 006E
MOV A,R1 ; 006F
RL A ; 0070
RL A ; 0071
ANL A,#003H ; 0072
ORL A,R0 ; 0074
; read from the table value one of 0,A,5, rules are same as with
; P1.4 and P1.5
ORL A,#0F0H ; 0075
MOVP A,@A ; 0077
; for 0x05 increment R4
; for 0x00 decrement R4
JB3 007FH ; 0078
INC R4 ; 007A
JB2 007FH ; 007B
DEC R4 ; 007D
DEC R4 ; 007E
;;;;;;;;;;;;;;
; R3 value represents the phase direction of P1.4 and P1.5
; R4 value represents the phase direction of P1.6 and P1.7
; if R6 bits 0-3 non-zero, decrease R6 and rotate right R5 filling bit 7 with 1
; if R5 bit 0 was 0, set F0 - this will cause to emit signal on P2.7
; this actually sends on P2.7 a bit signal of length R6 (4 lower bits) coded on R5
; if this sending is executed, the rest of the loop is omitted until all bits are sent
MOV A,R6 ; 007F
ANL A,#00FH ; 0080
JZ 0090H ; 0082
DEC R6 ; 0084
CLR C ; 0085
CPL C ; 0086
MOV A,R5 ; 0087
RRC A ; 0088
MOV R5,A ; 0089
CLR F0 ; 008A
JC 00BBH ; 008B
CPL F0 ; 008D
JMP 0BBH ; 008E
; put 0xC (12) to R6 (count of bits to transmit) and set F0 to not send signal on P2.7
MOV A,R6 ; 0090
ORL A,#00CH ; 0091
MOV R6,A ; 0093
CLR F0 ; 0094
; check higher 4 bits of R6, if they are zero and F1 is set (happened event
; indicating move on P1.4/5 or P1.6/7 or push on P1.0/1/2) set R6 to 0x5*
; and move previous stored P1.0/1/2 to A, additionally set A.7. A will get
; transmitted as R5 later
ANL A,#0F0H ; 0095
JNZ 00A7H ; 0097
JF1 00BBH ; 0099
CPL F1 ; 009B
MOV A,R6 ; 009C
ORL A,#050H ; 009D
MOV R6,A ; 009F
MOV A,R1 ; 00A0
ANL A,#007H ; 00A1
ORL A,#080H ; 00A3
JMP 0B9H ; 00A5
; this decreases 4 higher bits of R6 (starting from 0x5* to 0x0* - 4 iterations)
MOV R5,#0FFH ; 00A7
MOV A,R6 ; 00A9
ADD A,#0F0H ; 00AA
MOV R6,A ; 00AC
ANL A,#0F0H ; 00AD
JZ 00BBH ; 00AF
; at odd iterations transmit R4, at even iterations transmit R3
JB4 00B7H ; 00B1
CLR A ; 00B3
XCH A,R3 ; 00B4
JMP 0B9H ; 00B5
CLR A ; 00B7
XCH A,R4 ; 00B8
; store bit message in R5
CPL F0 ; 00B9
MOV R5,A ; 00BA
; wait for timer to expire - delay
JTF 001AH ; 00BB
JMP 0BBH ; 00BD
ORG 000F0H
data 0A05000A 000A0A05 050A0A00 0A00050A
END