Тема: Гра "життя" конвея для мікроконтролерів i8051
Написав конвеївську гру "життя" для мікроконтролерів родини i8051.
Особливістю реалізації є:
* Поле розміром 8х8, де найправіша клітниа межує з найлівішою, а найвища - з найнищею, тобто це таке уявне коло, або стрічка Меібуса.
FIELD1 EQU 0x20 ; Адреса першого поля
FIELD2 EQU 0x28 ; Адреса другого поля
START:
MOV R0, #FIELD2 ; Очищення другого поля
CALL CLEAR_FIELD
MOV R0, #0x1 ; Обрання візерунка "маяк" в якості початкового, тобто копіювання другого візерунка з таблиці візерунків у перше поле
CALL FILL_FIELD1
CALL NEXT_GENERATION ; Здійснити хід або перейти до наступного покоління.
; В першому полі знаходиться "попередник" або "батько". Тобто початковий стан.
; В другому полі після виконання знаходитиметься "нащадок"
CALL SWAP_FIELDS ; Міняємо місцями батька із нащадком
MOV R0, #FIELD2 ; Очищення поля 2
CALL CLEAR_FIELD
CALL NEXT_GENERATION
NEXT_GENERATION:
MOV R0, #FIELD2
CALL CLEAR_FIELD
MAIN_LOOP:
MOV R2, #0x8
MOV R3, #0x8
LOOP_Y_UP:
DEC R3
LOOP_X_UP:
DEC R2
MOV R6, #0x0
CALL NUMROTATE
MOV A, R3
ADD A, #FIELD1
MOV R0, A
MOV A, @R0
MOV R7, A
CALL ROTATE
MOV A, R7
ANL A, #0x5
CALL COUNT
MOV A, R3
INC A
ANL A, #0x7
ADD A, #FIELD1
MOV R0, A
MOV A, @R0
MOV R7, A
CALL ROTATE
MOV A, R7
ANL A, #0x7
CALL COUNT
MOV A, R3
DEC A
ANL A, #0x7
ADD A, #FIELD1
MOV R0, A
MOV A, @R0
MOV R7, A
CALL ROTATE
MOV A, R7
ANL A, #0x7
CALL COUNT
MOV A, #FIELD1
ADD A, R3
MOV R0, A
MOV A, @R0
MOV R7, A
CLR C
MOV A, #0x7
SUBB A, R2
MOV R5, A
CALL ROTATE
MOV A, R7
ANL A, #0x1
JNZ LIVE_CELL
DEATH_CELL:
CJNE R6, #0x3, LOOP_DOWN
JMP LIVE
LIVE_CELL:
MOV A, R6
DEC A
DEC A
JZ LIVE
DEC A
JNZ LOOP_DOWN
LIVE:
MOV A, R2
MOV R5, A
MOV R7, #0x80
CALL ROTATE
MOV A, #FIELD2
ADD A, R3
MOV R0, A
MOV A, @R0
ORL A, R7
MOV @R0, A
LOOP_DOWN:
MOV A, R2
JNZ LOOP_X_UP
MOV R2, #0x8
MOV A, R3
JNZ LOOP_Y_UP
MOV R6, #0x0
MOV A, #0x5
CALL SWAP_FIELDS
RET
ROTATE:
MOV A, R5
MOV R1, A
ROTATE_UP:
MOV A, R1
JZ ROTATE_DOWN
MOV A, R7
RR A
MOV R7, A
DEC R1
JMP ROTATE_UP
ROTATE_DOWN:
RET
NUMROTATE:
MOV A, #0x7
CJNE R2, #0x7, NUMROTATE_CALC
JMP NUMROTATE_END
NUMROTATE_CALC:
DEC A
CLR C
SUBB A, R2
NUMROTATE_END:
MOV R5, A
RET
COUNT:
RRC A
JNC COUNT_1
INC R6
COUNT_1:
RRC A
JNC COUNT_2
INC R6
COUNT_2:
RRC A
JNC COUNT_3
INC R6
COUNT_3:
RET
CLEAR_FIELD:
MOV R1, #0x8
CLR A
FILL_FIELD_UP:
MOV @R0, A
INC R0
DJNZ R1, FILL_FIELD_UP
RET
; Міняє місцями попередника (або батька по-іншому) з нащадком
SWAP_FIELDS:
MOV R0, #FIELD1
MOV R1, #FIELD2
SWAP_FIELDS_LOOP:
MOV B, @R0
MOV A, @R1
MOV @R0, A
MOV @R1, B
INC R0
INC R1
CJNE R0, #(FIELD1+0x8), SWAP_FIELDS_LOOP
RET
; MOV R0, #0x0
FILL_FIELD1:
MOV DPTR, #START_VALUE
MOV A, R0
RL A
RL A
RL A
ANL A, #0xF8
MOV R0, A
MOV R1, #FIELD1
FILL_FIELD1_UP:
MOV A, R0
MOVC A, @A+DPTR
MOV @R1, A
INC R0
INC R1
CJNE R1, #(FIELD1+0x8), FILL_FIELD1_UP
RET
; Таблиця з візерунками (patterns` table)
START_VALUE:
DB 0x00, 0x00, 0x08, 0x04, 0x1C, 0x00, 0x00, 0x00 ; Планер (GLIDER)
DB 0x00, 0x00, 0x30, 0x20, 0x04, 0x0C, 0x00, 0x00 ; Маяк (BEACON)
Допишу, як буде час і натхнення. Те саме стосується і вікі, привяченій грі Життя