Загрузка данных
; Laboratory 3, variant 24_26. Keil A51 / NXP 80C552.
; CW at X:7FFA = 000 i1 i0 j1 j0 op (i,j = 0..3).
; op=0: sort block IDs by descending count of linear zero runs.
; Equal counts keep increasing IDs. First ID occupies result bits 7..6.
; op=1: shift A, injecting one bit per step in the written order.
; Right input: B7,B6,B5,B3 (B3 is literal, NOT silently changed to B4).
;
; Program entry: 8000h. ULS INT0 entry: 8003h.
P4 EQU 0C0H
CONTROL EQU 7FFAH
ARRAY_A EQU 8000H
ARRAY_B EQU 8004H
RESULT DATA 30H
COMMAND DATA 31H
INDEX_A DATA 32H
INDEX_B DATA 33H
OPERAND_A DATA 34H
OPERAND_B DATA 35H
SHIFT_N DATA 36H
PRODUCT_LO DATA 37H
PRODUCT_HI DATA 38H
BLOCKS EQU 40H ; 40h..43h: blocks, low six bits
COUNTS EQU 44H ; 44h..47h: zero-run counts
IDS EQU 48H ; 48h..4Bh: sorted block IDs
TEMP_COUNT DATA 4CH
TEMP_ID DATA 4DH
SHIFT_DIR DATA 4EH ; 0=left, 1=right
ORG 8000H
LJMP START
ORG 8003H
LJMP INT0_HANDLER
ORG 8030H
START:
MOV IE,#00H
MOV SP,#5FH ; stack 60h upward, outside banks/scratch
MOV PSW,#00H ; main program uses register bank 0
MOV RESULT,#00H
MOV P4,#00H
; A = [45h, A5h, 00h, A5h], B = [6Fh, 00h, 01h, 00h]
MOV DPTR,#ARRAY_A
MOV A,#045H
MOVX @DPTR,A
INC DPTR
MOV A,#0A5H
MOVX @DPTR,A
INC DPTR
CLR A
MOVX @DPTR,A
INC DPTR
MOV A,#0A5H
MOVX @DPTR,A
INC DPTR
MOV A,#06FH
MOVX @DPTR,A
INC DPTR
CLR A
MOVX @DPTR,A
INC DPTR
MOV A,#001H
MOVX @DPTR,A
INC DPTR
CLR A
MOVX @DPTR,A
SETB P3.2 ; release INT0 input
SETB IT0 ; falling edge, not low level
CLR IE0
SETB EX0
SETB EA
MAIN_LOOP:
MOV A,RESULT
DISPLAY_WRITE:
MOV P4,A
SJMP MAIN_LOOP
; Save all shared CPU context. Bank 1 is private to the ISR.
; RESULT is an intentional output: never restored from the stack.
INT0_HANDLER:
PUSH ACC
PUSH PSW
PUSH B
PUSH DPL
PUSH DPH
MOV PSW,#08H
MOV DPTR,#CONTROL
MOVX A,@DPTR
ANL A,#01FH
MOV COMMAND,A
RR A
RR A
RR A
ANL A,#03H
MOV INDEX_A,A
ADD A,#LOW ARRAY_A
MOV DPL,A
MOV DPH,#HIGH ARRAY_A
MOVX A,@DPTR
MOV OPERAND_A,A
MOV A,COMMAND
RR A
ANL A,#03H
MOV INDEX_B,A
ADD A,#LOW ARRAY_B
MOV DPL,A
MOV DPH,#HIGH ARRAY_B
MOVX A,@DPTR
MOV OPERAND_B,A
MOV A,COMMAND
JB ACC.0,DO_OPERATION_2
LCALL OPERATION_1
SJMP STORE_RESULT
DO_OPERATION_2:
LCALL OPERATION_2
STORE_RESULT:
MOV RESULT,A ; single publication of finished result
ISR_EXIT:
POP DPH
POP DPL
POP B
POP PSW
POP ACC
RETI
; Build 4 blocks using a ROM bit-position table. Table position 0 means
; A0, position 7 means A7, position 8 means B0, position 15 means B7.
OPERATION_1:
MOV R0,#BLOCKS
MOV R1,#COUNTS
MOV R4,#00H ; next table entry (0..23)
MOV R7,#04H
BUILD_BLOCK:
MOV R5,#00H
MOV R6,#06H
BUILD_BIT:
MOV DPTR,#BIT_POSITIONS
MOV A,R4
MOVC A,@A+DPTR
INC R4
LCALL READ_SOURCE_BIT ; returns source bit in C
MOV A,R5
RLC A
MOV R5,A
DJNZ R6,BUILD_BIT
MOV @R0,A
INC R0
LCALL COUNT_ZERO_RUNS
MOV @R1,A
INC R1
DJNZ R7,BUILD_BLOCK
MOV IDS+0,#00H
MOV IDS+1,#01H
MOV IDS+2,#02H
MOV IDS+3,#03H
MOV R7,#03H ; three bubble-sort passes
SORT_PASS:
MOV R0,#COUNTS
MOV R1,#IDS
MOV A,R7
MOV R6,A
SORT_PAIR:
MOV A,@R0
MOV TEMP_COUNT,A
INC R0
MOV A,@R0
MOV R5,A
CLR C
SUBB A,TEMP_COUNT
JC SORT_NEXT ; right < left: keep
JZ SORT_NEXT ; equal: keep stable order
MOV A,TEMP_COUNT
MOV @R0,A
DEC R0
MOV A,R5
MOV @R0,A
INC R0
MOV A,@R1
MOV TEMP_ID,A
INC R1
MOV A,@R1
DEC R1
MOV @R1,A
INC R1
MOV A,TEMP_ID
MOV @R1,A
DEC R1
SORT_NEXT:
INC R1
DJNZ R6,SORT_PAIR
DJNZ R7,SORT_PASS
MOV R0,#IDS
MOV R6,#04H
CLR A
PACK_ID:
RL A
RL A
ORL A,@R0
INC R0
DJNZ R6,PACK_ID
RET
; Input A=bit position 0..15; preserve R0,R1,R4,R5,R6,R7.
READ_SOURCE_BIT:
MOV R2,A
ANL A,#07H
MOV R3,A
INC R3
MOV A,R2
ANL A,#08H
JZ SOURCE_IS_A
MOV A,OPERAND_B
SJMP EXTRACT_BIT
SOURCE_IS_A:
MOV A,OPERAND_A
EXTRACT_BIT:
RRC A
DJNZ R3,EXTRACT_BIT
RET
; Input A=block in bits 5..0; output A=number of maximal linear zero
; runs. Inspect EXACTLY six bits; high padding bits must not count.
; Working R2=bits, R3=remaining, B=previous bit (initially 1).
COUNT_ZERO_RUNS:
RL A
RL A
MOV R2,A
MOV R3,#06H
MOV B,#01H
CLR A
MOV R5,A
COUNT_NEXT:
MOV A,R2
JNB ACC.7,COUNT_ZERO
MOV B,#01H
SJMP COUNT_ADVANCE
COUNT_ZERO:
MOV A,B
JZ COUNT_ADVANCE
INC R5
MOV B,#00H
COUNT_ADVANCE:
MOV A,R2
RL A
MOV R2,A
DJNZ R3,COUNT_NEXT
MOV A,R5
RET
; Products are unsigned 16-bit. Compare HIGH bytes first, then LOW.
OPERATION_2:
MOV A,INDEX_B
ADD A,#02H
MOV B,A
MOV A,INDEX_A
MUL AB
MOV B,#05H
DIV AB
MOV SHIFT_N,B
MOV SHIFT_DIR,#00H
MOV A,INDEX_B
INC A
MOV B,A
MOV A,OPERAND_A
MUL AB
MOV PRODUCT_LO,A
MOV PRODUCT_HI,B
MOV A,INDEX_A
ADD A,#02H
MOV B,A
MOV A,OPERAND_B
MUL AB
MOV R2,A ; right-hand product, low byte
MOV R3,B ; right-hand product, high byte
MOV A,PRODUCT_HI
CLR C
SUBB A,R3
JC SELECT_RIGHT
JNZ SHIFT_PREPARE
MOV A,PRODUCT_LO
CLR C
SUBB A,R2
JNC SHIFT_PREPARE ; equality selects left
SELECT_RIGHT:
MOV SHIFT_DIR,#01H
SHIFT_PREPARE:
MOV A,SHIFT_N
JZ NO_SHIFT
MOV R7,A
MOV A,OPERAND_A
MOV R5,A
MOV A,SHIFT_DIR
JNZ SHIFT_RIGHT_PREP
MOV A,OPERAND_B
MOV R4,A
SHIFT_LEFT_LOOP:
MOV A,R4
CLR C
RRC A ; next B0,B1,B2,B3 into C
MOV R4,A
MOV A,R5
RLC A
MOV R5,A
DJNZ R7,SHIFT_LEFT_LOOP
RET
SHIFT_RIGHT_PREP:
MOV R4,#00H
SHIFT_RIGHT_LOOP:
MOV DPTR,#RIGHT_POSITIONS
MOV A,R4
MOVC A,@A+DPTR
INC R4
LCALL READ_SOURCE_BIT
MOV A,R5
RRC A
MOV R5,A
DJNZ R7,SHIFT_RIGHT_LOOP
RET
NO_SHIFT:
MOV A,OPERAND_A
RET
BIT_POSITIONS:
DB 7,15,5,13,3,11 ; block 00: A7 B7 A5 B5 A3 B3
DB 6,14,4,12,2,10 ; block 01: A6 B6 A4 B4 A2 B2
DB 3,11,1,9,7,15 ; block 10: A3 B3 A1 B1 A7 B7
DB 2,10,0,8,6,14 ; block 11: A2 B2 A0 B0 A6 B6
RIGHT_POSITIONS:
DB 15,14,13,11 ; B7 B6 B5 B3, literal task order
END