Уровень 28: Движущаяся точка

Открыть уровень →

Задание

Напишите программу, которая двигает точку по экрану с помощью геймпада.

Для движущейся точки нужно:

Решение

В ассемблере нет переменных — есть карта памяти. Мы сами договариваемся: 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