Уровень 28: Движущаяся точка
Задание
Напишите программу, которая двигает точку по экрану с помощью геймпада.
Для движущейся точки нужно:
Материалы по теме
- Ассемблер: самый честный язык программирования
- Ветвления и циклы (JZ, JN, JMP)
- Справка по ассемблеру →
- MatrixDisplay — матричный дисплей
- Gamepad — геймпад
Решение
В ассемблере нет переменных — есть карта памяти. Мы сами договариваемся: RAM[0] — это X, RAM[1] — это Y. Это договорённость на весь остаток программы: нарушь её в одном месте — и программа молча сломается. Координаты «живут» в RAM, а код лишь читает и перезаписывает их.
1. Хранить координаты X и Y в RAM (например, RAM[0]=X, RAM[1]=Y). 2. На каждом шаге читать геймпад: LDA 254 (порт 0xFE). Кнопки: бит 0=Вверх, 1=Вниз, 2=Влево, 3=Вправо. 3. Обновлять X/Y в RAM в зависимости от нажатых кнопок (сравнение через SUB+JN/JZ). 4. Очищать старый пиксель: STA 255 с Acc=0. 5. Записывать новый X/Y через порты 252/253. 6. Зажигать пиксель: STA 255 с Acc=1. 7. Цикл через JMP.
Совет: начните с простой программы, которая рисует точку в фиксированной позиции. Чекпойнт проверит запись в (3,5).
Полная программа (двигает точку геймпадом; эта же программа подставляется кнопкой подсказки в игре):
; RAM: RAM[0]=X, RAM[1]=Y; константы:
; RAM[2]=1, RAM[3]=2, RAM[4]=4, RAM[5]=8, RAM[6]=15
; Порты: 252=MatrixX, 253=MatrixY, 254=геймпад, 255=пиксель
init:
LDA 7
STA 0 ; X = 7
LDA 7
STA 1 ; Y = 7
LDA 1
STA 2 ; const 1
LDA 2
STA 3 ; const 2
LDA 4
STA 4 ; const 4
LDA 8
STA 5 ; const 8
LDA 15
STA 6 ; const 15
loop:
; 1. Стереть старый пиксель
LDA 0
ADD 0 ; Acc = X
STA 252 ; MatrixX
LDA 0
ADD 1 ; Acc = Y
STA 253 ; MatrixY
LDA 0
STA 255 ; пиксель = 0
; 2. Прочитать геймпад
LDA 0
ADD 254 ; Acc = кнопки
STA 7
JZ draw ; кнопок нет — просто перерисовать
; Вверх (бит 0)
LDA 0
ADD 7
AND 2 ; & 1
JZ chk_dn
LDA 0
ADD 1
SUB 2 ; Y - 1
AND 6 ; & 15 — перенос через край
STA 1
JMP draw
chk_dn:
; Вниз (бит 1)
LDA 0
ADD 7
AND 3 ; & 2
JZ chk_lt
LDA 0
ADD 1
ADD 2 ; Y + 1
AND 6
STA 1
JMP draw
chk_lt:
; Влево (бит 2)
LDA 0
ADD 7
AND 4 ; & 4
JZ chk_rt
LDA 0
ADD 0
SUB 2 ; X - 1
AND 6
STA 0
JMP draw
chk_rt:
; Вправо (бит 3)
LDA 0
ADD 7
AND 5 ; & 8
JZ draw
LDA 0
ADD 0
ADD 2 ; X + 1
AND 6
STA 0
draw:
; 3. Нарисовать точку в новой позиции
LDA 0
ADD 0
STA 252
LDA 0
ADD 1
STA 253
LDA 1
STA 255 ; пиксель = 1
; 4. Задержка
NOP
NOP
NOP
NOP
JMP loop
HLT