;
; ╔═════════════════════════════════════════════════════════════════════════╗
; ║     This file is generated by The Interactive Disassembler (IDA)        ║
; ║     Copyright (c) 2006 by DataRescue sa/nv, <ida@datarescue.com>        ║
; ║ Licensed to: Nikto                                                      ║
; ╚═════════════════════════════════════════════════════════════════════════╝
;
; Input MD5   : 9B6BB7518A601694895E2B08D44BC7BC

; ───────────────────────────────────────────────────────────────────────────
; File Name   : PLANET.GMC.raw_uncr-game
; Format      : Binary file
; Base Address: 0000h Range: 0200h - 4008h Loaded length: 3E08h

; Processor:        К1801ВМ1
; Target assembler: BKTurbo8 Cross Assembler

; ═══════════════════════════════════════════════════════════════════════════

FONT = 112276

Start0$:        jmp     @#NextStart$
; ───────────────────────────────────────────────────────────────────────────

DisTrap:        mov     R0, -(SP)
                mov     R1, -(SP)
                mov     R2, -(SP)
                mov     R3, -(SP)
                mov     R4, -(SP)
                mov     R5, -(SP)
                mov     14(SP), R5
                mov     -(R5), R5
                bic     #177400, R5
                add     PC, R5
                add     #<TrapTbl-.>, R5
                call    @(R5)+
                mov     (SP)+, R5
                mov     (SP)+, R4
                mov     (SP)+, R3
                mov     (SP)+, R2
                mov     (SP)+, R1
                mov     (SP)+, R0
VecKbdNo$:      rti
; ───────────────────────────────────────────────────────────────────────────
TrapTbl:        .word Trap00            ; Вывод слова GAME и цифры 3
                                        ; Вход: @#40 - блок параметров (адрес слова и номер цифры)
                .word Trap02            ; Вывод информации на экран
                                        ; Вход: блок параметров по адресу 40:
                                        ; .word адрес экрана
                                        ; .word адрес данных
                                        ; .word маска цвета
                                        ; .word задержка
                .word Trap04            ; Вывод символа на экран
                                        ; Вход: R2 - код символа - 20
                                        ;       @#40 - адрес экрана, куда выводить
                                        ;       @#42 - масштаб по высоте
                                        ;       @#44 - маска цвета
                .word Trap06            ; Вывод текста сложного формата на экран
                                        ; Вход: R1 - адрес экрана
                                        ;       @#46 - адрес массива данных
                .word Trap10            ; Рисует рамку заданного цвета
                                        ; Вход:R0 - адрес
                                        ;      @#50, @#52 - байты заполнители цвета
                .word Trap12            ; Вывод текста
                                        ; Вход: блок параметров по адресу 40
                                        ; .word адрес экрана
                                        ; .word адрес данных (таблица адресов символов в шрифте)
                                        ; .word маска цвета для 1 бита символа
                                        ; .word масштаб по высоте
                .word Trap14            ; Вывод звука
                                        ; Вход R1 - адрес таблицы параметров
                                        ; .word длит
                                        ; .word тон, тон,... (0 - конец таблицы)
                .word Trap16            ; Анимация заставки
                                        ; Вход: R4 - адрес текста
                .word Trap20            ; Вывод падающей каплей буквы
                                        ; Вход: R1 - адрес экрана
                                        ;       R2 - высота падения
                                        ;       R3 - код буквы - 20
                .word Trap22            ; Вывод текста буквами тырк-тырк влево-вправо
                                        ; Вход: R1 - адрес экрана
                                        ;       R2 - адрес текста
                                        ;       @#44 - маска цвета для 1 бита символа
                                        ;       @#46 - масштаб по высоте
                .word Trap24            ; Вывод три зелёных полосы и на них копирайт спрайтами
                .word Trap26            ; Вывод и обработка меню
                                        ; Вход: R0 - номер начального пункта меню
                                        ;       R1 - номер последнего пункта меню
                                        ;       R4 - адрес параметров меню
                                        ; Выход: R0 - выбранный пункт меню
                .word Trap30            ; Заполнение прямоугольной области экрана заданным цветом
                                        ; Вход: R1 - адрес экрана
                                        ;       R2 - ширина в байтах
                                        ;       R3 - высота в строках / 2
                                        ;       R0,R4 - чересстрочные цвета
                .word Trap32            ; Вывод и обработка меню для задания управления
                                        ; Вход: R2 - регистр данных
                                        ;       R3 - регистр управления
                                        ;       R4 - адрес блока параметров меню
                .word Trap34            ; Вывод спрайта на экран movом
                                        ; Вход: R0 - адрес спрайта в памяти, первые 2 слова высота в строках и ширина в байтах
                                        ;       R1 - адрес экрана
                .word Trap36            ; Вывод спрайта на экран методом наложения
                                        ; Вход: R0 - адрес спрайта в памяти, первые 2 слова высота в строках и ширина в байтах
                                        ;       R1 - адрес экрана
                .word Trap40            ; Стирание спрайта с экрана методом побитовой очистки
                                        ; Вход: R0 - адрес спрайта в памяти, первые 2 слова высота в строках и ширина в байтах
                                        ;       R1 - адрес экрана
                .word Trap42            ; Стирание спрайта с экрана clrом
                                        ; Вход: R0 - адрес спрайта в памяти, первые 2 слова высота в строках и ширина в байтах
                                        ;       R1 - адрес экрана
                .word Trap44            ; Вспомогательная функция функции Trap46
                .word Trap46            ; Вывод звёзд на экран
off_Trp50s:     .word Trap50_1          ; Опрос клавиатуры 1
off_Trp52s:     .word Trap52_1          ; Опрос джойстика 1
                .word Trap54            ; Проверка на коллизию.
                                        ; Вход: R0 - адрес спрайта объекта 2
                                        ;       R3 - адрес спрайта объекта 1
                                        ;       R4 - структура объекта 2
                                        ;       R5 - структура объекта 1
                                        ; Формат структуры см в другом месте
                .word Trap56            ; Проверка попаданиями пулек игрока в объект
                                        ; Вход: R3 - спрайт объекта
                                        ;       R5 - структура объекта
                .word Trap60            ; Вывод числовых значений счёта, жизней и т.п.
                                        ; Вход: R5 - адрес данных
                                        ;       R1 - адрес экрана
                .word Trap62            ; Увеличение счёта
                .word Trap64
                .word Trap66
                .word Trap70            ; Очистка экрана
                .word Trap72            ; Ждать нажатия чего-нибудь
                .word 100140            ; Trap 74 == Emt 14
                .word 0
; ───────────────────────────────────────────────────────────────────────────

NextStart$:     mov     #100112, @#30
                emt     314             ; Выполняет п/п по адресу 10004, там все инициализации
                br      Exit$
; ───────────────────────────────────────────────────────────────────────────
                emt     14
                mov     #strError, R1
                br      0Exit1$
; ───────────────────────────────────────────────────────────────────────────
strError:       .asciz <31>"ПРОГРАММА НЕ РАБОТОСПОСОБНА!"
                .even

; ███████████████ S U B R O U T I N E ███████████████████████████████████████


OutFinalScore:  mov     #Score, R0
                mov     R0, @#46
                mov     #114434, (R0)+  ; делаем из цифр строку
                mov     #3, R1

1$:             add     #20040, (R0)+
                sob     R1, 1$
                clr     (R0)+
                mov     #44010, R1
                trap    6               ; Вывод текста сложного формата на экран
                                        ; Вход: R1 - адрес экрана
                                        ;       @#46 - адрес массива данных
                trap    72              ; Ждать нажатия чего-нибудь
                return
; End of function OutFinalScore


; ███████████████ S U B R O U T I N E ███████████████████████████████████████


GoExit:         trap    74              ; == EMT 14
                clr     @#320
                mov     #DisTrap, @#34  ; делаем приготовления
                mov     #1000, @#264
                mov     #233, R0
                emt     16              ; вывод символа
                mov     #40000, R0
                mov     #1000, R1

1$:             clr     (R0)+
                sob     R1, 1$
                trap    24              ; Вывод три зелёных полосы и на них копирайт спрайтами

Exit$:          mov     #strStart, R1   ; " ЗАПУСК "

0Exit1$:        clr     R2
                emt     20
                halt
; End of function GoExit

; ───────────────────────────────────────────────────────────────────────────
strStart:       .asciz " ЗАПУСК "<265><265>" S 'ВВОД'"<12><12>
                .even
; ───────────────────────────────────────────────────────────────────────────

FinalGame:      mov     #TrapTo4.Fin$, @#4
                call    @#OutFinalScore

TrapTo4.Fin$:   mov     #760, SP
                mov     #1330, @#177664
                jmp     @#NextFinal1$

; ███████████████ S U B R O U T I N E ███████████████████████████████████████

; Ждать нажатия чего-нибудь

Trap72:         bit     #100, @#177716
                beq     1$
                tst     @#177714
                beq     Trap72          ; Ждать нажатия чего-нибудь
1$:             return
; End of function Trap72


; ███████████████ S U B R O U T I N E ███████████████████████████████████████

; Вывод слова GAME и цифры 3
; Вход: @#40 - блок параметров (адрес слова и номер цифры)

Trap00:         mov     @#44, R5        ; адрес начала экрана

1$:             clr     (R5)+           ; очищаем эран
                cmp     #100000, R5
                bne     1$
                mov     #1, 00.ScaleY$  ; масштаб по высоте символа
                mov     @#64, R1        ; адрес начала вывода

2$:             mov     @#46, R5        ; адрес адресов данных букв

3$:             mov     (R5)+, R3       ; берём очередной адрес
                beq     9$              ; 0 - конец

4$:             mov     (PC)+, R4
00.ScaleY$:     .word 12

5$:             movb    (R3), R2        ; берём очередной байт данных символа
                mov     #10, R0         ; в байте 8 бит

6$:             clr     (R1)
                rorb    R2
                bcc     7$
                mov     @#50, (R1)      ; цвет символа

7$:             tst     (R1)+           ; расширяем бит в слово
                sob     R0, 6$
                add     #60, R1
                sob     R4, 5$          ; масштабируем, повторяем вывод байта сколько надо
                movb    (R3)+, R0       ; вывели символ полностью?
                bne     4$              ; нет ещё - продолжаем
                mov     00.ScaleY$, R4  ; перейдём к позиции следующего символа

8$:             sub     #1000, R1
                sob     R4, 8$
                sub     #60, R1
                br      3$
; ────────────────────────────────────────────────────────────────────────────────────────────────────────────────

9$:             inc     00.ScaleY$      ; увеличим масштаб
                mov     #20, R0         ; звук

10$:            mov     #100, R4
                mov     R4, R3
                clr     @#177716

                sob     R3, .
                mov     #100300, @#177716

                sob     R4, .
                sob     R0, 10$
                cmp     @#52, 00.ScaleY$ ; до предела дошли?
                bne     2$
                mov     @#42, R1        ; адрес вывода
                bit     #177400, @#54   ; что выводить
                beq     11$             ; старшего байта нету - выводим только младший
                mov     @#54, R0        ; иначе сперва выведем мл.
                swab    R0              ; потом старший байт
                call    DrawDigit       ; вывод цифры

11$:            mov     @#54, R0
; End of function Trap00


; ███████████████ S U B R O U T I N E ███████████████████████████████████████


DrawDigit:      mov     #FONT + <'0 - 40>*10. + 1, R2
                bic     #177700, R0
                beq     2$

1$:             add     #10., R2
                sob     R0, 1$

2$:             mov     @#56, R3

3$:             mov     #10, R5
                movb    (R2), R4

4$:             ror     R4
                bcc     7$
                tst     (R1)
                bne     5$
                mov     @#40, (R1)

5$:             tst     (R1)+
                tst     (R1)
                bne     6$
                mov     @#40, (R1)

6$:             br      8$
; ───────────────────────────────────────────────────────────────────────────

7$:             tst     (R1)+

8$:             tst     (R1)+
                sob     R5, 4$
                add     #40, R1
                sob     R3, 3$
                movb    (R2)+, R4
                bne     2$
                mov     @#42, R1
                add     #40, R1
                return
; End of function DrawDigit


; ███████████████ S U B R O U T I N E ███████████████████████████████████████

; Вывод информации на экран
; Вход: блок параметров по адресу 40:
; .word адрес экрана
; .word адрес данных
; .word маска цвета
; .word задержка

Trap02:         mov     @#40, R1        ; адрес экрана
                mov     #40, R2         ; очищаем строку экрана

1$:             clr     (R1)+
                sob     R2, 1$
                mov     @#42, R5        ; адрес данных
                mov     @#40, R1        ; адрес экрана
                movb    (R5)+, R4       ; берём очередной байт
                beq     3$              ; если 0, то пропустим
                bic     #177400, R4     ; если не 0, то это число повторов

2$:             call    MovAddrDnScrlUp ; Очистка следующей строки экрана и скроллинг
                sob     R4, 2$          ; скроллим экран на заданное кол-во строк

3$:             mov     R1, @#40        ; сохраняем новый адрес экрана
                movb    (R5)+, R4       ; берём следующий байт - смещение от левого края экрана
                movb    (R5)+, R3       ; берём следующий байт - количество символов
                bic     #177400, R4
                mov     R4, @#50        ; сохраняем
                bic     #177400, R3
                mov     #300, R1        ; адрес буфера

4$:             movb    (R5)+, R2       ; берём следующий байт
                bne     5$              ; не 0 - нормально
                return                  ; 0 - конец данных
; ───────────────────────────────────────────────────────────────────────────

5$:             bic     #177400, R2     ; это код символа
                mov     #FONT-240+1, R0

6$:             add     #10., R0        ; * 10.
                sob     R2, 6$
                mov     R0, (R1)+       ; адрес данных символа сохраним в буфере
                sob     R3, 4$          ; и так всю строку
                clr     (R1)+           ; конец строки
                mov     R5, @#42        ; указатель на данные сохраним
                mov     @#40, R1        ; адрес экрана
                mov     #10, R5         ; это высота символа

7$:             mov     #300, R0        ; адрес буфера
                add     @#50, R1        ; сместимся к месту вывода строки

8$:             mov     (R0), R2        ; адрес данных символа
                beq     12$             ; 0 - конец строки
                movb    (R2), R2        ; очередные данные символа
                inc     (R0)+           ; указатель на следующий байт данных символа
                mov     #4, R3          ; байт -> в 2 слова

9$:             mov     #2, R4          ; два бита -> в байт

10$:            rorb    (R1)
                rorb    (R1)
                rorb    (R1)
                rorb    (R1)
                bicb    #360, (R1)
                rorb    R2
                bcc     11$
                bisb    @#44, (R1)       ; маска цвета букв

11$:            sob     R4, 10$
                inc     R1
                sob     R3, 9$
                br      8$              ; и так, пока строку не выведем
; ───────────────────────────────────────────────────────────────────────────

12$:            bit     #77, R1         ; попали на следующую строку?
                beq     13$             ; да - переход
                bis     #77, R1         ; иначе - переход на следующую строку
                inc     R1

13$:            call    ScrlUp          ; Проверка, на границы экрана, чтоб адрес за них не вышел и скролл на 1 строку
                                        ; Вход: R1 - адрес начала следующей строки
                sob     R5, 7$          ; и так все 8 строк символа
                mov     R1, @#40        ; новый адрес сохраним
                br      Trap02          ; и всё сначала
; End of function Trap02


; ███████████████ S U B R O U T I N E ███████████████████████████████████████

; Очистка следующей строки экрана и скроллинг

MovAddrDnScrlUp:add     #100, R1
; End of function MovAddrDnScrlUp


; ███████████████ S U B R O U T I N E ███████████████████████████████████████

; Проверка, на границы экрана, чтоб адрес за них не вышел и скролл на 1 строку
; Вход: R1 - адрес начала следующей строки

ScrlUp:         cmp     #100000, R1     ; если адрес вышел за низ экрана
                bne     1$
                mov     #40000, R1      ; сделаем начало экрана

1$:             mov     #40, R3         ; очищаем строку экрана

2$:             clr     (R1)+
                sob     R3, 2$
                mov     @#46, R3        ; задержка

                sob     R3, .
                inc     @#177664        ; скролл вверх на 1 строку
                sub     #100, R1        ; вернёмся к началу очищенной строки
                cmp     #37700, R1      ; проверим, если вышли за верх экрана
                bne     3$
                mov     #77700, R1      ; сделаем низ экрана

3$:             return
; End of function ScrlUp


; ███████████████ S U B R O U T I N E ███████████████████████████████████████

; Вывод символа на экран
; Вход: R2 - код символа - 20
;       @#40 - адрес экрана, куда выводить
;       @#42 - масштаб по высоте
;       @#44 - маска цвета

Trap04:         bic     #177400, R2
                mov     #FONT-240+1, R0 ; 112037

1$:             add     #12, R0
                sob     R2, 1$          ; получим адрес данных символа
                mov     #10, R5

2$:             mov     @#42, R2        ; масштаб по высоте

3$:             mov     #10, R3         ; в байте 8 бит
                movb    (R0), R4        ; берём данные

4$:             rorb    R4              ; берём бит
                bcc     5$              ; если 0, то пропускаем
                movb    @#44, (R1)      ; иначе - рисуем точку (расширение бит в байт)

5$:             inc     R1
                sob     R3, 4$          ; и так все биты
                add     #70, R1         ; к следующей строке экрана
                sob     R2, 3$          ; масштабируем
                movb    (R0)+, R4       ; берём ещё данные
                sob     R5, 2$          ; пока не 0
                return                  ; 0 - конец, но так мы не сможем вывести знаки типа . , - (у которых вверху нули)
; End of function Trap04

; формат:
; сперва идут два байта параметров: byte ScaleY, ColorMask
; затем данные, если 320 - то за ним снова два байта параметров
; если 377, то за ним байт - смещение по высоте в строках
; если 321..376 - то это смещение в строке + 320
; всё остальное - символы - 20

; ███████████████ S U B R O U T I N E ███████████████████████████████████████

; Вывод текста сложного формата на экран
; Вход: R1 - адрес экрана
;       @#46 - адрес массива данных

Trap06:         mov     @#46, R0        ; адрес массива данных

1$:             movb    (R0)+, R2       ; берём первый байт
                bic     #177400, R2
                mov     R2, @#42        ; это масштаб по высоте
                movb    (R0)+, R2       ; берём второй байт
                bic     #177400, R2
                mov     R2, @#44        ; это маска цвета

2$:             movb    (R0)+, R2       ; берём байт данных
                bne     3$              ; если 0,
                return                  ; то конец
; ───────────────────────────────────────────────────────────────────────────

3$:             bic     #177400, R2
                cmp     #320, R2        ; если 320
                beq     1$              ; то снова надо брать параметры
                cmp     #377, R2        ; если 377
                bne     6$
                movb    (R0)+, R1       ; то берём ещё байт
                bic     #177400, R1
                mov     #6, R4

4$:             clc
                rol     R1
                sob     R4, 4$          ; умножаем на 100
                add     @#40, R1        ; прибавляем адрес экрана
                bis     #77, R1
                inc     R1              ; переводим на следующую строку экрана
                mov     R1, @#40        ; и сохраняем новый адрес экрана

5$:             br      2$              ; и идём за новыми данными
; ───────────────────────────────────────────────────────────────────────────

6$:             cmp     R2, #320        ; если данные меньше 320
                ble     8$              ;  переход
                sub     #320, R2        ; иначе, вычитаем 320
                add     R2, R1          ;  и это смещение в строке
                nop

7$:             br      5$              ; и идём за новыми данными
; ───────────────────────────────────────────────────────────────────────────

8$:             trap    4               ; Вывод символа на экран
                                        ; Вход: R2 - код символа - 20
                                        ;       R1 - адрес экрана, куда выводить
                                        ;       @#40 - адрес экрана, куда выводить
                                        ;       @#42 - масштаб по высоте
                                        ;       @#44 - маска цвета
                add     #10, R1
                nop
                br      7$
; End of function Trap06


; ███████████████ S U B R O U T I N E ███████████████████████████████████████

; Рисует рамку заданного цвета
; Вход:R0 - адрес
;      @#50, @#52 - байты заполнители цвета

Trap10:         mov     R0, R3
                mov     R0, R5
                bic     #177700, R5
                bis     #77, R3
                bic     R5, R3
                mov     #140000, R4
                sub     R0, R4
                add     R5, R4
                add     R5, R4
                mov     R3, R2
                add     #400, R3

1$:             sub     #400, R4
                mov     #4, R1

2$:             bit     #100, R0
                beq     3$
                mov     @#50, R5
                br      4$
; ───────────────────────────────────────────────────────────────────────────

3$:             mov     @#52, R5

4$:             movb    R5, (R0)
                movb    R5, (R2)
                movb    R5, (R3)
                movb    R5, (R4)
                add     #100, R0
                add     #100, R2
                add     #100, R3
                add     #100, R4
                sob     R1, 2$
                sub     #401, R2
                inc     R4
                cmp     R3, R4
                bne     1$
                return
; End of function Trap10


; ███████████████ S U B R O U T I N E ███████████████████████████████████████

; Вывод текста
; Вход: блок параметров по адресу 40
; .word адрес экрана
; .word адрес данных (таблица адресов символов в шрифте)
; .word маска цвета для 1 бита символа
; .word масштаб по высоте

Trap12:         mov     @#46, 12.ScaleY$
                mov     @#42, R0        ; данные
                mov     @#40, R1        ; адрес экрана
                mov     R1, R5          ; сохраним тут

1$:             mov     (R0)+, R2       ; берём очередной адрес данных символа
                beq     9$              ; 0 - конец

2$:             movb    (R2)+, R4       ; данные символа

3$:             mov     #4, R3          ; расширяем байт в 2 слова

4$:             ror     (R1)
                ror     (R1)
                ror     (R1)
                ror     (R1)
                bic     #170000, (R1)   ; освобождаем место для очередных битов цвета
                ror     R4              ; смотрим бит
                bcc     5$              ; нету - 0
                bis     @#44, (R1)      ; есть  - применяем маску цвета

5$:             sob     R3, 4$          ; и так всё слово
                tst     (R1)+           ; переходим к следующему
                mov     R1, R3
                sub     R5, R3
                bic     #177700, R3     ; посмотрим, какая уже ширина символа
                cmp     #4, R3          ; если ещё не 4 байта
                bne     3$              ; продолжаем
                mov     (PC)+, R3
12.ScaleY$:     .word 1
                beq     7$              ; 0 - не надо масштабировать

6$:             add     #74, R1         ; дублируем по высоте
                mov     -100(R1), (R1)+
                mov     -100(R1), (R1)+
                sob     R3, 6$          ; сколько надо

7$:             add     #74, R1
                mov     12.ScaleY$, R3
                inc     R3
                mov     R5, R4

8$:             add     #600, R4        ; высота 6 строк?
                sob     R3, 8$
                cmp     R4, R1
                bge     2$              ; цикл пока не выведем весь символ
                add     #4, R5          ; переход к следующему символу
                mov     R5, R1
                br      1$
; ───────────────────────────────────────────────────────────────────────────

9$:             return
; End of function Trap12


; ███████████████ S U B R O U T I N E ███████████████████████████████████████

; Анимация заставки
; Вход: R4 - адрес текста

Trap16:         mov     #44000, @#334
                mov     #40, R0
                mov     #40404, (R0)+
                mov     #datText1, (R0)+ ; (C)  BIL corp.
                mov     #175000, (R0)+
                mov     #3, (R0)+
                trap    12              ; Вход: @#40 - заполненный блок параметров
                                        ; .word адрес экрана
                                        ; .word адрес данных (таблица адресов символов в ширите)
                                        ; .word маска цвета для 1 бита символа
                                        ; .word масштаб по высоте
                mov     R4, R5          ; адрес данных
                add     #40, R5         ; конец данных
                mov     R5, 16.DatEnd$
; тут заезжают в экран с боков буквы "**  PLANET  **"

1$:             mov     (R4)+, R3       ; адрес данных одного символа
                mov     (R4)+, R2       ; адрес данных другого символа
                mov     #8., R1         ; высота символа
                mov     #340, R0        ; буфер

2$:             movb    (R3)+, (R0)+    ; копируем туда чересстрочно данные обоих символов
                movb    (R2)+, (R0)+
                sob     R1, 2$
                mov     #4, R5

3$:             mov     #64036, R0
                mov     #64041, R1
                mov     #25, R2         ; высота

4$:             mov     #37, R3         ; сдвиг побайтно

5$:             movb    (R0)+, (R0)     ; слева направо
                tst     -(R0)
                movb    (R1), -(R1)     ; справа налево
                tst     (R1)+
                sob     R3, 5$
                add     #41, R1
                add     #137, R0
                sob     R2, 4$
                mov     #64000, R0
                mov     #340, R2

6$:             clrb    (R0)
                rolb    (R2)
                bcc     7$
                bisb    #365, (R0)

7$:             rolb    (R2)+
                bcc     8$
                bisb    #17, (R0)

8$:             call    sub_3442        ; Дублируем по высоте
                sub     #101, R0
                clrb    (R0)
                rorb    (R2)
                bcc     9$
                bisb    #17, (R0)

9$:             rorb    (R2)+
                bcc     10$
                bisb    #365, (R0)

10$:            call    sub_3442        ; Дублируем по высоте
                inc     R0
                cmp     #66400, R0
                bge     6$
                call    sub_3462        ; Опускаем вниз копирайт "(C)  BIL corp."
                nop
                sob     R5, 3$
                cmp     (PC)+, R4
16.DatEnd$:     .word 10272
                bne     1$
                br      NextTrap16$
; End of function Trap16

; ───────────────────────────────────────────────────────────────────────────
datText1:       .word FONT + <'( - 40>*10. + 1  ; (C)  BIL corp.
                .word FONT + <'C - 40>*10. + 1
                .word FONT + <') - 40>*10. + 1
                .word FONT + <'  - 40>*10. + 1
                .word FONT + <'  - 40>*10. + 1
                .word FONT + <'B - 40>*10. + 1
                .word FONT + <'I - 40>*10. + 1
                .word FONT + <'L - 40>*10. + 1
                .word FONT + <'  - 40>*10. + 1
                .word FONT + <'c - 40>*10. + 2
                .word FONT + <'o - 40>*10. + 2
                .word FONT + <'r - 40>*10. + 2
                .word FONT + <'p - 40>*10. + 2
                .word FONT + <'. - 40>*10. + 1
                .word 0

; ███████████████ S U B R O U T I N E ███████████████████████████████████████

; Дублируем по высоте

sub_3442:       movb    (R0), R3
                mov     #2, R1

1$:             add     #100, R0
                movb    R3, (R0)
                sob     R1, 1$
                return
; End of function sub_3442


; ███████████████ S U B R O U T I N E ███████████████████████████████████████

; Опускаем вниз копирайт "(C)  BIL corp."

sub_3462:       mov     #4, R3
                mov     @#334, R1

1$:             mov     R1, R0
                add     #100, R0
                mov     #1600, R2

2$:             mov     -(R1), -(R0)
                sob     R2, 2$
                mov     #40, R2

3$:             clr     -(R1)
                sob     R2, 3$
                add     #3600, R1
                mov     R1, @#334
                sob     R3, 1$
                return
; End of function sub_3462


; ███████████████ S U B R O U T I N E ███████████████████████████████████████

; Вывод звука
; Вход R1 - адрес таблицы параметров
; .word длит
; .word тон, тон,... (0 - конец таблицы)

Trap14:         mov     (R1)+, R5       ; длительность звуков

1$:             mov     R5, R2
                mov     (R1)+, R3       ; очередной тон
                beq     2$
                call    @#102062
                br      1$
; ───────────────────────────────────────────────────────────────────────────

2$:             return
; End of function Trap14

; ───────────────────────────────────────────────────────────────────────────
Sound1$:        .word 10
                .word 400
                .word 200
                .word 660
                .word 400
                .word 0
; ───────────────────────────────────────────────────────────────────────────
; START OF FUNCTION CHUNK FOR Trap16

NextTrap16$:    mov     #Sound1$, R1
                call    @#Trap14        ; Вывод звука
                                        ; Вход R1 - адрес таблицы параметров
                                        ; .word длит
                                        ; .word тон, тон,... (0 - конец таблицы)
; раздвигаем буквы вверх и вниз со звуком
                mov     #15, R1
                mov     #60000, R4
                mov     #70000, R5

1$:             mov     #1600, R0

2$:             mov     100(R4), (R4)+
                mov     -400(R5), (R5)
                tst     -(R5)
                sob     R0, 2$
                mov     #200, R0
                add     #300, R4

3$:             clrb    (R4)+
                clr     -(R5)
                sob     R0, 3$
                mov     #24, R2
                sub     R1, R2
                mov     #400, R3
                call    @#102062
                sub     #4200, R4
                add     #4400, R5
                sob     R1, 1$
                mov     #40, R0
                mov     #64410, (R0)+
                mov     #datText3, (R0)+ ; ПРЕДСТАВЛЯЕТ
                mov     #150000, (R0)+
                mov     #3, (R0)+
                trap    12
                mov     #1, R0
                mov     #600, R1

4$:             mov     R0, R2
                mov     #220, @#177716

                sob     R2, .
                mov     R0, R2
                mov     #320, @#177716

                sob     R2, .
                inc     R0
                sob     R1, 4$
                return
; END OF FUNCTION CHUNK FOR Trap16
; ───────────────────────────────────────────────────────────────────────────
                .word 0
datText3:       .word FONT + <'П - 100>*10. + 1 ; ПРЕДСТАВЛЯЕТ
                .word FONT + <'Р - 100>*10. + 1
                .word FONT + <'Е - 100>*10. + 1
                .word FONT + <'Д - 100>*10. + 1
                .word FONT + <'С - 100>*10. + 1
                .word FONT + <'Т - 100>*10. + 1
                .word FONT + <'А - 100>*10. + 1
                .word FONT + <'В - 100>*10. + 1
                .word FONT + <'Л - 100>*10. + 1
                .word FONT + <'Я - 100>*10. + 1
                .word FONT + <'Е - 100>*10. + 1
                .word FONT + <'Т - 100>*10. + 1
                .word 0
                .word 0
                .byte 0
; Спрайт капля, ширина 1 байт, высота 13 строк
SpriteDrop:     .byte ^B00000000
                .byte ^B00010000
                .byte ^B00000100
                .byte ^B00010000
                .byte ^B00000100
                .byte ^B00010000
                .byte ^B00010100
                .byte ^B01010101
                .byte ^B01010101
                .byte ^B01010101
                .byte ^B00010100

; ███████████████ S U B R O U T I N E ███████████████████████████████████████

; Вывод падающей каплей буквы
; Вход: R1 - адрес экрана
;       R2 - высота падения
;       R3 - код буквы - 20

Trap20:         mov     #SpriteDrop, R0
                mov     #13, R5

1$:             movb    (R0)+, (R1)
                add     #100, R1
                sob     R5, 1$
                mov     #1000, R5

                sob     R5, .
                sub     #1200, R1
                sob     R2, Trap20      ; капля падает вниз на сколько надо
                dec     R1
                mov     R1, @#40
                inc     R1
                mov     #12, R5         ; стирается

2$:             clrb    (R1)+
                add     #77, R1
                sob     R5, 2$
                mov     #FONT-240+1, R0 ; получаем адрес данных буквы
                bic     #177400, R3
                beq     4$

3$:             add     #10., R0
                sob     R3, 3$

4$:             mov     #50, R5         ; по этому адресу формируется массив из одного элемента
                mov     R5, @#42
                mov     R0, (R5)+
                clr     (R5)+
                mov     #200, R3
                mov     #30, R2
                call    @#102062        ; звук
                                        ; и выведем букву
                jmp     @#Trap12        ; Вывод текста
                                        ; Вход: блок параметров по адресу 40
                                        ; .word адрес экрана
                                        ; .word адрес данных (таблица адресов символов в шрифте)
                                        ; .word маска цвета для 1 бита символа
                                        ; .word масштаб по высоте
; End of function Trap20

; ███████████████ S U B R O U T I N E ███████████████████████████████████████

; Вывод текста буквами тырк-тырк влево-вправо
; Вход: R1 - адрес экрана
;       R2 - адрес текста
;       @#44 - маска цвета для 1 бита символа
;       @#46 - масштаб по высоте

Trap22:         mov     #334, @#42      ; это адрес массива для trap 12
                mov     #336, R0        ; тут формируем буфер
                clr     (R0)+           ; сперва 0

1$:             mov     #FONT-240+1, R5
                movb    (R2)+, R4       ;  потом адреса букв
                beq     3$        ; пока строка не кончится
                bic     #177400, R4

2$:             add     #10., R5
                sob     R4, 2$
                mov     R5, (R0)+
                br      1$
; ───────────────────────────────────────────────────────────────────────────

3$:             clr     (R0)+           ; в конце тоже 0
                mov     #340, R5        ; адрес начала массива адресов данных символов строки

T22.Repeat$:    mov     (R5), @#334
                mov     R1, @#40
                trap    12              ; Вход: @#40 - заполненный блок параметров
                                        ; .word адрес экрана
                                        ; .word адрес данных (таблица адресов символов в шрифте)
                                        ; .word маска цвета для 1 бита символа
                                        ; .word масштаб по высоте
                tst     -(R5)
                beq     4NextT22$
                sub     #4, R1
                mov     #T22.Repeat$, -(SP)
; End of function Trap22


; ███████████████ S U B R O U T I N E ███████████████████████████████████████


sub_4276:       mov     #17000, R3

                sob     R3, .
                mov     @#40, R4
                mov     @#46, R3
                inc     R3

1$:             mov     #10, R2

2$:             clr     (R4)+
                clr     (R4)
                add     #76, R4
                sob     R2, 2$
                sob     R3, 1$

3$:             return
; End of function sub_4276

; ───────────────────────────────────────────────────────────────────────────
; START OF FUNCTION CHUNK FOR Trap22

4NextT22$:      mov     R1, R3
                mov     #Sound2$, R1
                trap    14              ; Вывод звука
                                        ; Вход R1 - адрес таблицы параметров
                                        ; .word длит
                                        ; .word тон, тон,... (0 - конец таблицы)
                mov     R3, R1
                tst     (R5)+
                clr     (R5)+
                tst     (R5)
                beq     3$

5$:             mov     (R5)+, @#334
                add     #4, R1
                mov     R1, @#40
                trap    12              ; Вывод текста
                                        ; Вход: блок параметров по адресу 40
                                        ; .word адрес экрана
                                        ; .word адрес данных (таблица адресов символов в шрифте)
                                        ; .word маска цвета для 1 бита символа
                                        ; .word масштаб по высоте
                tst     (R5)
                beq     6$
                call    @#sub_4276
                br      5$
; ───────────────────────────────────────────────────────────────────────────

6$:             clr     -(R5)
                tst     -(R5)
                beq     3$
                sub     #4, R1
                mov     R1, R3
                mov     #Sound2$, R1
                trap    14              ; Вывод звука
                                        ; Вход R1 - адрес таблицы параметров
                                        ; .word длит
                                        ; .word тон, тон,... (0 - конец таблицы)
                mov     R3, R1
                br      T22.Repeat$
; END OF FUNCTION CHUNK FOR Trap22
; ───────────────────────────────────────────────────────────────────────────
Sound2$:        .word 14
                .word 100
                .word 200
                .word 300
                .word 400
                .word 300
                .word 200
                .word 0
sprBIL:         .byte 125, 125, 120, 25, 25, 0
                .byte 375, 377, 321, 77, 75, 0
                .byte 364, 320, 103, 17, 75, 0
                .byte 364, 325, 103, 17, 75, 0
                .byte 364, 377, 101, 17, 75, 0
                .byte 364, 320, 103, 17, 75, 125
                .byte 364, 320, 103, 17, 75, 375
                .byte 364, 325, 103, 17, 75, 375
                .byte 375, 377, 320, 77, 375, 377
sprCopyright:   .byte 300, 377, 3
                .byte 160, 125, 15
                .byte 134, 377, 65
                .byte 327, 327, 327
                .byte 327, 127, 325
                .byte 327, 127, 325
                .byte 327, 127, 325
                .byte 327, 327, 327
                .byte 134, 377, 65
                .byte 160, 125, 15
                .byte 300, 377, 3
                .byte 0

; ███████████████ S U B R O U T I N E ███████████████████████████████████████

; Вывод три зелёных полосы и на них копирайт спрайтами

Trap24:         mov     #40400, R0
                mov     #40, R1
; рисуем 3 зелёных полосы
                mov     #125252, R2

1$:             mov     R2, 400(R0)
                mov     R2, 200(R0)
                mov     R2, (R0)+
                sob     R1, 1$
; Выводим спрайт BIL
                mov     #SprBIL, R0
                mov     #40137, R1
                mov     #11, R2

2$:             mov     #6, R3
                clrb    (R1)+

3$:             movb    (R0)+, (R1)+
                sob     R3, 3$
                clrb    (R1)+
                add     #70, R1
                sob     R2, 2$
; выводим спрайт (С)
                mov     #40032, R1
                mov     #13, R2

4$:             mov     #3, R3
                clrb    (R1)+

5$:             movb    (R0)+, (R1)+
                sob     R3, 5$
                clrb    (R1)+
                add     #73, R1
                sob     R2, 4$
                return
; End of function Trap24


; ███████████████ S U B R O U T I N E ███████████████████████████████████████

; Вывод и обработка меню
; Вход: R0 - номер начального пункта меню
;       R1 - номер последнего пункта меню
;       R4 - адрес параметров меню
; Выход: R0 - выбранный пункт меню

Trap26:         mov     #176000, @#44   ; маска цвета
                mov     #1, @#46        ; масштаб по Y
                mov     R4, R5          ; адрес параметров меню
; выводим меню на экран
                mov     R1, R3          ; номер последнего пункта меню
                inc     R3              ; сделаем количество пунктов меню

1$:             mov     (R5)+, @#40     ; адрес экрана
                mov     (R5)+, @#50     ; ширина курсора меню в словах
                mov     R5, @#42        ; данные пункта меню
                trap    12              ; Вход: @#40 - заполненный блок параметров
                                        ; .word адрес экрана
                                        ; .word адрес данных (таблица адресов символов в шрифте)
                                        ; .word маска цвета для 1 бита символа
                                        ; .word масштаб по высоте

2$:             tst     (R5)+           ; пропустим текст, переходим к следующему пункту
                bne     2$
                sob     R3, 1$          ; и так выведем все пункты меню
                mov     R1, @#300       ; сохраним номер последнего пункта меню
                mov     R5, R1          ; сразу на меню - звук
                trap    14              ; Вывод звука
                                        ; Вход R1 - адрес таблицы параметров
                                        ; .word длит
                                        ; .word тон, тон,... (0 - конец таблицы)
; выбираем нужный пункт

LoopT26$:       mov     (R4)+, @#40     ; адрес экрана
                mov     (R4)+, @#50     ; ширина в словах
                mov     #KeybProc, -(SP) ; куда потом

SelectMenu:     mov     @#40, R3        ; адрес экрана
                sub     #300, R3        ; на 3 строки вверх
                mov     @#50, R5        ; ширина в словах

4$:             mov     #24, R2         ; высота курсора меню

5$:             com     (R3)            ; выделяем
                add     #100, R3
                sob     R2, 5$
                sub     #2376, R3
                sob     R5, 4$          ; и так по всей ширине
                return
; End of function Trap26


; ███████████████ S U B R O U T I N E ███████████████████████████████████████


KeybProc:       tst     @#177714        ; джойстик нажат?
                bne     6$              ; да - это ввода
                bit     #100, @#177716  ; клавиша нажата?
                bne     KeybProc        ; нет
                mov     @#177662, R5    ; да, берём код
                cmp     #33, R5         ; стрелка вниз?
                bne     3$              ; нет
                cmp     R0, @#300       ; мы уже на последнем пункте?
                beq     KeybProc        ; да - нечего делать
                inc     R0              ; нет - переходим к нижнему пункту меню

1$:             tst     (R4)+
                bne     1$

2$:             mov     #Sound3$, R1    ; звук выделения текущего пункта меню
                trap    14
                call    @#SelectMenu    ; развыделим текущий
                br      LoopT26$        ; перейдём к следующему
; ───────────────────────────────────────────────────────────────────────────

3$:             cmp     #32, R5         ; стрелка вверх?
                bne     5$              ; нет
                tst     R0              ; мы уже на первом пункте?
                beq     KeybProc        ; да - нечего делать
                dec     R0              ; нет - переходим к верхнему пункту меню
                sub     #12, R4         ; возвращаем указатель на начало предыдущего пункта

4$:             tst     -(R4)
                bne     4$
                tst     (R4)+
                br      2$              ; идём развыделять текущий и далее
; ───────────────────────────────────────────────────────────────────────────

5$:             cmp     #12, R5         ; ввод?
                bne     KeybProc        ; нет

6$:             mov     R0, 14(SP)      ; возвращаем значение
                mov     #Sound4$, R1    ; звук выбора пункта меню
                jmp     @#Trap14        ; Вывод звука
                                        ; Вход R1 - адрес таблицы параметров
                                        ; .word длит
                                        ; .word тон, тон,... (0 - конец таблицы)
; End of function KeybProc

; ███████████████ S U B R O U T I N E ███████████████████████████████████████

; Заполнение прямоугольной области экрана заданным цветом
; Вход: R1 - адрес экрана
;       R2 - ширина в байтах
;       R3 - высота в строках / 2
;       R0,R4 - чересстрочные цвета

Trap30:         mov     R3, 30.Height$

1$:             mov     R1, R5
                mov     (PC)+, R3
30.Height$:     .word 50

2$:             mov     R0, (R5)
                add     #100, R5
                mov     R4, (R5)
                add     #100, R5
                sob     R3, 2$
                tst     (R1)+
                sob     R2, 1$
                return
; End of function Trap30


; ███████████████ S U B R O U T I N E ███████████████████████████████████████

; Вывод и обработка меню для задания управления
; Вход: R2 - регистр данных
;       R3 - регистр управления
;       R4 - адрес блока параметров меню

Trap32:         mov     #175000, @#44
                mov     #1, @#46
                mov     R4, R5

1$:             mov     (R5)+, @#40
                mov     R5, @#42
                trap    12              ; Вход: блок параметров по адресу 40
                                        ; .word адрес экрана
                                        ; .word адрес данных (таблица адресов символов в шрифте)
                                        ; .word маска цвета для 1 бита символа
                                        ; .word масштаб по высоте

2$:             tst     (R5)+
                bne     2$
                sob     R1, 1$
                mov     R5, R1
                trap    14              ; Вывод звука
                                        ; Вход R1 - адрес таблицы параметров
                                        ; .word длит
                                        ; .word тон, тон,... (0 - конец таблицы)

T32Loop$:       mov     (R4)+, R5
                sub     #300, R5
                mov     #CtrlProc$, -(SP)
; End of function Trap32


; ███████████████ S U B R O U T I N E ███████████████████████████████████████


SelCtrlMenu:    mov     #24, R1

1$:             com     (R5)+
                com     (R5)
                add     #76, R5
                sob     R1, 1$
                sub     #2400, R5
                return
; End of function SelCtrlMenu


; ███████████████ S U B R O U T I N E ███████████████████████████████████████


CtrlProc$:      mov     (R2), R1        ; читаем регистр данных

1$:             tst     (R3)            ; ждём нового кода
                beq     1$
                mov     (R2), (R0)+     ; помещаем новый код в таблицу
                mov     #60000, R1
                sob     R1, .

2$:             tst     (R4)+           ; переходим к следующему пункту меню
                bne     2$
                mov     #Sound6$, R1
                trap    14              ; Вывод звука
                                        ; Вход R1 - адрес таблицы параметров
                                        ; .word длит
                                        ; .word тон, тон,... (0 - конец таблицы)
                call    @#SelCtrlMenu
                cmp     #20, (R4)       ; до звука дошли?
                bne     T32Loop$        ; нет, значит ещё не всё
                return
; End of function CtrlProc$


; ███████████████ S U B R O U T I N E ███████████████████████████████████████

; Вывод спрайта на экран movом
; Вход: R0 - адрес спрайта в памяти, первые 2 слова высота в строках и ширина в байтах
;       R1 - адрес экрана

Trap34:         mov     (R0)+, R2       ; берём высоту
                mov     (R0)+, R3       ; берём ширину
                mov     #100, R5
                sub     R3, R5
                mov     R3, 34.Width$

1$:             mov     (PC)+, R3
34.Width$:     .word 6

2$:             movb    (R0)+, (R1)+
                sob     R3, 2$
                add     R5, R1
                sob     R2, 1$
                return
; End of function Trap34


; ███████████████ S U B R O U T I N E ███████████████████████████████████████

; Вывод спрайта на экран методом наложения
; Вход: R0 - адрес спрайта в памяти, первые 2 слова высота в строках и ширина в байтах
;       R1 - адрес экрана

Trap36:         mov     (R0)+, R2
                mov     (R0)+, R3
                mov     #100, R5
                sub     R3, R5
                mov     R3, 36.Width$

1$:             mov     (PC)+, R3
36.Width$:     .word 4

2$:             bisb    (R0)+, (R1)+
                sob     R3, 2$
                add     R5, R1
                sob     R2, 1$
                return
; End of function Trap36


; ███████████████ S U B R O U T I N E ███████████████████████████████████████

; Стирание спрайта с экрана методом побитовой очистки
; Вход: R0 - адрес спрайта в памяти, первые 2 слова высота в строках и ширина в байтах
;       R1 - адрес экрана

Trap40:         mov     (R0)+, R2
                mov     (R0)+, R3
                mov     #100, R5
                sub     R3, R5
                mov     R3, 40.Width$

1$:             mov     (PC)+, R3
40.Width$:     .word 4

2$:             bicb    (R0)+, (R1)+
                sob     R3, 2$
                add     R5, R1
                sob     R2, 1$
                return
; End of function Trap40


; ███████████████ S U B R O U T I N E ███████████████████████████████████████

; Стирание спрайта с экрана clrом
; Вход: R0 - адрес спрайта в памяти, первые 2 слова высота в строках и ширина в байтах
;       R1 - адрес экрана

Trap42:         mov     (R0)+, R2
                mov     (R0)+, R3
                mov     #100, R5
                sub     R3, R5
                mov     R3, 42.Width$

1$:             mov     (PC)+, R3
42.Width$:     .word 6

2$:             clrb    (R1)+
                sob     R3, 2$
                add     R5, R1
                sob     R2, 1$
                return
; End of function Trap42


; ███████████████ S U B R O U T I N E ███████████████████████████████████████

; Вспомогательная функция функции Trap46

Trap44:         mov     (R0), R5
                beq     3$
                clrb    (R5)
                add     R2, (R0)
                bit     #77, (R0)
                bne     2$

1$:             clr     (R0)
                br      4$
; ───────────────────────────────────────────────────────────────────────────

2$:             cmp     #42300, (R0)
                bgt     1$
                cmp     #76000, (R0)
                ble     1$

3$:             bisb    #140, @(R0)+

4$:             sob     R1, Trap44
                return
; End of function Trap44


; ███████████████ S U B R O U T I N E ███████████████████████████████████████

; Вывод звёзд на экран

Trap46:         tst     (PC)+
T46Counter1:    .word 7
                bne     5$
                mov     #10, @#T46Counter1
                mov     #T46.Arr0, R0
                mov     #10, R1

1$:             tst     (R0)+
                beq     2$
                sob     R1, 1$
                br      6$
; ───────────────────────────────────────────────────────────────────────────

2$:             mov     @#177710, -(R0)
                com     #0
                beq     3$
                bic     #77, (R0)
                br      4$
; ───────────────────────────────────────────────────────────────────────────

3$:             bic     #177700, (R0)
4$:             add     #42300, (R0)

5$:             dec     @#T46Counter1

6$:             mov     #T46.Arr0, R0
                mov     #10, R1
                mov     (PC)+, R2
T46CntVal1:     .word 101
                trap    44
                tst     (PC)+
T46Counter2:    .word 5
                bne     15$
                mov     #10, @#T46Counter2
                mov     #T46.Arr1, R0
                mov     #10, R1

11$:            tst     (R0)+
                beq     12$
                sob     R1, 11$
                br      16$
; ───────────────────────────────────────────────────────────────────────────

12$:            mov     @#177710, -(R0)
                com     #0
                beq     13$
                bic     #77, (R0)
                br      14$
; ───────────────────────────────────────────────────────────────────────────

13$:            bic     #177700, (R0)
                add     #35000, (R0)

14$:            add     #42300, (R0)

15$:            dec     @#T46Counter2

16$:            mov     #T46.Arr1, R0
                mov     #10, R1
                mov     (PC)+, R2
T46CntVal2:     .word 101
                trap    44
                tst     (PC)+
T46Counter3:    .word 0
                bne     23$
                mov     #10, @#T46Counter3
                mov     #T46.Arr2, R0
                mov     #10, R1

21$:            tst     (R0)+
                beq     22$
                sob     R1, 21$
                br      24$
; ───────────────────────────────────────────────────────────────────────────

22$:            mov     @#177710, -(R0)
                bic     #77, (R0)
                add     #42300, (R0)

23$:            dec     @#T46Counter3

24$:            mov     #T46.Arr2, R0
                mov     #10, R1
                mov     (PC)+, R2
T46CntVal3:     .word 1
                trap    44
                tst     (PC)+
T46Counter4:    .word 2
                bne     33$
                mov     #10, @#T46Counter4
                mov     #T46.Arr3, R0
                mov     #10, R1

31$:            tst     (R0)+
                beq     32$
                sob     R1, 31$
                br      34$
; ───────────────────────────────────────────────────────────────────────────

32$:            mov     @#177710, -(R0)
                bic     #77, (R0)
                add     #42300, (R0)

33$:            dec     @#T46Counter4

34$:            mov     #T46.Arr3, R0
                mov     #10, R1
                mov     (PC)+, R2
T46CntVal4:     .word 2
                trap    44
                return
; End of function Trap46


; ███████████████ S U B R O U T I N E ███████████████████████████████████████

; Опрос клавиатуры 1

Trap50_1:       cmp     #100250, @#177716 ; клавиша нажата?
                bmi     Trap50_2        ; нет - выход
                mov     #KeyTab, R1     ; таблица управляющих клавиш
                mov     @#177662, R2    ; берём код нажатой клавиши
                mov     #GrowPlayerAddr, R3 ; Приращение адреса игрока
                cmp     R2, (R1)+       ; нажали вправо?
                bne     1$              ; нет
                add     #1, (R3)        ; двигаться вперёд
                                        
1$:             cmp     R2, (R1)+       ; нажали влево?
                bne     2$              ; нет
                add     #-1, (R3)       ; двигаться назад
                                        
2$:             cmp     R2, (R1)+       ; нажали вверх?
                bne     3$              ; нет
                add     #-400, (R3)     ; двигаться вверх
                                        
3$:             cmp     R2, (R1)+       ; нажали вниз?
                bne     4$              ; нет
                add     #300, (R3)      ; двигаться вниз
                                        
4$:             cmp     R2, (R1)+       ; нажали стрелять?
                bne     Trap50_2        ; нет
                mov     #1, @#FireFlag  ; Стрелять

Trap50_2:       return
; End of function Trap50_1


; ███████████████ S U B R O U T I N E ███████████████████████████████████████

; Опрос джойстика 1

Trap52_1:       tst     @#177714        ; джойстик нажат?
                beq     5$              ; нет - выход
                mov     #JoyTab, R1     ; таблица масок битов джойстика
                mov     @#177714, R2    ; берём данные с джойстика
                mov     #GrowPlayerAddr, R3 ; Приращение адреса игрока
                bit     R2, (R1)+       ; нажали вправо?
                beq     1$              ; да
                add     #1, (R3)        ; нет - компенсируем
                                        
1$:             bit     R2, (R1)+       ; нажали влево?
                beq     2$              ; да
                add     #-1, (R3)       ; нет - компенсируем
                                        
2$:             bit     R2, (R1)+       ; нажали вверх?
                beq     3$              ; да
                add     #-400, (R3)     ; нет - компенсируем
                                        
3$:             bit     R2, (R1)+       ; нажали вниз?
                beq     4$              ; да
                add     #300, (R3)      ; нет - компенсируем
                                        
4$:             bit     R2, (R1)+       ; нажали стрелять?
                beq     5$              ; нет
                mov     #1, @#FireFlag  ; Стрелять

5$:             return
; End of function Trap52_1

; ───────────────────────────────────────────────────────────────────────────
GrowPlayerAddr: .word 100               ; Приращение адреса игрока
FireFlag:       .word 0                 ; Флаг стрельбы
MoveSpeed:      .word 1                 ; Скорость передвижения
CurSprPlayer:   .word sprPlayerLt       ; Адрес текущего спрайта игрока
CurrVyhlopSpr:  .word sprVyhlopLt1      ; адрес текущего спрайта выхлопа игрока
; это структура параметров игрока
; размер 6 слов:
; 0 - адрес экрана
; 2,4 - два слова габаритов, для проверки на коллизию
; 6 - крепкость, т.е. сколько попаданий выдерживает
; для игрока так:
;   - мл.байт - ???
;   - ст.байт - флаг попадания в объект (коллизия)
; 10 - спрайт осколков
; 12 - смещение от адреса экрана - центр разлёта осколков
PlayerScrAddr:  .word 64724             ; Адрес спрайта игрока
                .word 2600, 4           ; габариты спрайта для сравнения на коллизию:
                                        ; высота в строках * 100, ширина в байтах
ObjForce:       .byte 0                 ; обычно, тут крепкость объекта
PlayerHit:      .byte 1                 ; 0 - есть попадание в игрока
                                        ; !0 - нет попадания
                .word sprRedBallBullet  ; спрайт осколков
                .word 1002              ; смещение от адреса экрана - центр разлёта осколков

sprBulletLt:    .word 3, 1
                .byte ^B11110000
                .byte ^B00111111
                .byte ^B11110000
                .even
sprBulletRt:    .word 3, 1
                .byte ^B00001111
                .byte ^B11111100
                .byte ^B00001111
                .even
strScore:       .asciz "SCORE"
                .even
strLive:        .asciz "LIVE"
                .even
strGuard:       .asciz "GUARD"
strGuardEnd:    .even

; Счёт, 8 разрядов, каждый байт - один разряд
Score:          .byte 0,0,0,0,0,1,0,2
EndScore:       .byte 377               ; байт-ограничитель
                .even
; Количество жизней, 2 разряда, каждый байт - один разряд
Lives:          .byte 0,7
EndLives:       .byte 377               ; байт-ограничитель
                .even
; Количество охранников, которых нужно уничтожить, 4 разряда, каждый байт - один разряд
Guard:          .byte 0,0,2,4
EndGuard:       .byte 377               ; байт-ограничитель
                .even
                .word 0
; буфер размером 14 слов
Buffer2:        .word 37215
                .word 177401
                .word 177777
                .word 177777
                .word 177777
                .word 177777
                .word 177777
                .word 177777
                .word 177777
                .word 177777
                .word 177777
                .word 177777
Buffer2End:
Buffer2SizeW = <Buffer2End - Buffer2>/2
; буфер пушек размером 42 байта
; тут хранятся ???
; бит 6 (0100) - признак подбитой пушки
CannonBufSize = 34.
CannonBufInitPos = 16.
CannonBuffer:   .byte   2
                .byte  30,   2,   2,   2,   2,   2,   2,   2
                .byte   2,   2,   2,   2,   2,  14,  14,  14
                .byte 114, 114, 130,  30,  30,  20,   2,   2
                .byte   2,   2,   2,   2,   2,   2,   2,   2
                .byte   2

; ███████████████ S U B R O U T I N E ███████████████████████████████████████


sub_6662:       mov     6(R5), 10(R1)
                return
; End of function sub_6662

; ───────────────────────────────────────────────────────────────────────────
word_6672:      .word 51646             ; DATA XREF: sub_15410o
                .word 3300
                .word 3
                .word 177777
                .word sprParticle2
                .word 1101
                .word 0
Sound7$:        .word 4
                .word 2000
                .word 1000
                .word 400
                .word 100
                .word 0
                .word 0
                .word 0
                .word 0
                .word 0
                .word FONT + <'П - 100>*10. + 1 ; ПАУЗА-СБР (не используется)
                .word FONT + <'А - 100>*10. + 1
                .word FONT + <'У - 100>*10. + 1
                .word FONT + <'З - 100>*10. + 1
                .word FONT + <'А - 100>*10. + 1
                .word FONT + <'- - 40>*10. + 1
                .word FONT + <'С - 100>*10. + 1
                .word FONT + <'Б - 100>*10. + 1
                .word FONT + <'Р - 100>*10. + 1
                .word 0
SoundPlayerShoot:.word 6
                .word 37
                .word 200
                .word 60
                .word 0
                .word 0
                .word 0
                .word 0
; ───────────────────────────────────────────────────────────────────────────

DrawMenu$:      call    @#Trap70        ; Очистка экрана
                trap    24              ; Вывод три зелёных полосы и на них копирайт спрайтами
                mov     #sprPlanetTxt, R0
                mov     #44000, R1
                mov     #14, R2

1$:             mov     #20, R3

2$:             mov     #4, R4
                movb    (R0)+, R5

3$:             clrb    (R1)
                ror     R5
                bcc     4$
                bisb    #52525, (R1)

4$:             ror     R5
                bcc     5$
                bisb    #125252, (R1)

5$:             inc     R1
                sob     R4, 3$
                sob     R3, 2$
                mov     #500, R3
                add     #0, R1

6$:             movb    -100(R1), (R1)+
                sob     R3, 6$
                sob     R2, 1$
                mov     #MainMenu$, R4
                mov     #3, R1
                clr     R0
                trap    26              ; Вывод и обработка меню
                                        ; Вход: R0 - номер начального пункта меню
                                        ;       R1 - номер последнего пункта меню
                                        ;       R4 - адрес параметров меню
                                        ; Выход: R0 - выбранный пункт меню
                dec     R0              ; 0 - игра, 1 - управление, 2 - информация, 3 - выход
                bne     7$
                jmp     @#SetControls
; ───────────────────────────────────────────────────────────────────────────

7$:             dec     R0
                beq     ShowInfo
                dec     R0
                bne     8$
                call    @#GoExit

8$:             jmp     @#StartGame
; ───────────────────────────────────────────────────────────────────────────

ShowInfo:       mov     #40, R0
                mov     #77700, (R0)+
                mov     #datInfo$, (R0)+
                mov     #372, (R0)+
                mov     #10000, (R0)+
                trap    2               ; Вывод информации на экран
                                        ; Вход: блок параметров по адресу 40:
                                        ; .word адрес экрана
                                        ; .word адрес данных
                                        ; .word маска цвета
                                        ; .word задержка
                trap    24              ; Вывод три зелёных полосы и на них копирайт спрайтами
                trap    72              ; Ждать нажатия чего-нибудь
                nop
                jmp     @#DrawMenu$
; ───────────────────────────────────────────────────────────────────────────

SetControls:    mov     #42000, R1
                mov     #73567, R0
                clr     R4
                mov     #40, R2
                mov     #170, R3
                trap    30              ; Заполнение прямоугольной области экрана заданным цветом
                                        ; Вход: R1 - адрес экрана
                                        ;       R2 - ширина в байтах
                                        ;       R3 - высота в строках / 2
                                        ;       R0,R4 - чересстрочные цвета
                mov     #52412, R1
                clr     R0
                mov     #26, R2
                mov     #60, R3
                trap    30              ; Заполнение прямоугольной области экрана заданным цветом
                                        ; Вход: R1 - адрес экрана
                                        ;       R2 - ширина в байтах
                                        ;       R3 - высота в строках / 2
                                        ;       R0,R4 - чересстрочные цвета
                mov     #CtrlsMenu, R4
                mov     #2, R1
                trap    26              ; Вывод и обработка меню
                                        ; Вход: R0 - номер начального пункта меню
                                        ;       R1 - номер последнего пункта меню
                                        ;       R4 - адрес параметров меню
                                        ; Выход: R0 - выбранный пункт меню
                mov     #52312, R1
                mov     #73567, R4
                dec     R0
                beq     SetJoystick$
                dec     R0
                bne     SetKeyboard$
                trap    30              ; Заполнение прямоугольной области экрана заданным цветом
                                        ; Вход: R1 - адрес экрана
                                        ;       R2 - ширина в байтах
                                        ;       R3 - высота в строках / 2
                                        ;       R0,R4 - чересстрочные цвета
                br      ExitControls$
; ───────────────────────────────────────────────────────────────────────────

SetKeyboard$:   mov     #NextSetKbd$, -(SP)

; ███████████████ S U B R O U T I N E ███████████████████████████████████████


sub_7316:       clr     R0
                trap    30              ; Заполнение прямоугольной области экрана заданным цветом
                                        ; Вход: R1 - адрес экрана
                                        ;       R2 - ширина в байтах
                                        ;       R3 - высота в строках / 2
                                        ;       R0,R4 - чересстрочные цвета
                clr     R4
                mov     #51406, R1
                mov     #32, R2
                mov     #74, R3
                trap    30              ; Заполнение прямоугольной области экрана заданным цветом
                                        ; Вход: R1 - адрес экрана
                                        ;       R2 - ширина в байтах
                                        ;       R3 - высота в строках / 2
                                        ;       R0,R4 - чересстрочные цвета
                return
; End of function sub_7316

; ───────────────────────────────────────────────────────────────────────────

NextSetKbd$:    mov     #KeyTab, R0
                mov     #177660, R3
                mov     R3, R2
                tst     (R2)+
                br      1Next$
; ───────────────────────────────────────────────────────────────────────────

SetJoystick$:   call    @#sub_7316
                mov     #JoyTab, R0
                mov     #177714, R2
                mov     R2, R3

1Next$:         mov     #5, R1
                mov     #MenuCtrls2, R4
                trap    32              ; Вывод и обработка меню для задания управления
                                        ; Вход: R2 - регистр данных
                                        ;       R3 - регистр управления
                                        ;       R4 - адрес блока параметров меню
                br      SetControls
; ───────────────────────────────────────────────────────────────────────────

ExitControls$:  clr     R0
                clr     R4
                mov     #47412, R1
                mov     #26, R2
                mov     #20, R3
                trap    30              ; Заполнение прямоугольной области экрана заданным цветом
                                        ; Вход: R1 - адрес экрана
                                        ;       R2 - ширина в байтах
                                        ;       R3 - высота в строках / 2
                                        ;       R0,R4 - чересстрочные цвета
                mov     #60004, R1
                mov     #34, R2
                mov     #50, R3
                trap    30              ; Заполнение прямоугольной области экрана заданным цветом
                                        ; Вход: R1 - адрес экрана
                                        ;       R2 - ширина в байтах
                                        ;       R3 - высота в строках / 2
                                        ;       R0,R4 - чересстрочные цвета
                mov     #40, R5
                mov     #50114, (R5)+
                jmp     @#NextExitCtrls$
; ───────────────────────────────────────────────────────────────────────────
                .word 0
Menu3:          .word 61406
                .word 32
                .word FONT + <'О - 100>*10. + 1
                .word FONT + <'Т - 100>*10. + 1
                .word FONT + <'  - 040>*10. + 1
                .word FONT + <'К - 100>*10. + 1
                .word FONT + <'Л - 100>*10. + 1
                .word FONT + <'А - 100>*10. + 1
                .word FONT + <'В - 100>*10. + 1
                .word FONT + <'И - 100>*10. + 1
                .word FONT + <'А - 100>*10. + 1
                .word FONT + <'Т - 100>*10. + 1
                .word FONT + <'У - 100>*10. + 1
                .word FONT + <'Р - 100>*10. + 1
                .word FONT + <'Ы - 100>*10. + 1
                .word 0
                .word 64010
                .word 30
                .word FONT + <'О - 100>*10. + 1
                .word FONT + <'Т - 100>*10. + 1
                .word FONT + <'  - 040>*10. + 1
                .word FONT + <'Д - 100>*10. + 1
                .word FONT + <'Ж - 100>*10. + 1
                .word FONT + <'О - 100>*10. + 1
                .word FONT + <'И - 100>*10. + 1
                .word FONT + <'С - 100>*10. + 1
                .word FONT + <'Т - 100>*10. + 1
                .word FONT + <'И - 100>*10. + 1
                .word FONT + <'К - 100>*10. + 1
                .word FONT + <'А - 100>*10. + 1
                .word 0
                .word 66410
                .word 30
                .word FONT + <'П - 100>*10. + 1
                .word FONT + <'А - 100>*10. + 1
                .word FONT + <'Р - 100>*10. + 1
                .word FONT + <'А - 100>*10. + 1
                .word FONT + <'Л - 100>*10. + 1
                .word FONT + <'Л - 100>*10. + 1
                .word FONT + <'Е - 100>*10. + 1
                .word FONT + <'Л - 100>*10. + 1
                .word FONT + <'Ь - 100>*10. + 1
                .word FONT + <'Н - 100>*10. + 1
                .word FONT + <'О - 100>*10. + 1
                .word FONT + <'Е - 100>*10. + 1
                .word 0
                .word 20
                .word 1000
                .word 300
                .word 1000
                .word 0
CtrlMode:       .word 2                 ; режим управления: 0 - от клавиатуры
                                        ;                   1 - от джойстика
                                        ;                   2 - клавиатура + джойстик
strControl:     .word FONT + <'У - 100>*10. + 1
                .word FONT + <'П - 100>*10. + 1
                .word FONT + <'Р - 100>*10. + 1
                .word FONT + <'А - 100>*10. + 1
                .word FONT + <'В - 100>*10. + 1
                .word FONT + <'Л - 100>*10. + 1
                .word FONT + <'Е - 100>*10. + 1
                .word FONT + <'Н - 100>*10. + 1
                .word FONT + <'И - 100>*10. + 1
                .word FONT + <'Е - 100>*10. + 1
                .word 0

JoyTab:         .word 1
                .word 2
                .word 4
                .word 10
                .word 40

KeyTab:         .word 31
                .word 10
                .word 32
                .word 33
                .word 40

Sound6$:        .word 22
                .word 30
                .word 500
                .word 300
                .word 500
                .word 0
Sound4$:        .word 20
                .word 1000
                .word 200
                .word 0
; ───────────────────────────────────────────────────────────────────────────
                mov     #40000, (SP)
                jmp     @#100140
; ───────────────────────────────────────────────────────────────────────────

SkipSplash1$:   nop
                mov     #1330, @#177664
                mov     #VecKbdNo$, @#60
                mov     #VecKbdNo$, @#274
                jmp     @#DrawMenu$
; ───────────────────────────────────────────────────────────────────────────

TrapTo4:        mov     #760, SP

; Начальная инициализация
Init$:          mov     #TrapTo4, @#4
                mov     #DisTrap, @#34
                clr     @#36
                mov     #20, @#177712
                mov     #34000, @#177706
                mov     #SprBILun$, R0  ; Аргумент п/п sub_15552
                mov     #760, SP
                nop
                mov     #1330, @#177664

MorphBR$:       br      .+2             ; этот BR правится, чтобы пропускать начальную заставку
                nop
                nop
                nop
                call    @#sub_15552
                sob     R2, .
                clr     @#177660
                mtps    #0
                mov     @#177662, R0
                mov     #SkipSplash$, @#60
                mov     #SkipSplash$, @#274
                mov     #StartSplash$, -(SP)

; ███████████████ S U B R O U T I N E ███████████████████████████████████████

; Очистка экрана

Trap70:         mov     #40000, R1
                mov     R1, R2
                mov     #77700, R3
                mov     #40, R4

1$:             clr     (R2)+
                clr     (R3)+
                sob     R4, 1$
                mov     #40077, R0
                mov     #377, R2

2$:             mov     #1164, R3

3$:             bicb    R2, (R0)
                bicb    R2, (R1)
                add     #32, R0
                add     #32, R1
                sob     R3, 3$
                cmp     #323, R2
                beq     4$
                sub     #37711, R0
                sub     #37707, R1
                sob     R2, 2$

4$:             return
; End of function Trap70

; ───────────────────────────────────────────────────────────────────────────
; тут непонятно с чего к пробелам надо 2 прибавлять
strSplashTxt1:  .word FONT + <'A - 040>*10. + 1
                .word FONT + <'N - 040>*10. + 1
                .word FONT + <'L - 040>*10. + 1
                .word FONT + <'E - 040>*10. + 1
                .word FONT + <'P - 040>*10. + 1
                .word FONT + <'T - 040>*10. + 1
                .word FONT + <'  - 040>*10. + 2
                .word FONT + <'  - 040>*10. + 2
                .word FONT + <'  - 040>*10. + 2
                .word FONT + <'  - 040>*10. + 2
                .word FONT + <'* - 040>*10. + 1
                .word FONT + <'* - 040>*10. + 1
                .word FONT + <'* - 040>*10. + 1
                .word FONT + <'* - 040>*10. + 1
                .word FONT + <'  - 040>*10. + 2
                .word FONT + <'  - 040>*10. + 2
; ───────────────────────────────────────────────────────────────────────────

StartSplash$:   mov     #strSplashTxt1, R4
                trap    16              ; Анимация заставки
                                        ; Вход: R4 - адрес текста
                br      NextSplash$
; ───────────────────────────────────────────────────────────────────────────
strSplashTxt2:  .asciz "БОРТНИК  БОРИС"
strSplashTxt2e: .even
                .word 0
; ───────────────────────────────────────────────────────────────────────────

NextSplash$:    mov     #41004, R1
                mov     #strSplashTxt2, R2
                mov     #162000, @#44
                mov     #3, @#46
                trap    22              ; Вывод текста буквами тырк-тырк влево-вправо
                                        ; Вход: R1 - адрес экрана
                                        ;       R2 - адрес текста
                                        ;       @#44 - маска цвета для 1 бита символа
                                        ;       @#46 - масштаб по высоте
                mov     #47200, R1
                mov     #strSplashTxt3, @#46
                br      NextSplash1$
; ───────────────────────────────────────────────────────────────────────────
strSplashTxt3:  .byte 5, 231
                .asciz "г.МОСКВА"
strSplashTxt3e: .even
; ───────────────────────────────────────────────────────────────────────────

NextSplash1$:   trap    6               ; Вывод текста сложного формата на экран
                                        ; Вход: R1 - адрес экрана
                                        ;       @#46 - адрес массива данных
                sob     R0, .
                sob     R0, .
                sob     R0, .

                mov     #40040, R1
                mov     #364, R2
                mov     #20, R3
                clr     @#46
                trap    20              ; Вывод падающей каплей буквы
                                        ; Вход: R1 - адрес экрана
                                        ;       R2 - высота падения
                                        ;       R3 - код буквы - 20
                call    @#Trap70        ; Очистка экрана
                mov     #40, R0
                mov     #146314, (R0)+
                mov     #42020, (R0)+
                mov     #77700, (R0)+
                mov     #datText9, (R0)+
                mov     #126664, (R0)+
                mov     #12, (R0)+
                mov     #3, (R0)+       ; номер игры
                mov     #40, (R0)+
                mov     #60000, @#64
                trap    0               ; Вывод слова GAME и цифры 3
                                        ; Вход: @#40 - блок параметров (адрес слова и номер цифры)
                br      NextSplash2$
; ───────────────────────────────────────────────────────────────────────────
datText9:       .word FONT + <'G - 040>*10. + 1
                .word FONT + <'A - 040>*10. + 1
                .word FONT + <'M - 040>*10. + 1
                .word FONT + <'E - 040>*10. + 1
                .word 0
; ───────────────────────────────────────────────────────────────────────────

NextSplash2$:   mov     #1400, R2
                mov     R2, R3
                call    @#102062

SkipSplash$:    jmp     @#SkipSplash1$
; ───────────────────────────────────────────────────────────────────────────
; Спрайт  названия игры
sprPlanetTxt:   .byte 252,252,202,52, 0, 0,240,252,250,202,52,252,252,242,252,252
                .byte 377,377,312,57, 0, 0,370,277,374,312,57,377,377,362,377,277
                .byte 277,360,313,57, 0, 0,276,277,374,313,57,277,360,362,376,276
                .byte 277,360,313,57, 0,200,57,277,374,313,57,277,300,262,374,262
                .byte 277,360,313,57, 0,340,13,277,374,357,57,277,50, 0,374, 2
                .byte 277,360,313,57, 0,360,13,277,374,356,57,277,56, 0,374, 2
                .byte 277,372,313,57, 0,360,253,277,374,356,57,377,57, 0,374, 2
                .byte 377,377,302,57,240,362,377,277,374,356,57,277,54, 0,374, 2
                .byte 277, 0,300,57,370,362,13,277,374,376,57,277,200, 2,374, 2
                .byte 277, 0,300,57,376,362,13,277,374,362,57,277,340, 2,374, 2
                .byte 277, 0,300,257,377,362,13,277,374,362,57,277,372, 2,374, 2
                .byte 277, 0,300,377,377,362,13,277,374,302,57,377,377, 2,374, 2
datText10:      .byte 30, 231
                .asciz "END"
datText10End:   .even
AddrText11:     .word 74002             ; адрес вывода строки
                .word 0
datText11:      .asciz "СТОП ─ ЗАСТАВКА" ; вот этой строки
datText11End:   .even


; ───────────────────────────────────────────────────────────────────────────

NextFinal4$:    mov     #44024, R1
                mov     #datText10, @#46
                trap    6               ; Вывод текста сложного формата на экран
                                        ; Вход: R1 - адрес экрана
                                        ;       @#46 - адрес массива данных
                mov     #175000, @#44
                mov     #AddrText11, R5 ; адрес, где находится адрес экрана
                mov     #datText11, R2  ; адрес текста
                call    @#sub_37024
                mov     #TrapTo4, @#4
                jmp     @#DrawMenu$
; ───────────────────────────────────────────────────────────────────────────
                .word 0
                .word 0
MainMenu$:      .word 62030
                .word 10
                .word FONT + <'И - 100>*10. + 1
                .word FONT + <'Г - 100>*10. + 1
                .word FONT + <'Р - 100>*10. + 1
                .word FONT + <'А - 100>*10. + 1
                .word 0
                .word 64414
                .word 24
                .word FONT + <'У - 100>*10. + 1
                .word FONT + <'П - 100>*10. + 1
                .word FONT + <'Р - 100>*10. + 1
                .word FONT + <'А - 100>*10. + 1
                .word FONT + <'В - 100>*10. + 1
                .word FONT + <'Л - 100>*10. + 1
                .word FONT + <'Е - 100>*10. + 1
                .word FONT + <'Н - 100>*10. + 1
                .word FONT + <'И - 100>*10. + 1
                .word FONT + <'Е - 100>*10. + 1
                .word 0
                .word 67014
                .word 24
                .word FONT + <'И - 100>*10. + 1
                .word FONT + <'Н - 100>*10. + 1
                .word FONT + <'Ф - 100>*10. + 1
                .word FONT + <'О - 100>*10. + 1
                .word FONT + <'Р - 100>*10. + 1
                .word FONT + <'М - 100>*10. + 1
                .word FONT + <'А - 100>*10. + 1
                .word FONT + <'Ц - 100>*10. + 1
                .word FONT + <'И - 100>*10. + 1
                .word FONT + <'Я - 100>*10. + 1
                .word 0
                .word 71426
                .word 12
                .word FONT + <'В - 100>*10. + 1
                .word FONT + <'Ы - 100>*10. + 1
                .word FONT + <'Х - 100>*10. + 1
                .word FONT + <'О - 100>*10. + 1
                .word FONT + <'Д - 100>*10. + 1
                .word 0
                .word 5                 ; звук сразу за меню
                .word 1400
                .word 1600
                .word 1000
                .word 0
Sound3$:        .word 14
                .word 700
                .word 400
                .word 100
                .word 0
NShooting:      .word 0                 ; Количество выстреливаемых очередей
datInfo$:
                .byte 40, 10, 14
                .ascii "ВАША ЗАДАЧА:"
                .byte 30, 14, 12
                .ascii "УНИЧТОЖИТЬ"
                .byte 4, 2, 17
                .ascii "ОХРАНУ ПЛАНЕТЫ,"
                .byte 4, 4, 16
                .ascii "ЧТОБЫ СЕСТЬ НА"
                .byte 4, 4, 16
                .ascii "ЕЕ ПОВЕРХНОСТЬ"
                .byte 4, 10, 14
                .ascii "И НАИТИ ВХОД"
                .byte 4, 20, 10
                .ascii "В ШАХТУ."
                .byte 20, 24, 6
                .ascii "ЖИЗНИ,"
                .byte 4, 0, 20
                .ascii "СКОРОСТЬ ПОЛЕТА,"
                .byte 4, 2, 17
                .ascii "ЧИСЛО И ЧАСТОТУ"
                .byte 4, 6, 15
                .ascii "ВЫСТРЕЛИВАНИЯ"
                .byte 4, 26, 5
                .ascii "МОЖНО"
                .byte 4, 0, 20
                .ascii "УВЕЛИЧИВАТЬ,ЛОВЯ"
                .byte 4, 4, 16
                .ascii "БУКВЫ: L S N F"
                .byte 4, 2, 17
                .ascii "СООТВЕТСТВЕННО."
                .byte 20, 0, 0
                .byte 0
                .word 0
CtrlsMenu:      .word 55014
                .word 24
                .word FONT + <'К - 100>*10. + 1
                .word FONT + <'Л - 100>*10. + 1
                .word FONT + <'А - 100>*10. + 1
                .word FONT + <'В - 100>*10. + 1
                .word FONT + <'И - 100>*10. + 1
                .word FONT + <'А - 100>*10. + 1
                .word FONT + <'Т - 100>*10. + 1
                .word FONT + <'У - 100>*10. + 1
                .word FONT + <'Р - 100>*10. + 1
                .word FONT + <'А - 100>*10. + 1
                .word 0
                .word 57420
                .word 20
                .word FONT + <'Д - 100>*10. + 1
                .word FONT + <'Ж - 100>*10. + 1
                .word FONT + <'О - 100>*10. + 1
                .word FONT + <'И - 100>*10. + 1
                .word FONT + <'С - 100>*10. + 1
                .word FONT + <'Т - 100>*10. + 1
                .word FONT + <'И - 100>*10. + 1
                .word FONT + <'К - 100>*10. + 1
                .word 0
                .word 62026
                .word 12
                .word FONT + <'В - 100>*10. + 1
                .word FONT + <'Ы - 100>*10. + 1
                .word FONT + <'Х - 100>*10. + 1
                .word FONT + <'О - 100>*10. + 1
                .word FONT + <'Д - 100>*10. + 1
                .word 0
                .word 20                ; звук меню
                .word 200
                .word 200
                .word 200
                .word 1000
                .word 0
MenuCtrls2:     .word 52610
                .word FONT + <'1 - 040>*10. + 1
                .word FONT + <'  - 040>*10. + 1
                .word FONT + <'Д - 100>*10. + 1
                .word FONT + <'В - 100>*10. + 1
                .word FONT + <'И - 100>*10. + 1
                .word FONT + <'Ж - 100>*10. + 1
                .word FONT + <'Е - 100>*10. + 1
                .word FONT + <'Н - 100>*10. + 1
                .word FONT + <'И - 100>*10. + 1
                .word FONT + <'Е - 100>*10. + 1
                .word FONT + <'  - 040>*10. + 1
                .word 112171
                .word 0
                .word 55210
                .word FONT + <'2 - 040>*10. + 1
                .word FONT + <'  - 040>*10. + 1
                .word FONT + <'Д - 100>*10. + 1
                .word FONT + <'В - 100>*10. + 1
                .word FONT + <'И - 100>*10. + 1
                .word FONT + <'Ж - 100>*10. + 1
                .word FONT + <'Е - 100>*10. + 1
                .word FONT + <'Н - 100>*10. + 1
                .word FONT + <'И - 100>*10. + 1
                .word FONT + <'Е - 100>*10. + 1
                .word FONT + <'  - 040>*10. + 1
                .word 112051
                .word 0
                .word 57610
                .word FONT + <'3 - 040>*10. + 1
                .word FONT + <'  - 040>*10. + 1
                .word FONT + <'Д - 100>*10. + 1
                .word FONT + <'В - 100>*10. + 1
                .word FONT + <'И - 100>*10. + 1
                .word FONT + <'Ж - 100>*10. + 1
                .word FONT + <'Е - 100>*10. + 1
                .word FONT + <'Н - 100>*10. + 1
                .word FONT + <'И - 100>*10. + 1
                .word FONT + <'Е - 100>*10. + 1
                .word FONT + <'  - 040>*10. + 1
                .word 112203
                .word 0
                .word 62210
                .word FONT + <'4 - 040>*10. + 1
                .word FONT + <'  - 040>*10. + 1
                .word FONT + <'Д - 100>*10. + 1
                .word FONT + <'В - 100>*10. + 1
                .word FONT + <'И - 100>*10. + 1
                .word FONT + <'Ж - 100>*10. + 1
                .word FONT + <'Е - 100>*10. + 1
                .word FONT + <'Н - 100>*10. + 1
                .word FONT + <'И - 100>*10. + 1
                .word FONT + <'Е - 100>*10. + 1
                .word FONT + <'  - 040>*10. + 1
                .word 112215
                .word 0
                .word 64610
                .word FONT + <'5 - 040>*10. + 1
                .word FONT + <'  - 040>*10. + 1
                .word FONT + <'В - 100>*10. + 1
                .word FONT + <'Ы - 100>*10. + 1
                .word FONT + <'С - 100>*10. + 1
                .word FONT + <'Т - 100>*10. + 1
                .word FONT + <'Р - 100>*10. + 1
                .word FONT + <'Е - 100>*10. + 1
                .word FONT + <'Л - 100>*10. + 1
                .word 0
                .word 20
                .word 500
                .word 1000
                .word 300
                .word 0
; ───────────────────────────────────────────────────────────────────────────

NextExitCtrls$: mov     #strControl, (R5)+
                mov     #124000, (R5)+
                mov     #2, (R5)+
                trap    12              ; Вывод текста
                                        ; Вход: блок параметров по адресу 40
                                        ; .word адрес экрана
                                        ; .word адрес данных (таблица адресов символов в шрифте)
                                        ; .word маска цвета для 1 бита символа
                                        ; .word масштаб по высоте
                mov     #2, R1
                mov     #Menu3, R4
                trap    26              ; Вывод и обработка меню
                                        ; Вход: R0 - номер начального пункта меню
                                        ;       R1 - номер последнего пункта меню
                                        ;       R4 - адрес параметров меню
                                        ; Выход: R0 - выбранный пункт меню
                mov     R0, @#CtrlMode  ; режим управления: 0 - от клавиатуры
                                        ;                   1 - от джойстика
                                        ;                   2 - клавиатура + джойстик
                jmp     @#DrawMenu$
; ───────────────────────────────────────────────────────────────────────────
                .word 0
                .word 0
T46.Arr0:       .word 42455
                .word 73026
                .word 64055
                .word 71775
                .word 50435
                .word 44452
                .word 52511
                .word 0
T46.Arr1:       .word 61717
                .word 0
                .word 55273
                .word 67753
                .word 0
                .word 0
                .word 0
                .word 0
T46.Arr2:       .word 61724
                .word 42610
                .word 56266
                .word 67656
                .word 73416
                .word 0
                .word 52676
                .word 72054
T46.Arr3:       .word 62014
                .word 0
                .word 62760
                .word 63740
                .word 56330
                .word 0
                .word 0
                .word 0

sprPlayerRt:    .word 27, 4
                .byte 114, 5, 0, 0
                .byte 123, 125, 25, 0
                .byte 120, 25, 0, 0
                .byte 123, 77, 0, 0
                .byte 120, 35, 0, 0
                .byte 103, 5, 0, 0
                .byte 14, 65, 12, 0
                .byte 103, 363, 10, 40
                .byte 114, 217, 252, 252
                .byte 103, 377, 52, 0
                .byte 114, 374, 373, 0
                .byte 103, 3, 0, 0
                .byte 14, 375, 77, 0
                .byte 63, 124, 125, 0
                .byte 314, 120, 125, 1
                .byte 60, 3, 124, 1
                .byte 0, 314, 120, 1
                .byte 0, 60, 123, 1
                .byte 0, 300, 120, 1
                .byte 0, 0, 123, 3
                .byte 0, 300, 320, 15
                .byte 0, 0, 163, 167
                .byte 0, 0, 374, 377
sprPlayerLt:    .word 27, 4
                .byte 0, 0, 120, 61
                .byte 0, 124, 125, 305
                .byte 0, 0, 124, 5
                .byte 0, 0, 374, 305
                .byte 0, 0, 164, 5
                .byte 0, 0, 120, 301
                .byte 0, 240, 134, 60
                .byte 10, 40, 317, 301
                .byte 252, 252, 362, 61
                .byte 0, 250, 377, 301
                .byte 0, 357, 77, 61
                .byte 0, 0, 300, 301
                .byte 0, 374, 177, 60
                .byte 0, 125, 25, 314
                .byte 100, 125, 5, 63
                .byte 100, 25, 300, 14
                .byte 100, 5, 63, 0
                .byte 100, 305, 14, 0
                .byte 100, 5, 3, 0
                .byte 300, 305, 0, 0
                .byte 160, 7, 3, 0
                .byte 335, 315, 0, 0
                .byte 377, 77, 0, 0
sprVyhlopRt1:   .word 10, 2
                .word ^B0000000010000000
                .word ^B0000000000100000
                .word ^B0000001101000000
                .word ^B0010110111100000
                .word ^B0010101101110000
                .word ^B0000000010001000
                .word ^B0000000000100000
                .word ^B0000000000000010
sprVyhlopRt2:   .word 10, 2
                .word ^B0000000010000000
                .word ^B0000000000100000
                .word ^B0000011011000000
                .word ^B0010110001111000
                .word ^B0010001011000000
                .word ^B0000101100000010
                .word ^B0000001000000000
                .word ^B0000000010000000
sprVyhlopLt1:   .word 10, 2
                .word ^B0000001000000000
                .word ^B0000100000000000
                .word ^B0000000111000000
                .word ^B0000101101111000
                .word ^B0000110111101000
                .word ^B0010001000000000
                .word ^B0000100000000000
                .word ^B1000000000000000
sprVyhlopLt2:   .word 10, 2
                .word ^B0000001000000000
                .word ^B0000100000000000
                .word ^B0000001110010000
                .word ^B0010110100111000
                .word ^B0000001110001000
                .word ^B1000000011100000
                .word ^B0000000010000000
                .word ^B0000001000000000
SprVyhlopSize = sprVyhlopRt2 - sprVyhlopRt1
; ───────────────────────────────────────────────────────────────────────────

StartGame:      mov     #40000, R1
                mov     #strScore, R2
                mov     #110000, @#44
                clr     @#46
                trap    22              ; Вывод текста буквами тырк-тырк влево-вправо
                                        ; Вход: R1 - адрес экрана
                                        ;       R2 - адрес текста
                                        ;       @#44 - маска цвета для 1 бита символа
                                        ;       @#46 - масштаб по высоте
                add     #31, R1
                add     #6, R2
                trap    22              ; Вывод текста буквами тырк-тырк влево-вправо
                                        ; Вход: R1 - адрес экрана
                                        ;       R2 - адрес текста
                                        ;       @#44 - маска цвета для 1 бита символа
                                        ;       @#46 - масштаб по высоте
                add     #23, R1
                add     #6, R2
                trap    22              ; Вывод текста буквами тырк-тырк влево-вправо
                                        ; Вход: R1 - адрес экрана
                                        ;       R2 - адрес текста
                                        ;       @#44 - маска цвета для 1 бита символа
                                        ;       @#46 - масштаб по высоте

RestartGame:    bis     #6, @#MorphBR$   ; глушим появления экрана "BREAK IDEA LEADER"
                                        ; чтобы больше не появлялось
                nop
                nop
                nop
                mov     #40700, R0      ; очистка экрана
1$:             clr     (R0)+
                tst     R0
                bpl     1$

                mov     #EndScore+2, R5
                mov     #377, -(R5)     ; обнуление счёта
                mov     #4, R1
2$:             clr     -(R5)
                sob     R1, 2$
                add     #41002, R1      ; Выводим счёт
                trap    60              ; Вывод числовых значений счёта, жизней и т.п.
                                        ; Вход: R5 - адрес данных
                                        ;       R1 - адрес экрана
                mov     #Lives, R5
                mov     #1, (R5)
                mov     #41036, R1      ; Выводим жизни
                trap    60              ; Вывод числовых значений счёта, жизней и т.п.
                                        ; Вход: R5 - адрес данных
                                        ;       R1 - адрес экрана
                mov     #EndGuard, R5
                mov     #2, -(R5)
                clr     -(R5)
                mov     #41062, R1      ; Выводим кол-во охранников
                trap    60              ; Вывод числовых значений счёта, жизней и т.п.
                                        ; Вход: R5 - адрес данных
                                        ;       R1 - адрес экрана

                mov     #100000, R0     ; Рисуем подложку
                mov     #200, R3
3$:             mov     #125252, -(R0)
                sob     R3, 3$

                mov     #400, @#ObjForce ; инициализация флагов попадания в игрока
                mov     #56636, @#PlayerScrAddr ; Адрес спрайта игрока
                mov     #0, @#word_23536
                mov     #75037, @#word_23534
                mov     #1, @#Buf2Mask$
                mov     #Buffer2, @#Buf2Ptr$

                mov     @#66, R0        ; !!! вот секретная часть, там число 23540 = TreeBuffer
                mov     #TreeBufferSizeW, R1
4$:             clr     (R0)+
                sob     R1, 4$

                mov     #Buffer2, R0
                mov     #Buffer2SizeW, R1
5$:             mov     #-1, (R0)+
                sob     R1, 5$

                mov     #CannonBuffer+CannonBufInitPos, @#CannonBufPtr
                mov     #6, @#NewCannonCnt
                clr     @#CannonStruct
                mov     #CannonBuffer, R0
                mov     #CannonBufSize, R1
6$:             bicb    #100, (R0)+
                sob     R1, 6$

                mov     #ScratchBuffer+2, R0

7$:             mov     #3000, (R0)+
                add     #20, R0
                cmp     #10705, (R0)+   ; !!! это опкод программы, которая начинается сразу за массивом
                bne     7$

                clr     @#LiveBoxScrAddr
                clr     @#SpeedBoxScrAddr
                mov     #1, R0
                mov     R0, @#LiveBoxDelay
                mov     R0, @#SpeedBoxDelay
                clr     @#NBoxScrAddr
                mov     R0, @#NBoxDelay
                clr     @#ForceBoxScrAddr
                mov     R0, @#ForceBoxDelay
                call    @#InitAchievs   ; Инициализация ачивок
                call    @#InitRoger

                mov     #BlockBuf, R5
                mov     #BlockBufItemsNum, R4
8$:             clr     (R5)+
                mov     #13, (R5)+
                sob     R4, 8$

                mov     #2000, @#BlockBOutCnt
                mov     #60000, @#100

                mov     #GuardsBuffer, R0
                mov     #GuardsBufferSize, R1
9$:             clrb    (R0)+
                sob     R1, 9$

                mov     #Trap50_1, @#off_Trp50s ; Опрос клавиатуры 1
                mov     #Trap52_1, @#off_Trp52s ; Опрос джойстика 1

                mov     #EnemyBulletBuffer, R0
                mov     #AllBuffersSize, R1
10$:            clrb    (R0)+
                sob     R1, 10$

                mov     #1, @#MoveSpeed ; Скорость передвижения

GameLoop$:      mov     #10000, @#2     ; игровая задержка
                com     #-1
                beq     1$
                trap    46              ; Вывод звёзд на экран

1$:             call    @#PlayerAnim    ; Обработка и анимация движения игрока
                                        ; Обработка стрельбы, заполнение массива выстреленных пуль.
                call    @#PlayerBulletsAnim ; Обработка и анимация полёта пулек игрока
                call    @#FragScratchAnim ; Обработка разлёта осколков от объектов при попадании
                tstb    @#PlayerHit     ; 0 - есть попадание в игрока
                                        ; !0 - нет попадания
                bne     2$
                call    @#CheckLives    ; Проверка, закончились  ли жизни, и если нет - то уменьшение
                                        ; если да - начать игру заново
; ### заменить call на tst, чтобы ачивки не снимались
                call    @#AchievesDown  ; Снятие ачивок при попадании в игрока

2$:             cmp     #sprPlayerRt, @#CurSprPlayer ; движемся вправо?
                bne     3$       ; нет
                call    @#GoLeftConst   ; Установка констант для движения грунта влево
                br      4$
; ───────────────────────────────────────────────────────────────────────────

3$:             call    @#GoRigthConst  ; Установка констант для движения грунта вправо

4$:             tst     @#CannonStruct
                bne     5$
                call    @#CannonPrepare ; Функция подготавливает структуру параметров пушки

5$:             call    @#CannonAnim    ; Обработка и вывод пушек, проверка на коллизии
                                        ; и вывод сломанных пушек
                call    @#sub_24360     ; Подготовка прорисовки элементов на поверхности земли
                call    @#CannonShootAnim ; Выстрел из пушки
                call    @#EnemyShootAnim ; Анимация полёта выстрелов врагов
                call    @#sub_26320     ; проверка попали ли вражеские выстрелы в игрока
                                        ; и проверка, попал ли игрок куда-нибудь
                bis     #125252, @#77402
                call    @#DustCloudAnim
                call    @#LiveBoxAnim   ; Вывод и анимация ящика с жизнью
                call    @#LiveBoxCatch  ; Проверка поймал ли игрок коробку с жизнью
                                        ; и если да - то увеличение жизней
                call    @#SpeedBoxAnim  ; Вывод и анимация ящика с ускорением
                call    @#SpeedBoxCatch ; Проверка поймал ли игрок коробку с ускорением
                                        ; и если да - то увеличение скорости передвижения
                call    @#NBoxAnim      ; Вывод и анимация ящика N
                call    @#NBoxCatch     ; Проверка поймал ли игрок коробку с N
                                        ; и если да - то увеличение чего-то
                call    @#ForceBoxAnim  ; Вывод и анимация ящика F
                call    @#FBoxCatch     ; Проверка поймал ли игрок коробку с F
                                        ; и если да - то уменьшение чего-то
                call    @#RogerAnim
                call    @#UfoAnim
                call    @#BlockWallAnim
                call    @#BlockWall2Anim
                call    @#BlockWall3Anim
                nop
                bit     #100, @#177716
                bne     7$

6$:             cmp     #14, @#177662
                bne     7$
                tst     @#177714
                beq     6$

7$:             call    @#CheckBlockB   ; Проверка, есть ли блок Б и если есть, то добавление
                                        ; охранника, если нет - проверка на конец игры
                com     #0
                beq     8$
                call    @#GuardsAnim    ; Обработка и анимация охранников

8$:             call    @#GuardShootsAnim ; Кажется обработка и анимация выстрелов охранников
                nop
                nop
                nop
                nop
                nop
                nop
                mov     @#2, R1
                sob     R1, .
                com     #-1
                beq     9$
                call    @#CloudsAnim    ; Вывод и анимация облаков

9$:             jmp     @#GameLoop$
; ───────────────────────────────────────────────────────────────────────────

                .blkb 40
sprGuardRt:     .word 33, 3
                .byte 0, 24, 0
                .byte 0, 125, 0
                .byte 0, 175, 25
                .byte 0, 375, 3
                .byte 0, 375, 0
                .byte 0, 24, 0
                .byte 10, 74, 0
                .byte 4, 74, 0
                .byte 25, 250, 0
                .byte 21, 42, 2
                .byte 31, 50, 2
                .byte 221, 50, 3
                .byte 231, 350, 377
                .byte 221, 250, 17
                .byte 31, 242, 52
                .byte 21, 12, 0
                .byte 31, 250, 0
                .byte 21, 74, 0
                .byte 0, 74, 0
                .byte 0, 74, 0
                .byte 0, 74, 0
                .byte 0, 74, 0
                .byte 0, 74, 0
                .byte 0, 164, 0
                .byte 0, 124, 0
                .byte 0, 124, 1
                .byte 0, 120, 5
                .byte 0
sprGuardLt:     .word 33, 3
                .byte 0, 24, 0
                .byte 0, 125, 0
                .byte 124, 175, 0
                .byte 300, 177, 0
                .byte 0, 177, 0
                .byte 0, 24, 0
                .byte 0, 74, 40
                .byte 0, 74, 20
                .byte 0, 52, 124
                .byte 200, 210, 104
                .byte 200, 50, 144
                .byte 300, 50, 106
                .byte 377, 53, 146
                .byte 360, 52, 106
                .byte 250, 212, 144
                .byte 0, 240, 104
                .byte 0, 52, 144
                .byte 0, 74, 104
                .byte 0, 74, 0
                .byte 0, 74, 0
                .byte 0, 74, 0
                .byte 0, 74, 0
                .byte 0, 74, 0
                .byte 0, 35, 0
                .byte 0, 25, 0
                .byte 100, 25, 0
                .byte 120, 5, 0
                .byte 0
; Это спрайты выхлопа ранца охранника
sprGuardFlame1: .word 14, 1
                .byte ^B00000000
                .byte ^B00100010
                .byte ^B00000000
                .byte ^B00100010
                .byte ^B00001000
                .byte ^B00101010
                .byte ^B00001000
                .byte ^B00100010
                .byte ^B00000000
                .byte ^B00000000
                .byte ^B00001000
                .byte ^B00000000
sprGuardFlame2: .word 14, 1
                .byte ^B00000000
                .byte ^B00001000
                .byte ^B00000000
                .byte ^B00001000
                .byte ^B00100010
                .byte ^B00001000
                .byte ^B00101010
                .byte ^B00001000
                .byte ^B00000000
                .byte ^B00000000
                .byte ^B00100010
                .byte ^B00000000
SprGuardFlameLen = sprGuardFlame2 - sprGuardFlame1
; Буфер охранников на экране, размер 50 байтов
; размер элемента - 10 байтов, 4 слова. Количество элементов - 5
; Формат
; элемент массива охранников
; 0       адрес спрайта выхлопа ранца
; 2       адрес спрайта охранника
; 4       адрес экрана
; 6       число 3 (сколько выдерживает попаданий?)
GuardsBuffer:   .word 14454,14306, 0,177777, 0, 0, 0, 0
                .word  0, 0, 0, 0, 0, 0, 0, 0
                .word  0, 0, 0, 0
GuardsItemsNum = 5
GuardsItemSize = 10
GuardsBufferSize = GuardsItemSize * GuardsItemsNum
; ███████████████ S U B R O U T I N E ███████████████████████████████████████

; Обработка и анимация охранников

GuardsAnim:     clr     @#GuardsOnScreen ; сколько охранников видно на экране
                mov     #<GuardsBuffer+4>, R5 ; указатель в буфере
                mov     #GuardsItemsNum, R4 ; количество элементов

1$:             tst     (R5)            ; пусто?
                beq     2$              ; да
                inc     @#GuardsOnScreen ; нет - считаем сколько охранников на экране

2$:             add     #GuardsItemSize, R5
                sob     R4, 1$
                mov     #Guard, R5
                tst     (R5)+           ; охранников ещё много?
                bne     3$              ; да
                tstb    (R5)+           ; больше 10.?
                bne     3$              ; да
                cmpb    (PC)+, (R5)     ; меньше 10, и все видны на экране?
GuardsOnScreen: .word 0                 ; сколько охранников видно на экране
                bmi     3$              ; можно ещё добавить
                br      10$       ; все видны - не нужно добавлять
; ───────────────────────────────────────────────────────────────────────────

3$:             tst     (PC)+
NewGuardCnt:    .word 51                ; счётчик появления нового охранника на экране
                bne     9$              ; ещё рано добавлять
                call    @#sub_15514     ; Коррекция счётчика появления нового охранника
                nop
                mov     #<GuardsBuffer+4>, R5
                mov     #GuardsItemsNum, R4 ; количество элементов

4$:             tst     (R5)            ; ищем в массиве пустое место
                beq     5$              ; нашли
                add     #GuardsItemSize, R5
                sob     R4, 4$
                br      9$              ; некуда добавлять
; ───────────────────────────────────────────────────────────────────────────

5$:             sub     #4, R5          ; добавляем
                mov     #sprGuardFlame1, (R5)+ ; спрайт выхлопа ранца
                mov     @#177710, R1    ; псевдослучайный адрес экрана
                sub     #10000, R1
                bpl     6$
                clr     R1

6$:             add     #42200, R1
                bic     #77, R1
                cmp     #sprPlayerRt, @#CurSprPlayer ; смотрим вправо?
                beq     7$              ; да
                mov     #sprGuardRt, (R5)+ ; нет - охранник смотрит вправо
                br      8$
; ───────────────────────────────────────────────────────────────────────────

7$:             bis     #75, R1
                mov     #sprGuardLt, (R5)+ ; нет - охранник смотрит влево

8$:             mov     R1, (R5)+       ; адрес экрана
                mov     #3, (R5)+       ; кол-во жизней

9$:             dec     @#NewGuardCnt   ; уменьшаем счётчик

10$:            mov     #<GuardsBuffer+4>, R2 ; буфер
                mov     #GuardsItemsNum, R3 ; кол-во элементов

11$:            tst     (R2)            ; пусто?
                bne     13$             ; нет
                add     #GuardsItemSize, R2 ; да - к следующему

12$:            sob     R3, 11$
                return
; ───────────────────────────────────────────────────────────────────────────

13$:            mov     (R2), R1        ; адрес экрана
                mov     -(R2), R0       ; адрес спрайта
                mov     -(R2), R5       ; адрес спрайта выхлопа
                cmp     #sprGuardRt, R0
                beq     14$
                mov     #2202, R4       ; смещение для выхлопа если смотрит влево
                br      15$
; ───────────────────────────────────────────────────────────────────────────

14$:            mov     #2200, R4       ; смещение для выхлопа если смотрит право

15$:            trap    40              ; Стирание спрайта с экрана методом побитовой очистки
                                        ; Вход: R0 - адрес спрайта в памяти, первые 2 слова высота в строках и ширина в байтах
                                        ;       R1 - адрес экрана
                mov     R5, R0
                add     R4, R1          ; теперь сотрём выхлоп
                trap    40              ; Стирание спрайта с экрана методом побитовой очистки
                                        ; Вход: R0 - адрес спрайта в памяти, первые 2 слова высота в строках и ширина в байтах
                                        ;       R1 - адрес экрана
                sub     R4, R1
                tst     6(R2)           ; жизни ещё остались?
                bpl     17$             ; да
                call    @#RemoveDeadGuard ; Уменьшаем количество охранников.
                                        ; Вход: R2 - адрес элемента в массиве GuardsBuffer

16$:            nop
                add     #GuardsItemSize+4, R2
                br      12$
; ───────────────────────────────────────────────────────────────────────────
; теперь определим, куда двигаться охраннику

17$:            mov     @#PlayerScrAddr, R5 ; Адрес спрайта игрока
                add     #2600, R5
                clr     R4              ; приращение к адресу экрана
                cmp     R5, R1
                bpl     18$
                mov     #-200, R4
                br      19$
; ───────────────────────────────────────────────────────────────────────────

18$:            sub     #4400, R5
                cmp     R5, R1
                bmi     19$
                mov     #200, R4

19$:            bic     #177700, R1
                bic     #177700, R5
                cmp     R5, R1
                bmi     20$
                inc     R4
                mov     #sprGuardRt, R0
                br      21$
; ───────────────────────────────────────────────────────────────────────────

20$:            dec     R4
                mov     #sprGuardLt, R0

21$:            mov     4(R2), R1
                add     R4, R1          ; корректируем адрес экрана
                trap    36              ; Вывод спрайта на экран методом наложения
                                        ; Вход: R0 - адрес спрайта в памяти, первые 2 слова высота в строках и ширина в байтах
                                        ;       R1 - адрес экрана
                mov     R0, 2(R2)       ; сохраняем новый адрес спрайта
                mov     R1, 4(R2)       ; сохраняем новый адрес экрана
                cmp     #sprGuardRt, R0
                beq     22$
                add     #2202, R1       ; адрес экрана выхлопа ранца
                br      23$
; ───────────────────────────────────────────────────────────────────────────

22$:            add     #2200, R1

23$:            mov     (R2), R0        ; анимируем выхлоп
                cmp     #sprGuardFlame2, R0
                bne     24$
                mov     #sprGuardFlame1, R0
                br      25$
; ───────────────────────────────────────────────────────────────────────────

24$:            add     #SprGuardFlameLen, R0

25$:            mov     R0, (R2)        ; сохраняем новый спрайт выхлопа
                trap    36              ; Вывод спрайта на экран методом наложения
                                        ; Вход: R0 - адрес спрайта в памяти, первые 2 слова высота в строках и ширина в байтах
                                        ;       R1 - адрес экрана
                br      16$
; End of function GuardsAnim


; ███████████████ S U B R O U T I N E ███████████████████████████████████████

; Кажется обработка и анимация выстрелов охранников

GuardShootsAnim:mov     #<GuardsBuffer+4>, R1
                mov     #GuardsItemsNum, R2 ; количество элементов

1$:             tst     (R1)            ; там пусто?
                bne     3$       ; нет

2$:             add     #GuardsItemSize, R1 ; идём к следующему
                sob     R2, 1$          ; и так весь массив
                return
; ───────────────────────────────────────────────────────────────────────────

3$:             call    @#sub_15410
                tst     (PC)+
0GuardNewShootCnt$:.word 30
                beq     4$
                dec     @#0GuardNewShootCnt$
                br      2$
; ───────────────────────────────────────────────────────────────────────────

4$:             mov     #30, @#0GuardNewShootCnt$
                mov     #<EnemyBulletBuffer+2>, R5
                mov     #EnemyBulletBufferItemsNum, R4

5$:             tst     (R5)
                beq     6$
                add     #EnemyBulletBufferItemSize, R5
                sob     R4, 5$
                br      2$
; ───────────────────────────────────────────────────────────────────────────

6$:             mov     (R1), R0
                mov     @#PlayerScrAddr, R3 ; Адрес спрайта игрока
                trap    66
                mov     #sprBallBullet, -(R5)
                tst     (R5)+
                add     #1101, R0
                call    @#sub_36200
                mov     #500, (R5)+
                mov     #2, (R5)+
                mov     #1, (R5)+
                br      2$
; End of function GuardShootsAnim


; ███████████████ S U B R O U T I N E ███████████████████████████████████████


sub_15410:      mov     #word_6672, R5
                mov     (R1), (R5)
                mov     2(R1), 6(R5)
                mov     -2(R1), R3
                trap    56              ; Проверка попаданиями пулек игрока в объект
                                        ; Вход: R3 - спрайт объекта
                                        ;       R5 - структура объекта
                mov     6(R5), 2(R1)
                return
; End of function sub_15410


; ███████████████ S U B R O U T I N E ███████████████████████████████████████

; Уменьшаем количество охранников.
; Вход: R2 - адрес элемента в массиве GuardsBuffer

RemoveDeadGuard:clr     4(R2)           ; очищаем адрес экрана
                mov     #EndGuard, R0
                call    @#DecreaseValue ; Уменьшение двоично-десятичного числа
                                        ; Вход: R0 - конец числа
                mov     #41062, R1
                mov     #Guard, R5
                trap    60              ; Вывод числовых значений счёта, жизней и т.п.
                                        ; Вход: R5 - адрес данных
                                        ;       R1 - адрес экрана
                tst     (R1)+           ; !!! Тут кажись ошибка, нужно не R1, а R5 проверять
                bne     1$
                tst     (R1)+
                bne     1$
                jmp     @#FinalGame
; ───────────────────────────────────────────────────────────────────────────

1$:             mov     #Sound7$, R1
                trap    14
                return
; End of function RemoveDeadGuard


; ███████████████ S U B R O U T I N E ███████████████████████████████████████

; Коррекция счётчика появления нового охранника

sub_15514:      mov     #<BlockBuf+2>, R5 ; буфер
                mov     #BlockBufItemsNum, R4 ; количество элементов

1$:             tst     (R5)+           ; там пусто?
                beq     2$              ; да
                add     #3, @#NewGuardCnt ; нет - корректируем счётчик

2$:             tst     (R5)+           ; переходим к следующему элементу
                sob     R4, 1$          ; и так весь массив
                add     #34, @#NewGuardCnt ; счётчик появления нового охранника на экране
                return
; End of function sub_15514


; Буфер размером 2220 байтов

; буфер всех выстрелов, в том числе и из пушки, количество элементов 40
; размер элемента 16
; т.е. этот массив включает в себя и следующий
EnemyBulletBufferItemsNum = 40
EnemyBulletBufferItemSize = 16
EnemyBulletBuffer =  sub_15552 + 6
EnemyBulletBufferSize = EnemyBulletBufferItemsNum * EnemyBulletBufferItemSize

; буфер выстрелов из пушки, количество элементов 20
; размер элемента 16
; Этот массив входит в предыдущий
CannonBulletBufferItemsNum = 20
CannonBulletBuffer = EnemyBulletBuffer + EnemyBulletBufferSize / 2

; буфер пулек игрока
PlayersBulletBufferItemsNum = 74
PlayersBulletBufferItemSize = 14
PlayersBulletBuffer = EnemyBulletBuffer + EnemyBulletBufferSize
PlayersBulletBufferSsize = PlayersBulletBufferItemsNum * PlayersBulletBufferItemSize
AllBuffersSize = EnemyBulletBufferSize + PlayersBulletBufferSsize

; ███████████████ S U B R O U T I N E ███████████████████████████████████████

; эта п/п и спрайт используется только один раз

sub_15552:      mov     #VecKbdNo$, @#60
                mov     #VecKbdNo$, @#274
                trap    70              ; Очистка экрана

                mov     #45000, R1
                mov     #1000, R2

1$:             mov     (R0), 5000(R1)
                mov     (R0), 12000(R1)
                mov     (R0), 17000(R1)
                mov     (R0), 24000(R1)
                mov     (R0)+, (R1)+
                sob     R2, 1$
                sob     R2, .
                sob     R2, .
                sob     R2, .
                return
; End of function sub_15552

; ───────────────────────────────────────────────────────────────────────────
                .blkb 44
; Спрайт "Break IDea Leader"
SprBILun$:      .word 0, 125252, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120000, 5252, 0, 0
                .word 0, 0, 0, 0, 0, 0, 125200, 52, 0, 0, 0, 0, 0, 0, 0, 0
                .word 0, 177776, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 160000, 7777, 0, 0
                .word 0, 0, 0, 0, 0, 0, 177600, 77, 0, 0, 0, 0, 0, 0, 0, 0
                .word 0, 177776, 277, 0, 0, 0, 0, 0, 0, 0, 0, 0, 160000, 7777, 0, 0
                .word 0, 0, 0, 0, 0, 0, 177600, 77, 0, 0, 0, 0, 0, 0, 0, 0
                .word 0, 107770, 377, 25252, 125000, 1252, 25240, 5200, 1250, 0, 0, 0, 100000, 1777, 125252, 124002
                .word 1252, 125200, 0, 0, 0, 0, 177000, 3, 125240, 52, 1252, 125252, 124002, 5252, 25252, 0
                .word 0, 1770, 376, 137776, 177000, 1777, 37750, 7600, 1772, 0, 0, 0, 100000, 377, 177776, 174013
                .word 1777, 177640, 0, 0, 0, 0, 177000, 3, 177740, 100077, 1776, 177776, 174013, 7777, 137776, 0
                .word 0, 101772, 376, 177776, 177002, 1777, 37772, 107600, 376, 0, 0, 0, 100000, 377, 177776, 174017
                .word 1777, 177750, 0, 0, 0, 0, 177000, 3, 177740, 120077, 1777, 177776, 174017, 7777, 177776, 2
                .word 0, 125776, 377, 174076, 37003, 100000, 37376, 127600, 77, 0, 0, 0, 120000, 377, 100370, 174017
                .word 0, 175772, 0, 0, 0, 0, 177200, 3, 1740, 164000, 1757, 100370, 174017, 0, 174076, 3
                .word 0, 177776, 100077, 164076, 137203, 100052, 37077, 167640, 17, 0, 0, 0, 160000, 377, 100370, 175017
                .word 252, 174376, 0, 0, 0, 0, 177600, 3, 125750, 174002, 1743, 100370, 175017, 100252, 164076, 3
                .word 0, 177776, 100017, 175277, 177600, 120077, 37257, 177740, 3, 0, 0, 0, 160000, 77, 120372, 177017
                .word 100377, 175276, 0, 0, 0, 0, 177600, 0, 177770, 175003, 1752, 120372, 177017, 100377, 175277, 0
                .word 100000, 177776, 100057, 37777, 177600, 160077, 37777, 177740, 0, 0, 0, 0, 160000, 77, 160376, 177017
                .word 100377, 177777, 0, 0, 0, 0, 177600, 25200, 177770, 177003, 1777, 160376, 177017, 100377, 37777, 0
                .word 100000, 100377, 100277, 7777, 7600, 164000, 7777, 177740, 2, 0, 0, 0, 164000, 77, 164076, 37003
                .word 120000, 37777, 0, 0, 0, 0, 177640, 37600, 370, 177200, 377, 164076, 37003, 100000, 7777, 0
                .word 100000, 100377, 120376, 27617, 127600, 174012, 7603, 175750, 13, 0, 0, 0, 174000, 120077, 175276, 137003
                .word 160052, 37017, 0, 0, 0, 0, 177740, 37600, 125370, 37600, 120370, 175276, 137003, 120052, 27617, 0
                .word 100000, 120077, 160377, 137617, 177640, 175017, 7600, 161770, 57, 0, 0, 0, 174000, 160077, 177777, 177200
                .word 164077, 37003, 0, 0, 0, 0, 37740, 37640, 177772, 7640, 160370, 177777, 177200, 160077, 137617, 0
                .word 120000, 165277, 160077, 177003, 177740, 177017, 7600, 100370, 77, 0, 0, 0, 175000, 160017, 37777, 177600
                .word 174077, 37003, 0, 0, 0, 0, 137750, 7752, 177776, 7740, 160370, 37777, 177600, 160077, 177003, 0
                .word 160000, 177777, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 177000, 77, 0, 0
                .word 0, 0, 0, 0, 0, 0, 177770, 7777, 0, 0, 0, 0, 0, 0, 0, 0
                .word 160000, 177777, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 177000, 77, 0, 0
                .word 0, 0, 0, 0, 0, 0, 177770, 1777, 0, 0, 0, 0, 0, 0, 0, 0
                .blkb 64
LastItemPlrsBlltBuf: .word 0
                .word 0
                .word 0
                .word 0
                .word 0
                .word 0

; ███████████████ S U B R O U T I N E ███████████████████████████████████████

; Обработка и анимация движения игрока
; Обработка стрельбы, заполнение массива выстреленных пуль.

PlayerAnim:     clr     @#FireFlag      ; Флаг стрельбы
                add     #100, @#GrowPlayerAddr ; если ничего не делать - то плавно снижаемся к земле
                mov     @#MoveSpeed, R4 ; Скорость передвижения

1$:             mov     @#CtrlMode, R5  ; режим управления: 0 - от клавиатуры
                                        ;                   1 - от джойстика
                                        ;                   2 - клавиатура + джойстик
                bne     2$              ; не только от клавиатуры
                                        ; от клавиатуры
                trap    50              ; Опрос клавиатуры
                br      4$
; ───────────────────────────────────────────────────────────────────────────

2$:             dec     R5
                beq     3$              ; только от джойстика
                tst     @#177714        ; параллельное, джойстик нажат?
                bne     3$              ; да - значит опросим джойстик
                trap    50              ; иначе - Опрос клавиатуры

3$:             trap    52              ; Опрос джойстика

4$:             dec     R4              ; дадим шанс нажать что-нибудь ещё
                bpl     1$
                mov     @#PlayerScrAddr, R5 ; Адрес спрайта игрока
                mov     @#CurSprPlayer, R0 ; Адрес текущего спрайта игрока
                mov     R5, R1          ; это текущий адрес
                add     @#GrowPlayerAddr, R5 ; это новый адрес
                cmp     #74400, R5      ; нижней границы достигли?
                bpl     5$              ; нет
                bic     #177700, R5     ; да - не дадим опуститься ниже нижней границы
                bis     #74400, R5

5$:             cmp     #42300, R5      ; верхней границы достигли?
                bmi     6$              ; нет
                bic     #177700, R5     ; да - не дадим подняться выше верхней границы
                bis     #42300, R5

6$:             mov     R1, R2
                bic     #177700, R2     ; текущая горизонтальная позиция
                mov     @#GrowPlayerAddr, R3 ; Приращение адреса игрока
                bic     #177770, R3
                beq     10$
                cmp     #5, R3
                bgt     8$
                mov     R5, R3          ; новый адрес
                bic     #177700, R3     ; новая горизонтальная позиция
                cmp     R3, R2          ; движемся влево?
                blt     7$              ; да - переход
                add     #100, R5        ; коррекция при движении вправо
                sub     R3, R5

7$:             mov     #sprPlayerLt, @#CurSprPlayer ; Адрес текущего спрайта игрока
                br      10$
; ───────────────────────────────────────────────────────────────────────────

8$:             mov     R5, R3
                add     #4, R3
                bic     #177700, R3
                cmp     R2, R3
                blt     9$
                sub     R3, R5

9$:             mov     #sprPlayerRt, @#CurSprPlayer ; Адрес текущего спрайта игрока

10$:            mov     R0, -(SP)
                mov     R1, -(SP)
                cmp     #sprPlayerRt, R0
                bne     14$
                mov     @#CurrVyhlopSpr, R0 ; адрес текущего спрайта выхлопа игрока
                add     #2000, R1
                trap    40              ; Стирание спрайта с экрана методом побитовой очистки
                                        ; Вход: R0 - адрес спрайта в памяти, первые 2 слова высота в строках и ширина в байтах
                                        ;       R1 - адрес экрана
                mov     R5, R1
                add     #2000, R1
                cmp     #sprPlayerRt, @#CurSprPlayer ; Адрес текущего спрайта игрока
                beq     11$
                tst     (R1)+
                mov     #sprVyhlopLt1, R0
                mov     R0, @#CurrVyhlopSpr ; адрес текущего спрайта выхлопа игрока
                trap    36              ; Вывод спрайта на экран методом наложения
                                        ; Вход: R0 - адрес спрайта в памяти, первые 2 слова высота в строках и ширина в байтах
                                        ;       R1 - адрес экрана
                br      17$
; ───────────────────────────────────────────────────────────────────────────

11$:            cmp     #sprVyhlopRt2, R0
                bgt     13$

12$:            mov     #<sprVyhlopRt1-SprVyhlopSize>, R0

13$:            add     #SprVyhlopSize, R0
                mov     R0, @#CurrVyhlopSpr ; адрес текущего спрайта выхлопа игрока
                trap    36              ; Вывод спрайта на экран методом наложения
                                        ; Вход: R0 - адрес спрайта в памяти, первые 2 слова высота в строках и ширина в байтах
                                        ;       R1 - адрес экрана
                br      17$
; ───────────────────────────────────────────────────────────────────────────

14$:            mov     @#CurrVyhlopSpr, R0 ; адрес текущего спрайта выхлопа игрока
                add     #2002, R1
                trap    40              ; Стирание спрайта с экрана методом побитовой очистки
                                        ; Вход: R0 - адрес спрайта в памяти, первые 2 слова высота в строках и ширина в байтах
                                        ;       R1 - адрес экрана
                mov     R5, R1
                add     #2002, R1
                cmp     #sprPlayerLt, @#CurSprPlayer ; Адрес текущего спрайта игрока
                beq     15$
                tst     -(R1)
                br      12$
; ───────────────────────────────────────────────────────────────────────────

15$:            cmp     #sprVyhlopLt2, R0
                bgt     16$
                mov     #sprVyhlopRt2, R0

16$:            br      13$
; ───────────────────────────────────────────────────────────────────────────

17$:            mov     (SP)+, R1
                mov     (SP)+, R0
                trap    40              ; Стирание спрайта с экрана методом побитовой очистки
                                        ; Вход: R0 - адрес спрайта в памяти, первые 2 слова высота в строках и ширина в байтах
                                        ;       R1 - адрес экрана
                mov     R5, R1
                mov     @#CurSprPlayer, R0 ; Адрес текущего спрайта игрока
                trap    36              ; Вывод спрайта на экран методом наложения
                                        ; Вход: R0 - адрес спрайта в памяти, первые 2 слова высота в строках и ширина в байтах
                                        ;       R1 - адрес экрана
                mov     R1, @#PlayerScrAddr ; Адрес спрайта игрока
; теперь обработка стрельбы
                tst     @#FireFlag      ; Флаг стрельбы
                beq     25$             ; не стреляет, выходим
                bic     #177770, NewShootCnt ; счётчик до возможности нового выстрела
                dec     (PC)+           ; выстреливать пора?
NewShootCnt:    .word 1                 ; счётчик до возможности нового выстрела
                bne     25$             ; нет ещё - выходим

ShootSpeed:     mov     #5, NewShootCnt ; Ускорение стрельбы (меньше - быстрее)
                mov     #SoundPlayerShoot, R1
                trap    14              ; Вывод звука
                                        ; Вход R1 - адрес таблицы параметров
                                        ; .word длит
                                        ; .word тон, тон,... (0 - конец таблицы)
                mov     @#PlayerScrAddr, R0 ; Адрес спрайта игрока
                add     #700, R0
                mov     @#NShooting, R3 ; Количество выстреливаемых очередей
                bne     21$
                mov     #-3, R1         ; одна очередь
                br      23$
; ───────────────────────────────────────────────────────────────────────────

21$:            cmp     #1, R3
                bne     22$
                mov     #-103, R1       ; две очереди
                br      23$
; ───────────────────────────────────────────────────────────────────────────

22$:            mov     #-203, R1       ; три очереди

23$:            cmp     #sprPlayerRt, @#CurSprPlayer ; Адрес текущего спрайта игрока
                bne     24$
                add     #3, R0          ; направление вправо
                neg     R1

24$:            call    sub_20650       ; Поиск в массиве свободного пространства для рисования пульки
                                        ; Выход: R5 - указатель в массиве на пустой элемент
                                        ; Размер одного элемента 6 слов
                mov     R0, -(R5)       ; уменьшаем на 2 указатель
                mov     R1, (R5)+       ; приращение к адресу
                mov     R0, (R5)+       ; адрес экрана
                mov     #500, (R5)+
                mov     #4, (R5)+
                mov     #1, (R5)+
                clr     (R5)+
                nop
                nop
                nop
                dec     R3
                bpl     26$

25$:            return
; ───────────────────────────────────────────────────────────────────────────

26$:            cmp     #-103, R1
                beq     27$
                cmp     #-3, R1
                bne     28$

27$:            add     #400, R1

28$:            cmp     #-203, R1
                beq     27$
                sub     #200, R1
                br      24$
; End of function PlayerAnim


; ███████████████ S U B R O U T I N E ███████████████████████████████████████

; Поиск в массиве свободного пространства для рисования пульки
; Выход: R5 - указатель в массиве на пустой элемент
; Размер одного элемента 6 слов

sub_20650:      mov     #PlayersBulletBuffer+2, R5 ; буфер пулек игрока
                mov     #PlayersBulletBufferItemsNum, R4 ; количество элементов

1$:             tst     (R5)            ; пусто?
                beq     2$    ; да - нашли место
                add     #PlayersBulletBufferItemSize, R5 ; переходим к следующей позиции
                sob     R4, 1$          ; и так весь массив
                tst     (SP)+           ; массив заполнен, вообще выходим из родительской функции

2$:             return
; End of function sub_20650

; ───────────────────────────────────────────────────────────────────────────
                .word 0

; ███████████████ S U B R O U T I N E ███████████████████████████████████████

; Обработка и анимация полёта пулек игрока

PlayerBulletsAnim:
                mov     #PlayersBulletBuffer, R5 ; массив пулек игрока
                mov     #PlayersBulletBufferItemsNum, R4 ; количество элементов

1$:             tst     2(R5)           ; пулька на экране?
                bne     3$              ; да
                add     #PlayersBulletBufferItemSize, R5 ; нет - переходим к следующему элементу

2$:             sob     R4, 1$
                return
; ───────────────────────────────────────────────────────────────────────────

3$:             mov     (R5)+, R3       ; приращение к адресу
                mov     (R5), R1        ; адрес экрана
                mov     #sprBulletLt, R0
                bit     #2, R3          ; куда летит?
                beq     4$              ; влево
                add     #10, R0         ; вправо - корректируем спрайт

4$:             trap    40              ; Стирание спрайта с экрана методом побитовой очистки
                                        ; Вход: R0 - адрес спрайта в памяти, первые 2 слова высота в строках и ширина в байтах
                                        ;       R1 - адрес экрана
                cmp     #77000, R1      ; до нижней границы долетели?
                bpl     5$              ; нет
                clr     (R5)            ; да - очищаем элемент, пулька улетела за экран

5$:             cmp     #42300, R1      ; до верхней границы долетели?
                bmi     6$              ; нет
                clr     (R5)            ; да - очищаем элемент, пулька улетела за экран

6$:             bit     #74, R1         ; до левой границы долетели?
                bne     7$              ; нет
                clr     (R5)            ; да - очищаем элемент, пулька улетела за экран

7$:             add     #4, R1          ; до правой границы долетели?
                bit     #74, R1
                bne     8$              ; нет
                clr     (R5)            ; да - очищаем элемент, пулька улетела за экран

8$:             mov     (R5), R1        ; снова возьмём адрес
                beq     9$              ; пульки уже нету, не надо рисовать
                add     R3, R1          ; новый адрес
                trap    36              ; Вывод спрайта на экран методом наложения
                                        ; Вход: R0 - адрес спрайта в памяти, первые 2 слова высота в строках и ширина в байтах
                                        ;       R1 - адрес экрана

9$:             mov     R1, (R5)+       ; сохраняем новый адрес
                add     #10, R5         ; переходим к следующему элементу
                br      2$
; End of function PlayerBulletsAnim

; ───────────────────────────────────────────────────────────────────────────
                .word 0
sprRedBallBullet:.word 5, 1
                .byte ^B00111100
                .byte ^B11111111
                .byte ^B11111111
                .byte ^B11111111
                .byte ^B00111100
                .byte 0
Sprite8$:       .word 4, 1
                .byte ^B01000001
                .byte ^B01010101
                .byte ^B01010101
                .byte ^B01000001
TmpBlockStruct: .word 45174
                .word 1500
                .word 3
                .word 1
                .word sprParticle1
                .word 601
                .word 0
sprParticle1:   .word 1, 4
                .word ^B0011110011000011
                .word ^B1100001100111100
sprParticle2:   .word 2, 2
                .word ^B0010100010000010
                .word ^B1000001000101000
; Смещения разлёта осколков
ScratchOffsetTbl:.word -300
                .word -77
                .word 2
                .word 101
                .word 300
                .word 77
                .word -2
                .word -101
; Массив разлёта осколков от попадания в объекты.
; элемент - структура размером 10. слов. количество 30 шт.
; первое слово - адрес спрайта,
; второе слово - число 3000
; затем 8 слов адресов разлёта

ScratchBufferItemsNum = 30
ScratchBufferItemSize = 24

ScratchBuffer:  .word 0
                .word 3000
                .word 0, 0, 0, 0
                .word 0, 0, 0, 0
                .word 0
                .word 3000
                .word 0, 0, 0, 0
                .word 0, 0, 0, 0
                .word 21040
                .word 3000
                .word 54020, 53401, 0, 0
                .word 0, 46627, 50336, 53033
                .word 21110
                .word 3000
                .word 55655, 55236, 53527, 51032
                .word 50045, 50464, 52173, 54670
                .word 21110
                .word 3000
                .word 55655, 55236, 53527, 51032
                .word 50045, 50464, 52173, 54670
                .word 21110
                .word 3000
                .word 55653, 55234, 53525, 51030
                .word 50043, 50462, 52171, 54666
                .word 21100
                .word 3000
                .word 50660, 50241, 46532, 44035
                .word 43050, 43467, 45176, 47673
                .word 21100
                .word 3000
                .word 47163, 46544, 45035, 42340
                .word 0, 0, 0, 0
                .word 21100
                .word 3000
                .word 50663, 50244, 46535, 44040
                .word 43053, 43472, 0, 0
                .word 23466
                .word 3000
                .word 0, 0, 0, 72757
                .word 71772, 0, 0, 0
                .word 21100
                .word 3000
                .word 47116, 0, 0, 0
                .word 0, 0, 43434, 46131
                .word 21100
                .word 3000
                .word 50616, 0, 0, 0
                .word 0, 43425, 45134, 47631
                .word 21052
                .word 3000
                .word 0, 0, 0, 0
                .word 72513, 73132, 74641, 0
                .word 23466
                .word 3000
                .word 0, 0, 75432, 72735
                .word 71750, 72367, 74076, 76573
                .word 23466
                .word 3000
                .word 0, 0, 75423, 72726
                .word 71741, 72360, 74067, 76564
                .word 23466
                .word 3000
                .word 0, 0, 75406, 72711
                .word 71724, 72343, 74052, 76547
                .word 23466
                .word 3000
                .word 0, 0, 0, 0
                .word 0, 72325, 74034, 76531
                .word 23466
                .word 3000
                .word 0, 0, 0, 0
                .word 71773, 0, 0, 0
                .word 21100
                .word 3000
                .word 47117, 0, 0, 0
                .word 0, 0, 43435, 46132
                .word 21100
                .word 3000
                .word 50617, 0, 0, 0
                .word 0, 43426, 45135, 47632
                .word 21052
                .word 3000
                .word 0, 0, 0, 0
                .word 72514, 73133, 74642, 0
                .word 21100
                .word 3000
                .word 47120, 46501, 0, 0
                .word 0, 0, 43436, 46133
                .word 21100
                .word 3000
                .word 50620, 50201, 0, 0
                .word 0, 43427, 45136, 47633
                .word 21100
                .word 3000
                .word 47121, 46502, 0, 0
                .word 0, 0, 43437, 46134
; эта функция должна следовать за массивом, т.к.
; конец массива проверяется по опкодам этой функции

; ███████████████ S U B R O U T I N E ███████████████████████████████████████

; Обработка разлёта осколков от объектов при попадании

FragScratchAnim:mov     PC, R5
                sub     #<. - ScratchBuffer>, R5

1$:             mov     (R5)+, R0       ; это адрес спрайта осколков
                cmp     #3000, (R5)+    ; второе число 3000?
                beq     13$             ; да - элемент считается пустым
                tst     -(R5)           ; возвращаемся ко второму числу
                cmpb    (R5)+, (R5)     ; сравним мл. байт и ст. байт
                bne     2$              ; не равны
                incb    (R5)            ; равны - увеличим ст. байт
                clrb    -1(R5)          ; обнулим мл.байт
                br      3$
; ───────────────────────────────────────────────────────────────────────────

2$:             incb    -1(R5)          ; увеличим мл.байт

3$:             movb    (R5)+, R3       ; берём ст.байт
                asl     R3              ; *2
                mov     #8., R2         ; 8 осколков

4$:             mov     (R5), R1        ; берём очередной адрес
                beq     8$              ; нету - не надо ничего делать
                trap    40              ; Стирание спрайта с экрана методом побитовой очистки
                                        ; Вход: R0 - адрес спрайта в памяти, первые 2 слова высота в строках и ширина в байтах
                                        ;       R1 - адрес экрана
                mov     PC, R4          ; ну вот нахера такие сложности?
                add     R3, R4          ; получим индекс в массива приращений к адресам разлёта осколков
                add     <ScratchOffsetTbl - . + 2>(R4), (R5) ; формируем новый адрес
                cmp     #42300, (R5)    ; верхней границы достигли?
                bmi     5$              ; нет
                clr     (R5)            ; да - удаляем

5$:             cmp     #77000, (R5)    ; нижней границы достигли?
                bpl     6$              ; нет
                clr     (R5)            ; да - удаляем

6$:             mov     (R5), R1        ; левого края экрана достигли?
                bic     #177700, R1
                bne     7$              ; нет
                clr     (R5)            ; да - удаляем

7$:             cmp     #77, R1         ; правого края экрана достигли?
                bne     8$              ; нет
                clr     (R5)            ; да - удаляем

8$:             tst     (R3)+           ; следующий индекс приращения
                cmp     #20, R3         ; двигаем указатель циклически
                bne     9$
                clr     R3

9$:             tst     (R5)+           ; следующий адрес
                sob     R2, 4$          ; и так все 8 осколков
                sub     #ScratchBufferItemSize-3, R5 ; возвращаемся к ст. байту второго слова
                movb    (R5)+, R3       ; берём значение
                cmpb    #6, R3          ; там начальное значение?
                beq     13$             ; да - ничего не делать
                                        ; иначе, это индекс в таблице приращений адресов разлёта осколков
; теперь выводим на новых местах
                mov     #8., R2         ; у нас 8 осколков

10$:            mov     (R5), R1        ; берём очередной адрес
                beq     11$             ; 0 - нету
                trap    36              ; Вывод спрайта на экран методом наложения
                                        ; Вход: R0 - адрес спрайта в памяти, первые 2 слова высота в строках и ширина в байтах
                                        ;       R1 - адрес экрана

11$:            tst     (R3)+           ; следующий индекс приращения
                cmp     #20, R3         ; двигаем указатель циклически
                bne     12$
                clr     R3

12$:            tst     (R5)+           ; следующий адрес
                sob     R2, 10$         ; и так все 8 осколков
                mov     PC, R1
                add     #<SoundScratch-.>, R1
                trap    14              ; Вывод звука
                                        ; Вход R1 - адрес таблицы параметров
                                        ; .word длит
                                        ; .word тон, тон,... (0 - конец таблицы)
                call    @#GameSpeedup   ; Уменьшаем игровую задержку
                br      14$
; ───────────────────────────────────────────────────────────────────────────

13$:            add     #ScratchBufferItemSize-4, R5 ; переходим к следующему элементу

14$:            cmp     #10705, (R5)    ; !!! - это опкод за массивом
                                        ; до конца дошли?
                bne     1$              ; нет ещё, продолжаем
                return
; End of function FragScratchAnim

; ───────────────────────────────────────────────────────────────────────────
SoundScratch:   .word 2
                .word 2
                .word 0, 0
                .word 0, 0

; ███████████████ S U B R O U T I N E ███████████████████████████████████████

; Проверка на коллизию.
; Вход: R0 - адрес спрайта объекта 2
;       R3 - адрес спрайта объекта 1
;       R4 - структура объекта 2
;       R5 - структура объекта 1
; Формат структуры см в другом месте

Trap54:         mov     2(SP), R5       ; восстанавливаем значение R5
                mov     (R4)+, R1       ; адрес экрана объекта 2
                mov     (R5)+, R2       ; адрес экрана объекта 1
                add     (R4), R1        ; нижняя граница 2
                cmp     R2, R1
                bmi     1$
                return                  ; объект 2 выше объекта 1
; ───────────────────────────────────────────────────────────────────────────

1$:             sub     (R4)+, R1       ; возвращаем как было
                add     (R5), R2        ; нижняя граница 1
                cmp     R2, R1
                bpl     2$
                return                  ; объект 1 выше объекта 2
; ───────────────────────────────────────────────────────────────────────────

2$:             sub     (R5)+, R2       ; возвращаем как было
                bic     #177700, R2     ; теперь оставим горизонтальные позиции
                bic     #177700, R1
                add     (R4), R1        ; правая граница 2
                cmp     R2, R1
                bmi     3$
                return                  ; объект 2 правее объекта 1
; ───────────────────────────────────────────────────────────────────────────

3$:             sub     (R4)+, R1       ; возвращаем как было
                add     (R5), R2        ; правая граница 1
                cmp     R2, R1
                bpl     4$
                return                  ; объект 1 правее объекта 2
; ───────────────────────────────────────────────────────────────────────────
; объекты пересеклись

4$:             sub     (R5)+, R2       ; возвращаем как было
                mov     -6(R4), R1
                trap    42              ; Стирание спрайта с экрана clrом
                                        ; Вход: R0 - адрес спрайта в памяти, первые 2 слова высота в строках и ширина в байтах
                                        ;       R1 - адрес экрана
                mov     -6(R5), R1
                mov     R3, R0
                trap    42              ; Стирание спрайта с экрана clrом
                                        ; Вход: R0 - адрес спрайта в памяти, первые 2 слова высота в строках и ширина в байтах
                                        ;       R1 - адрес экрана
                call    sub_22474       ; Вход: R4 - адрес структуры + 6
                mov     R5, R4
; End of function Trap54


; ███████████████ S U B R O U T I N E ███████████████████████████████████████

; Вход: R4 - адрес структуры + 6

sub_22474:      mov     #ScratchBuffer-<ScratchBufferItemSize-2>, R0

1$:             add     #ScratchBufferItemSize, R0
                cmp     #162705, (R0)    ; !!! это тоже опкод
                bne     2$
                return
; ───────────────────────────────────────────────────────────────────────────

2$:             cmp     #3000, (R0)     ; ищем в таблице разлёта осколков пустое место
                bne     1$              ; не пустое, ищем дальше
                dec     (R4)+           ; нашли, снимаем хитпоинт, для игрока происходит фиксация коллизии
                bne     3$              ; ещё живёт
                clr     -10(R4)         ; всё, умер, обнуляем адрес экрана

3$:             sub     #2, R0
                mov     (R4)+, (R0)+    ; это адрес спрайта осколков
                beq     5$              ; если 0, то без осколков
                mov     (R4)+, R1
                add     -14(R4), R1     ; получим центр разлёта осколков
                                        ; для объекта, которого нет на экране,
                                        ; получится число за пределами экрана
                clr     (R0)+
                mov     #8., R2         ; заполняем таблицу адресов осколков

4$:             mov     R1, (R0)+
                sob     R2, 4$

5$:             trap    62              ; Увеличение счёта
                return
; End of function sub_22474

; ───────────────────────────────────────────────────────────────────────────
                .word 0
                .word 0
                .word 0
                .word 0
                .word 0

; ███████████████ S U B R O U T I N E ███████████████████████████████████████

; Проверка попаданиями пулек игрока в объект
; Вход: R3 - спрайт объекта
;       R5 - структура объекта

Trap56:         mov     #PlayersBulletBuffer+2, R4
                mov     2(SP), R5
                mov     #PlayersBulletBufferItemsNum, R1
                mov     #sprBulletLt, R0 ; тут лево/ право не важно, спрайт используется для стирания

1$:             tst     (R4)
                beq     2$
                trap    54              ; Проверка на коллизию.
                                        ; Вход: R0 - адрес спрайта объекта 2
                                        ;       R3 - адрес спрайта объекта 1
                                        ;       R4 - структура объекта 2
                                        ;       R5 - структура объекта 1
                                        ; Формат структуры см в другом месте

2$:             add     #PlayersBulletBufferItemSize, R4
                sob     R1, 1$
                return
; End of function Trap56

; ───────────────────────────────────────────────────────────────────────────
                .word 0

; ███████████████ S U B R O U T I N E ███████████████████████████████████████

; Вывод числовых значений счёта, жизней и т.п.
; Вход: R5 - адрес данных
;       R1 - адрес экрана

Trap60:         mov     2(SP), R5       ; восстанавливаем значение R5

OutLivesI$:     movb    (R5)+, R0       ; берём очередное значение, 0..9.
                cmpb    #171777, R0     ; дошли до конца?
                bne     1$              ; нет
                return
; ───────────────────────────────────────────────────────────────────────────

1$:             asl     R0              ; * 6
                mov     R0, R2
                asl     R0
                add     R2, R0
                add     PC, R0
                add     #<Digits$-.>, R0
                mov     (R0)+, R2
                mov     (R0)+, R3
                mov     (R0)+, R4
                mov     R2, (R1)
                bic     #7760, R2
                mov     R2, 100(R1)
                mov     R2, 200(R1)
                mov     R2, 300(R1)
                mov     R3, 400(R1)
                mov     R4, 1000(R1)
                bic     #7760, R4
                mov     R4, 500(R1)
                mov     R4, 600(R1)
                mov     R4, 700(R1)
                add     #2, R1
                br      OutLivesI$
; End of function Trap60

; ───────────────────────────────────────────────────────────────────────────
Digits$:        .word ^B0011001111001100
                .word ^B0000000000000000
                .word ^B0011001111001100
Num1$:          .word ^B0011000000000000
                .word ^B0000000000000000
                .word ^B0011000000000000
Num2$:          .word ^B0011001111110000
                .word ^B0000001111000000
                .word ^B0000111111001100
Num3$:          .word ^B0011001111110000
                .word ^B0000001111000000
                .word ^B0011001111110000
Num4$:          .word ^B0011000000001100
                .word ^B0000001111000000
                .word ^B0011000000000000
Num5$:          .word ^B0000111111001100
                .word ^B0000001111000000
                .word ^B0011001111110000
Num6$:          .word ^B0000111111001100
                .word ^B0000001111000000
                .word ^B0011001111001100
Num7$:          .word ^B0011001111001100
                .word ^B0000000000000000
                .word ^B0011000000000000
Num8$:          .word ^B0011001111001100
                .word ^B0000001111000000
                .word ^B0011001111001100
Num9$:          .word ^B0011001111001100
                .word ^B0000001111000000
                .word ^B0011001111110000
                .word ^B0000000000000000

; ███████████████ S U B R O U T I N E ███████████████████████████████████████

; Увеличение счёта

Trap62:         com     #-1
                beq     1$
                return
; ───────────────────────────────────────────────────────────────────────────

1$:             mov     #EndScore, R0

2$:             incb    -(R0)
                cmpb    #10., (R0)
                bne     3$
                clrb    (R0)
                br      2$
; ───────────────────────────────────────────────────────────────────────────

3$:             mov     #41002, R1
                mov     #Score, R5
                jmp     @#OutLivesI$
; End of function Trap62

; ───────────────────────────────────────────────────────────────────────────
                .word 0
                .word 0
                .word 0
                .word 0
                .word 0
                .word 0

; ███████████████ S U B R O U T I N E ███████████████████████████████████████

; Уменьшение двоично-десятичного числа
; Вход: R0 - конец числа

DecreaseValue:  decb    -(R0)
                bmi     1$
                return
; ───────────────────────────────────────────────────────────────────────────

1$:             movb    #9., (R0)
                br      DecreaseValue   ; Уменьшение двоично-десятичного числа
                                    ; Вход: R0 - конец числа
; End of function DecreaseValue 
; ───────────────────────────────────────────────────────────────────────────
                .word 0
                .word 0

; ███████████████ S U B R O U T I N E ███████████████████████████████████████

; Увеличение двоично-десятичного числа
; Вход: R0 - конец числа

IncreaseValue:  incb    -(R0)
                cmpb    #10., (R0)
                beq     1$
                return
; ───────────────────────────────────────────────────────────────────────────

1$:             clrb    (R0)
                br      IncreaseValue   ; Увеличение двоично-десятичного числа
                                        ; Вход: R0 - конец числа
; End of function IncreaseValue
; ───────────────────────────────────────────────────────────────────────────
                .word 0

; ███████████████ S U B R O U T I N E ███████████████████████████████████████

; Проверка, закончились  ли жизни, и если нет - то уменьшение
; если да - начать игру заново

CheckLives:     tst     @#Lives
                bne     1$
                jmp     @#PlayerDead
; ───────────────────────────────────────────────────────────────────────────

1$:             mov     #EndLives, R0
; ### заменить call на tst, чтобы жизни не уменьшались
                call    @#DecreaseValue ; Уменьшение двоично-десятичного числа
                                        ; Вход: R0 - конец числа
                mov     #Lives, R5
                mov     #41036, R1
                mov     #400, @#ObjForce ; !!! Возвращаем флаги как было, а то пушки самоуничтожаются.
                jmp     @#OutLivesI$
; End of function CheckLives

; ───────────────────────────────────────────────────────────────────────────
                .word 0
                .word 0
                .word 0
                .word 0
                .word 0
                .word 0

; ███████████████ S U B R O U T I N E ███████████████████████████████████████

; Установка констант для движения грунта влево

GoLeftConst:    mov     #77, @#T46CntVal1
                mov     #-101, @#T46CntVal2
                mov     #-1, @#T46CntVal3
                mov     #-2, @#T46CntVal4
                return
; End of function GoLeftConst

; ───────────────────────────────────────────────────────────────────────────
                .word 0
                .word 0
                .word 0

; ███████████████ S U B R O U T I N E ███████████████████████████████████████

; Установка констант для движения грунта вправо

GoRigthConst:   mov     #101, @#T46CntVal1
                mov     #101, @#T46CntVal2
                mov     #1, @#T46CntVal3
                mov     #2, @#T46CntVal4
                return
; End of function GoRigthConst

; ───────────────────────────────────────────────────────────────────────────
                .word 0
                .word 0
                .word 0
sprTree:        .word 26, 3
                .byte 200, 252, 2
                .byte 240, 253, 12
                .byte 50, 252, 52
                .byte 310, 352, 56
                .byte 250, 250, 10
                .byte 252, 353, 252
                .byte 242, 262, 252
                .byte 216, 216, 256
                .byte 350, 262, 12
                .byte 270, 214, 56
                .byte 250, 262, 50
                .byte 340, 316, 12
                .byte 200, 263, 2
                .byte 0, 216, 0
                .byte 0, 262, 0
                .byte 0, 14, 0
                .byte 0, 60, 0
                .byte 0, 14, 0
                .byte 0, 60, 0
                .byte 0, 14, 0
                .byte 0, 60, 0
                .byte 0, 314, 0
Sprite9$:       .word 3, 1
                .byte ^B00101000
                .byte ^B10101010
                .byte ^B00101000
                .byte 0
                .word 0
sprBreakTree:   .word 10, 3
                .byte 72, 0, 0
                .byte 256, 0, 0
                .byte 272, 263, 16
                .byte 354, 342, 53
                .byte 270, 73, 256
                .byte 40, 14, 273
                .byte 0, 262, 240
                .byte 200, 314, 2
word_23534:     .word 0
word_23536:     .word 177747

; буфер размером 60 слов, там каждый элемент - 10 слов
; итого - 6 элементов
; формат:
; 0 значение указателя в Buffer2
; 2 значение маски для слова по этому указателю
; 4 адрес экрана спрайта
; 6  \
; 10 - габариты
; 12 - крепкость
; 14 - адрес спрайта осколков
; 16 - 3 ???
TreeBufferItemsNum = 6
TreeBufferItemSize = 20
TreeBuffer:     .word 6572, 0, 76467, 2600, 3, 401, 23466, 3
                .word 6572, 0, 76460, 2600, 3, 401, 23466, 3
                .word 6572, 0, 76443, 2600, 3, 401, 23466, 3
                .word 6572, 0, 76434, 2600, 3, 401, 23466, 3
                .word 6572, 0, 76422, 2600, 3, 401, 23466, 3
                .word 6572, 0, 76405, 2600, 3, 401, 23466, 3
TreeBufferEnd:
TreeBufferSizeW = <TreeBufferEnd - TreeBuffer>/2

; ███████████████ S U B R O U T I N E ███████████████████████████████████████

; Прорисовка элементов на поверхности земли

DrawTrees:      dec     (PC)+
NewTreeCnt:     .word 3
                bne     8$
                mov     @#word_23534, R5
                bic     #177770, R5
                add     #7, R5
                mov     R5, @#NewTreeCnt
                mov     #3, R5
                ccc

Morph1$:        ror     @#word_23534
                sob     R5, Morph1$

Morph2$:        dec     @#word_23536
                bne     LoopGrnd$
                mov     #6, @#word_23536
                mov     #75037, @#word_23534

LoopGrnd$:      mov     #TreeBuffer, R5
                mov     #TreeBufferItemsNum, R4 ; количество элементов в буфере

1$:             tst     (R5)            ; пусто?
                beq     2$              ; да
                add     #TreeBufferItemSize, R5 ; нет - идём к следующему элементу
                sob     R4, 1$          ; и так весь массив
                return
; ───────────────────────────────────────────────────────────────────────────

2$:             mov     Buf2Ptr$, (R5)+

                bit     (PC)+, @(PC)+
Buf2Mask$:      .word   10
Buf2Ptr$:       .word   Buffer2 + 2
                bne     3$
                clr     (R5)
                br      4$
; ───────────────────────────────────────────────────────────────────────────

3$:             mov     @#Buf2Mask$, (R5)

4$:             ccc

Morph3$:        rol     @#Buf2Mask$
                bcc     5$

Morph4$:        adc     @#Buf2Mask$

Morph5$:        add     #2, @#Buf2Ptr$

Morph6$:        cmp     #Buffer2End, @#Buf2Ptr$
                bne     5$

Morph7$:        mov     #Buffer2, @#Buf2Ptr$

5$:             tst     (R5)+
                beq     6$
                mov     (PC)+, (R5)+
Morph8$:        .word 74600
                br      7$
; ───────────────────────────────────────────────────────────────────────────

6$:             mov     (PC)+, (R5)+
Morph9$:        .word 76400

7$:             mov     #2600, (R5)+
                mov     #3, (R5)+
                mov     #401, (R5)+
                mov     #Sprite9$, (R5)+
                mov     #3, (R5)+

8$:             mov     #TreeBuffer+4, R2

OutTreeLoop$:   mov     #sprTree, R0    ; спрайт дерева
                mov     (R2), R1        ; адрес спрайта
                beq     12$       ; 0 - нету дерева
                bit     #2000, R1       ; нормальное?
                beq     9$              ; да
                add     #sprBreakTree-sprTree, R0 ; нет - сломанное

9$:             trap    40              ; Стирание спрайта с экрана методом побитовой очистки
                                        ; Вход: R0 - адрес спрайта в памяти, первые 2 слова высота в строках и ширина в байтах
                                        ;       R1 - адрес экрана
                add     (PC)+, R1       ; проверка на выход за границы экрана
Morph10$:       .word 4
                bit     #77, R1
                bne     11$             ; ещё не вышло
                clr     (R2)            ; вышло - обнуляем адрес экрана
                cmp     #sprTree, R0    ; это дерево?
                beq     10$       ; да
                bic     -(R2), @-(R2)   ; нет - очищаем биты второго слова по адресу первого слова
                add     #4, R2

10$:            clr     -4(R2)          ; обнуляем первое слово
                br      12$
; ───────────────────────────────────────────────────────────────────────────

11$:            sub     (PC)+, R1       ; сдвигаем
Morph11$:       .word 3
                mov     R1, (R2)        ; сохраняем новый адрес
                trap    36              ; Вывод спрайта на экран методом наложения
                                        ; Вход: R0 - адрес спрайта в памяти, первые 2 слова высота в строках и ширина в байтах
                                        ;       R1 - адрес экрана
                mov     R0, R3          ; адрес спрайта сохраним
                mov     R2, R5
                mov     @#CurSprPlayer, R0 ; Адрес текущего спрайта игрока
                mov     #PlayerScrAddr, R4 ; Адрес спрайта игрока
                cmp     #sprBreakTree, R3
                bne     13$

12$:            add     #TreeBufferItemSize, R2
                cmp     #TreeBufferEnd+4, R2
                bne     OutTreeLoop$
                return
; ───────────────────────────────────────────────────────────────────────────

13$:            call    @#sub_24620     ; Проверка, не врезался ли игрок в дерево
                tstb    7(R2)
                bne     12$
                bic     #177700, (R2)
                bis     #76400, (R2)
                br      12$
; ───────────────────────────────────────────────────────────────────────────
                .word 0
; ───────────────────────────────────────────────────────────────────────────

jmp_24320:      inc     @#word_23536
                cmp     #6, @#word_23536
                bne     1$
                clr     @#word_23536
                mov     #75073, @#word_23534
                asl     @#word_23534

1$:             jmp     @#LoopGrnd$
; End of function DrawTrees

; ───────────────────────────────────────────────────────────────────────────
                .word 0

; ███████████████ S U B R O U T I N E ███████████████████████████████████████

; Подготовка прорисовки элементов на поверхности земли

sub_24360:      cmp     #sprPlayerLt, @#CurSprPlayer ; Адрес текущего спрайта игрока
                bne     1$       ; мутация функции в зависимости от направления движения игрока
                mov     #6037, @#Morph1$
                mov     #5337, @#Morph2$
                mov     #word_23536, @#Morph2$+2
                mov     #6137, @#Morph3$
                mov     #5537, @#Morph4$
                mov     #62737, @#Morph5$
                mov     #Buffer2End, @#Morph6$+2
                mov     #Buffer2, @#Morph7$+2
                bic     #77, @#Morph8$
                bic     #77, @#Morph9$
                mov     #4, @#Morph10$
                mov     #3, @#Morph11$
                br      2$
; ───────────────────────────────────────────────────────────────────────────

1$:             mov     #6137, @#Morph1$
                mov     #137, @#Morph2$
                mov     #jmp_24320, @#Morph2$+2
                mov     #6037, @#Morph3$
                mov     #6037, @#Morph4$
                mov     #162737, @#Morph5$
                mov     #Buffer2-2, @#Morph6$+2
                mov     #Buffer2End-2, @#Morph7$+2
                bis     #73, @#Morph8$
                bis     #73, @#Morph9$
                mov     #0, @#Morph10$
                mov     #1, @#Morph11$

2$:             jmp     @#DrawTrees     ; затем её выполнение
; End of function sub_24360

; ───────────────────────────────────────────────────────────────────────────
                .word 0

; ███████████████ S U B R O U T I N E ███████████████████████████████████████

; Проверка, не врезался ли игрок в дерево

sub_24620:      trap    54              ; Проверка на коллизию.
                                        ; Вход: R0 - адрес спрайта объекта 2
                                        ;       R3 - адрес спрайта объекта 1
                                        ;       R4 - структура объекта 2
                                        ;       R5 - структура объекта 1
                                        ; Формат структуры см в другом месте
                trap    56              ; Проверка попаданиями пулек игрока в объект
                                        ; Вход: R3 - спрайт объекта
                                        ;       R5 - структура объекта
                trap    64
                nop
                tstb    @#PlayerHit     ; 0 - есть попадание в игрока
                                        ; !0 - нет попадания
                bne     1$
                tstb    7(R2)
                bne     1$
                inc     @#ObjForce

1$:             nop
                nop
                return
; End of function sub_24620

; ───────────────────────────────────────────────────────────────────────────
                .word 0
sprCannon:      .word 20, 3
                .byte 0, 377, 0
                .byte 0, 377, 0
                .byte 0, 327, 0
                .byte 0, 327, 0
                .byte 300, 327, 3
                .byte 300, 175, 3
                .byte 300, 125, 3
                .byte 300, 125, 3
                .byte 360, 327, 17
                .byte 160, 377, 15
                .byte 160, 125, 15
                .byte 160, 125, 15
                .byte 160, 125, 15
                .byte 374, 377, 77
                .byte 377, 377, 377
                .byte 125, 125, 125
                .byte    0 ;
                .byte    0 ;
                .byte    0 ;
                .byte    0 ;
                .byte    0 ;
                .byte    0 ;
                .byte    0 ;
                .byte    0 ;
                .byte    0 ;
                .byte    0 ;
                .byte    0 ;
                .byte    0 ;
sprBreakCannon: .word 5, 3
                .byte 314, 60, 314
                .byte 163, 337, 303
                .byte 100, 125, 1
                .byte 124, 125, 25
                .byte 125, 125, 125
                .byte 0
                .word 0
                .word 0
CannonBufPtr:   .word 6641
                .word 0
                .word 0
                .word 0
sprBallBullet:  .word 5, 1
                .byte ^B00111100
                .byte ^B11101011
                .byte ^B11101011
                .byte ^B11101011
                .byte ^B00111100
                .byte 0
                .word 0
                .word 0
                .word 0
; структура параметров для пушки, такая же как для игрока
CannonStruct:   .word 77030             ; адрес
                .word 2000              ; габариты
                .word 3
                .word 402               ; прочность
                .word Sprite8$          ; осколки
                .word 1                 ; смещение центра разлёта
                .blkb 24

; ███████████████ S U B R O U T I N E ███████████████████████████████████████

; Функция подготавливает структуру параметров пушки

CannonPrepare:  cmp     #sprPlayerRt, @#CurSprPlayer ; Адрес текущего спрайта игрока
                beq     6$
                dec     (PC)+
NewCannonCnt:   .word 14                ; Счётчик до появления новой пушки  на экране
                beq     1$
                return
; ───────────────────────────────────────────────────────────────────────────

1$:             mov     @#CannonBufPtr, R5
                movb    (R5), @#NewCannonCnt

2$:             clr     R0
                bitb    #100, (R5)+
                beq     3$
                com     R0

3$:             bic     #100, @#NewCannonCnt
                mov     #CannonStruct, R5
                tst     R0
                beq     4$
                mov     #1400, (R5)

4$:             cmp     #sprPlayerRt, @#CurSprPlayer ; Адрес текущего спрайта игрока
                bne     5$
                bis     #73, (R5)

5$:             add     #75400, (R5)+
                mov     #2000, (R5)+
                mov     #3, (R5)+
                mov     #402, (R5)+
                mov     #Sprite8$, (R5)+
                mov     #1, (R5)+
                return
; ───────────────────────────────────────────────────────────────────────────

6$:             mov     @#CannonBufPtr, R5
                inc     @#NewCannonCnt
                movb    (R5), R4
                bic     #100, R4
                cmp     R4, @#NewCannonCnt
                blt     7$
                return
; ───────────────────────────────────────────────────────────────────────────

7$:             mov     #6, @#NewCannonCnt
                dec     R5
                br      2$
; End of function CannonPrepare

; ───────────────────────────────────────────────────────────────────────────
                .word 0
                .word 0
                .word 0

; ███████████████ S U B R O U T I N E ███████████████████████████████████████

; Обработка и вывод пушек, проверка на коллизии
; и вывод сломанных пушек

CannonAnim:     mov     #CannonStruct, R5
                mov     (R5), R1        ; пушка на экране есть?
                bne     1$              ; да
                return                  ; нету
; ───────────────────────────────────────────────────────────────────────────

1$:             bit     #2000, R1       ; какой у неё адрес
                beq     2$              ; как у нормальной
                mov     #sprBreakCannon, R0 ; будет сломанная пушка
                br      3$
; ───────────────────────────────────────────────────────────────────────────

2$:             mov     #sprCannon, R0  ; будет нормальная пушка

3$:             trap    40              ; Стирание спрайта с экрана методом побитовой очистки
                                        ; Вход: R0 - адрес спрайта в памяти, первые 2 слова высота в строках и ширина в байтах
                                        ;       R1 - адрес экрана
                cmp     #sprPlayerRt, @#CurSprPlayer ; куда летим?
                beq     5$              ; вправо
                add     #4, R1          ; влево, значит грунт движется вправо
                bit     #77, R1
                bne     6$
4$:             br      9$
; ───────────────────────────────────────────────────────────────────────────

5$:             bit     #77, R1
                beq     4$
                add     #2, R1

6$:             sub     #3, R1
                mov     R0, R3
                mov     @#CurSprPlayer, R0 ; Адрес текущего спрайта игрока
                mov     #PlayerScrAddr, R4 ; Адрес спрайта игрока
                call    @#sub_25600
                nop
                nop
                mov     R3, R0
                tstb    @#PlayerHit     ; 0 - есть попадание в игрока
                                        ; !0 - нет попадания
                beq     7$
                tstb    7(R5)
                bne     8$

7$:             mov     #sprBreakCannon, R0
                bic     #77700, R1
                bis     #77100, R1

8$:             mov     R1, (R5)
                trap    36              ; Вывод спрайта на экран методом наложения
                                        ; Вход: R0 - адрес спрайта в памяти, первые 2 слова высота в строках и ширина в байтах
                                        ;       R1 - адрес экрана
                return
; ───────────────────────────────────────────────────────────────────────────

9$:             mov     @#CannonBufPtr, R4
                bit     #2000, (R5)
                beq     10$
                bisb    #100, (R4)

10$:            nop
                clr     (R5)
                cmp     #sprPlayerRt, @#CurSprPlayer ; Адрес текущего спрайта игрока
                beq     12$
                add     #1, @#CannonBufPtr
                cmp     #CannonBuffer+CannonBufSize-1, @#CannonBufPtr
                bne     11$
                mov     #CannonBuffer, @#CannonBufPtr
11$:            return
; ───────────────────────────────────────────────────────────────────────────

12$:            sub     #1, @#CannonBufPtr
                cmp     #CannonBuffer-1, @#CannonBufPtr
                bne     13$
                mov     #CannonBuffer+CannonBufSize-2, @#CannonBufPtr
13$:            return
; End of function CannonAnim

; ───────────────────────────────────────────────────────────────────────────
                .word 0
                .word 0
                .word 0
                .word 0
                .word 0

; ███████████████ S U B R O U T I N E ███████████████████████████████████████


sub_25600:      bit     #2000, R1       ; пушка подбита
                bne     1$              ; да - ничего не делать
                trap    54              ; Проверка на коллизию.
                                        ; Вход: R0 - адрес спрайта объекта 2
                                        ;       R3 - адрес спрайта объекта 1
                                        ;       R4 - структура объекта 2
                                        ;       R5 - структура объекта 1
                                        ; Формат структуры см в другом месте
                trap    56              ; Проверка попаданиями пулек игрока в объект
                                        ; Вход: R3 - спрайт объекта
                                        ;       R5 - структура объекта
                nop
                nop
1$:             return
; End of function sub_25600


; ███████████████ S U B R O U T I N E ███████████████████████████████████████

; Выстрел из пушки

CannonShootAnim:bit     #400, @#CannonStruct
                bne     1$
                return
; ───────────────────────────────────────────────────────────────────────────

1$:             tst     (PC)+
NewCannonShootCnt:.word 7
                bne     12$
                mov     #CannonBulletBuffer, R5
                mov     #CannonBulletBufferItemsNum, R4

2$:             tst     2(R5)
                beq     3$
                add     #EnemyBulletBufferItemSize, R5
                sob     R4, 2$
                return
; ───────────────────────────────────────────────────────────────────────────

3$:             call    @#sub_27740
                mov     @#CannonStruct, R4
                mov     R4, (R5)+
                mov     @#PlayerScrAddr, R3 ; Адрес спрайта игрока
                add     #3000, R3
                mov     R3, R1
                mov     R4, R2
                bic     #177700, R1
                bic     #177700, R2
                sub     R1, R2
                cmp     #3, R2
                blt     4$
                cmp     #-1, R2
                bgt     4$
                mov     #-500, (R5)+
                br      11$
; ───────────────────────────────────────────────────────────────────────────

4$:             cmp     R3, R4
                bmi     7$
                tst     R2
                bmi     5$
                mov     #-2, (R5)+
                br      6$
; ───────────────────────────────────────────────────────────────────────────

5$:             mov     #2, (R5)+
6$:             br      11$
; ───────────────────────────────────────────────────────────────────────────

7$:             tst     R2
                bmi     9$
                sub     R3, R4

8$:             asr     R4
                asr     R2
                bne     8$
                nop
                bic     #77, R4
                inc     R4
                neg     R4
                mov     R4, (R5)+
                br      11$
; ───────────────────────────────────────────────────────────────────────────

9$:             sub     R3, R4
                com     R2
                nop

10$:            asr     R4
                asr     R2
                bne     10$
                bis     #77, R4
                add     #100, R4
                neg     R4
                mov     R4, (R5)+

11$:            mov     #16, @#NewCannonShootCnt
                mov     #400, (R5)+
                mov     #2, (R5)+
                mov     #1, (R5)+
                clr     (R5)
                br      13$
; ───────────────────────────────────────────────────────────────────────────

12$:            dec     @#NewCannonShootCnt
                return
; ───────────────────────────────────────────────────────────────────────────

13$:            cmp     #sprPlayerRt, @#CurSprPlayer ; Адрес текущего спрайта игрока
                beq     14$
                dec     -10(R5)
14$:            return
; End of function CannonShootAnim

; ───────────────────────────────────────────────────────────────────────────
                .word 0
                .word 0
                .word 0
                .word 0

; ███████████████ S U B R O U T I N E ███████████████████████████████████████

; Анимация полёта выстрелов врагов

EnemyShootAnim:      mov     #EnemyBulletBuffer, R5
                mov     #EnemyBulletBufferItemsNum, R2

1$:             cmp     #sprBallBullet, (R5)
                beq     3$
                add     #EnemyBulletBufferItemSize, R5

2$:             sob     R2, 1$
                return
; ───────────────────────────────────────────────────────────────────────────

3$:             mov     (R5)+, R0
                mov     (R5)+, R1
                bne     5$

4$:             add     #EnemyBulletBufferItemSize-4, R5
                br      2$
; ───────────────────────────────────────────────────────────────────────────

5$:             trap    40              ; Стирание спрайта с экрана методом побитовой очистки
                                        ; Вход: R0 - адрес спрайта в памяти, первые 2 слова высота в строках и ширина в байтах
                                        ;       R1 - адрес экрана
                add     (R5), -(R5)
                cmp     #sprPlayerRt, @#CurSprPlayer ; Адрес текущего спрайта игрока
                beq     6$
                inc     (R5)

6$:             mov     (R5), R1
                cmp     #77000, R1
                bmi     7$
                cmp     #42300, R1
                bmi     8$

7$:             clr     (R5)+
                br      4$
; ───────────────────────────────────────────────────────────────────────────

8$:             bit     #74, R1
                beq     7$
                add     #2, R1
                bit     #74, R1
                beq     7$
                mov     (R5)+, R1
                trap    36              ; Вывод спрайта на экран методом наложения
                                        ; Вход: R0 - адрес спрайта в памяти, первые 2 слова высота в строках и ширина в байтах
                                        ;       R1 - адрес экрана
                br      4$
; End of function EnemyShootAnim

; ───────────────────────────────────────────────────────────────────────────
                .word 0
                .word 0
                .word 0
                .word 0
                .word 0
; временная структура вражеского выстрела, для проверки на коллизии
TmpEnmyBulltStruct: .word 0
                .word 400
                .word 2
                .word 0
                .word 0
                .word 0
                .word 0

; ███████████████ S U B R O U T I N E ███████████████████████████████████████

; проверка попали ли вражеские выстрелы в игрока
; и проверка, попал ли игрок куда-нибудь

sub_26320:      mov     #EnemyBulletBuffer+14, R1
                mov     #EnemyBulletBufferItemsNum, R2

1$:             mov     #TmpEnmyBulltStruct+10, R5
                mov     -(R1), -(R5)
                bne     3$
                add     #EnemyBulletBufferItemSize+2, R1

2$:             sob     R2, 1$
                return
; ───────────────────────────────────────────────────────────────────────────

3$:             mov     -(R1), -(R5)
                mov     -(R1), -(R5)
                mov     -(R1), -(R5)
                mov     -(R1), (R5)
                bne     5$

4$:             add     #EnemyBulletBufferItemSize+12, R1
                br      2$
; ───────────────────────────────────────────────────────────────────────────

5$:             mov     -(R1), R3
                mov     (R1)+, R3
                mov     @#CurSprPlayer, R0 ; Адрес текущего спрайта игрока
                mov     #PlayerScrAddr, R4 ; Адрес спрайта игрока
                trap    54              ; Проверка на коллизию.
                                        ; Вход: R0 - адрес спрайта объекта 2
                                        ;       R3 - адрес спрайта объекта 1
                                        ;       R4 - структура объекта 2
                                        ;       R5 - структура объекта 1
                                        ; Формат структуры см в другом месте
                trap    56              ; Проверка попаданиями пулек игрока в объект
                                        ; Вход: R3 - спрайт объекта
                                        ;       R5 - структура объекта
                mov     (R5), (R1)
                call    @#sub_6662
                br      4$
; End of function sub_26320


; ███████████████ S U B R O U T I N E ███████████████████████████████████████


Trap64:         mov     2(SP), R5
                mov     #EnemyBulletBuffer+14, R1
                mov     #EnemyBulletBufferItemsNum, R2

1$:             mov     #TmpEnmyBulltStruct+10, R4
                mov     -(R1), -(R4)
                bne     3$
                add     #EnemyBulletBufferItemSize+2, R1

2$:             sob     R2, 1$
                return
; ───────────────────────────────────────────────────────────────────────────

3$:             mov     -(R1), -(R4)
                mov     -(R1), -(R4)
                mov     -(R1), -(R4)
                mov     -(R1), (R4)
                bne     5$

4$:             add     #EnemyBulletBufferItemSize+12, R1
                br      2$
; ───────────────────────────────────────────────────────────────────────────

5$:             mov     -(R1), R0
                tst     (R1)+
                trap    54              ; Проверка на коллизию.
                                        ; Вход: R0 - адрес спрайта объекта 2
                                        ;       R3 - адрес спрайта объекта 1
                                        ;       R4 - структура объекта 2
                                        ;       R5 - структура объекта 1
                                        ; Формат структуры см в другом месте
                mov     (R4), (R1)
                mov     6(R4), 10(R1)
                br      4$
; End of function Trap64

; ───────────────────────────────────────────────────────────────────────────
                .word 0
                .word 0
sprCloud1:      .word 15, 6
                .byte 200, 2, 240, 12, 0, 0
                .byte 240, 50, 12, 52, 250, 2
                .byte 40, 210, 202, 202, 202, 12
                .byte 40, 212, 242, 50, 0, 12
                .byte 10, 212, 42, 240, 10, 2
                .byte 12, 202, 0, 242, 200, 12
                .byte 212, 210, 240, 200, 42, 40
                .byte 50, 0, 52, 10, 12, 242
                .byte 40, 52, 240, 0, 212, 242
                .byte 240, 242, 210, 252, 202, 240
                .byte 50, 40, 2, 250, 250, 50
                .byte 250, 212, 250, 202, 240, 12
                .byte 240, 2, 12, 0, 52, 0
sprCloud2:      .word 15, 6
                .byte 200, 12, 0, 12, 240, 0
                .byte 240, 52, 10, 50, 250, 2
                .byte 0, 0, 12, 0, 12, 12
                .byte 240, 200, 202, 12, 0, 10
                .byte 50, 200, 40, 50, 0, 0
                .byte 12, 0, 2, 0, 210, 12
                .byte 12, 2, 2, 240, 0, 50
                .byte 50, 0, 202, 200, 2, 240
                .byte 0, 240, 2, 200, 202, 200
                .byte 0, 40, 12, 240, 200, 0
                .byte 10, 0, 0, 52, 200, 50
                .byte 50, 52, 240, 2, 210, 12
                .byte 240, 2, 52, 240, 2, 2
sprCloudEnd:
SprCloudSize = sprCloud2 - sprCloud1
CloudsNum = 2
CloudsItemSize = 6
CloudsTbl:      .word sprCloud2
                .word 51261
                .word 177777
                .word sprCloud2
                .word 55271
                .word 177777

; ███████████████ S U B R O U T I N E ███████████████████████████████████████

; Вывод и анимация облаков

CloudsAnim:     tst     (PC)+
NewCloudCnt:    .word   7
                bne     3$
                mov     #10, @#NewCloudCnt 
                mov     #CloudsTbl, R5
                tst     (R5)
                beq     1$
                add     #CloudsItemSize, R5
                tst     (R5)
                bne     3$

1$:             mov     #sprCloud1, (R5)+
                mov     @#177710, R4
                add     #42000, R4
                bit     #1, R4
                beq     2$
                bic     #77, R4
                bis     #72, R4
                mov     R4, (R5)+
                mov     #-1, (R5)+
                br      3$
; ───────────────────────────────────────────────────────────────────────────

2$:             bic     #74, R4
                mov     R4, (R5)+
                mov     #1, (R5)+

3$:             dec     @#NewCloudCnt 
                mov     #CloudsTbl, R5
                mov     #CloudsNum, R4

4$:             mov     (R5)+, R0
                bne     7$

5$:             tst     (R5)+

6$:             tst     (R5)+
                sob     R4, 4$
                return
; ───────────────────────────────────────────────────────────────────────────

7$:             mov     (R5)+, R1
                beq     6$
                mov     (R5), R2
                bmi     8$
                cmp     #sprPlayerRt, @#CurSprPlayer ; Адрес текущего спрайта игрока
                beq     9$
                inc     R2
                inc     R2
                br      9$
; ───────────────────────────────────────────────────────────────────────────

8$:             cmp     #sprPlayerRt, @#CurSprPlayer ; Адрес текущего спрайта игрока
                bne     9$
                asl     R2
                dec     R2

9$:             bit     #1, @#177710
                beq     10$
                add     #200, R2
                br      11$
; ───────────────────────────────────────────────────────────────────────────

10$:            sub     #200, R2

11$:            add     R1, R2
                trap    42              ; Стирание спрайта с экрана clrом
                                        ; Вход: R0 - адрес спрайта в памяти, первые 2 слова высота в строках и ширина в байтах
                                        ;       R1 - адрес экрана
                cmp     #42300, R2
                bmi     13$

12$:            clr     -(R5)
                clr     -(R5)
                br      4$
; ───────────────────────────────────────────────────────────────────────────

13$:            bit     #76, R2
                beq     12$
                add     #6, R2
                bit     #74, R2
                beq     12$

                sub     #6, R2
                cmp     #75600, R2
                bpl     14$
                sub     #2000, R2

14$:            mov     R2, R1
                trap    34              ; Вывод спрайта на экран movом
                                        ; Вход: R0 - адрес спрайта в памяти, первые 2 слова высота в строках и ширина в байтах
                                        ;       R1 - адрес экрана
                mov     R1, -(R5)
                add     #SprCloudSize, R0
                cmp     #sprCloudEnd, R0
                bne     15$
                mov     #sprCloud1, R0

15$:            mov     R0, -(R5)
                tst     (R5)+
                br      5$
; End of function CloudsAnim

; ───────────────────────────────────────────────────────────────────────────
                .word 0
                .word 0
sprSmlCloud1:   .word 12, 4
                .byte 240, 12, 250, 12
                .byte 250, 52, 52, 52
                .byte 12, 50, 52, 50
                .byte 212, 40, 250, 240
                .byte 212, 252, 200, 242
                .byte 12, 252, 212, 242
                .byte 52, 10, 250, 252
                .byte 252, 200, 40, 252
                .byte 250, 252, 2, 52
                .byte 240, 240, 200, 12
sprSmlCloud2:   .word 12, 4
                .byte 240, 12, 240, 12
                .byte 50, 10, 12, 50
                .byte 2, 240, 0, 40
                .byte 202, 200, 40, 242
                .byte 12, 200, 2, 200
                .byte 40, 10, 202, 210
                .byte 202, 2, 240, 200
                .byte 2, 0, 10, 200
                .byte 12, 12, 42, 50
                .byte 240, 250, 200, 12
sprSmlCloudEnd:
SprSmlCloudsSize = sprSmlCloud2 - sprSmlCloud1  ; 54
SmlCloudsNum = 2
SmlCloudsItemSize = 4
SmlCloudsTbl:   .word 0
                .word 76061
                .word 0
                .word 76151

; ███████████████ S U B R O U T I N E ███████████████████████████████████████


DustCloudAnim:  clr     @#GrowPlayerAddr ; Приращение адреса игрока
                cmp     #74300, @#PlayerScrAddr ; Адрес спрайта игрока
                bpl     4$
                sub     #600, @#GrowPlayerAddr ; Приращение адреса игрока
                mov     #SmlCloudsTbl, R5
                tst     (R5)
                beq     1$
                add     #SmlCloudsItemSize, R5
                tst     (R5)
                bne     4$

1$:             mov     #sprSmlCloud1-SprSmlCloudsSize, (R5)+
                mov     @#PlayerScrAddr, R4 ; Адрес спрайта игрока
                cmp     #sprPlayerRt, @#CurSprPlayer ; Адрес текущего спрайта игрока
                beq     2$
                add     #1501, R4
                br      3$
; ───────────────────────────────────────────────────────────────────────────

2$:             add     #1477, R4

3$:             mov     R4, (R5)+

4$:             com     #0
                nop
                mov     #SmlCloudsTbl, R5
                mov     #SmlCloudsNum, R4

5$:             mov     (R5)+, R0
                bne     7$

6$:             tst     (R5)+
                sob     R4, 5$
                return
; ───────────────────────────────────────────────────────────────────────────

7$:             mov     (R5), R1
                beq     6$
                cmp     #sprSmlCloudEnd, R0
                bne     8$
                mov     #sprSmlCloud1, R0
                trap    42              ; Стирание спрайта с экрана clrом
                                        ; Вход: R0 - адрес спрайта в памяти, первые 2 слова высота в строках и ширина в байтах
                                        ;       R1 - адрес экрана
                clr     -(R5)
                tst     (R5)+
                br      6$
; ───────────────────────────────────────────────────────────────────────────

8$:             cmp     #sprSmlCloud1-SprSmlCloudsSize, R0
                beq     9$
                trap    42              ; Стирание спрайта с экрана clrом
                                        ; Вход: R0 - адрес спрайта в памяти, первые 2 слова высота в строках и ширина в байтах
                                        ;       R1 - адрес экрана
9$:             add     #SprSmlCloudsSize, R0
                cmp     #sprSmlCloudEnd, R0
                bne     10$
                mov     #sprSmlCloud1, R0
                trap    34              ; Вывод спрайта на экран movом
                                        ; Вход: R0 - адрес спрайта в памяти, первые 2 слова высота в строках и ширина в байтах
                                        ;       R1 - адрес экрана
                add     #SprSmlCloudsSize, R0
                trap    40              ; Стирание спрайта с экрана методом побитовой очистки
                                        ; Вход: R0 - адрес спрайта в памяти, первые 2 слова высота в строках и ширина в байтах
                                        ;       R1 - адрес экрана
                mov     #sprSmlCloudEnd, R0
                br      11$
; ───────────────────────────────────────────────────────────────────────────

10$:            trap    34              ; Вывод спрайта на экран movом
                                        ; Вход: R0 - адрес спрайта в памяти, первые 2 слова высота в строках и ширина в байтах
                                        ;       R1 - адрес экрана
11$:            mov     R0, -(R5)
                tst     (R5)+
                br      6$
; End of function DustCloudAnim

; ───────────────────────────────────────────────────────────────────────────
Sound8$:        .word 10
                .word 20
                .word 200
                .word 0

; ███████████████ S U B R O U T I N E ███████████████████████████████████████


sub_27740:      mov     #sprBallBullet, (R5)+
                mov     R1, -(SP)
                mov     #Sound8$, R1
                trap    14              ; Вывод звука
                                        ; Вход R1 - адрес таблицы параметров
                                        ; .word длит
                                        ; .word тон, тон,... (0 - конец таблицы)
                mov     (SP)+, R1
                return
; End of function sub_27740


; ███████████████ S U B R O U T I N E ███████████████████████████████████████

; Инициализация ачивок

InitAchievs:    clr     @#MoveSpeed     ; Скорость передвижения
                mov     #3, @#ShootSpeed+2 ; Ускорение стрельбы (меньше - быстрее)
                clr     @#NShooting     ; Количество выстреливаемых очередей
                return
; End of function InitAchievs

; ───────────────────────────────────────────────────────────────────────────
sprLiveBox:     .word 13, 3
                .byte 125, 0, 0
                .byte 167, 5, 0
                .byte 135, 5, 0
                .byte 167, 5, 0
                .byte 135, 5, 0
                .byte 167, 5, 0
                .byte 135, 105, 25
                .byte 167, 125, 127
                .byte 135, 325, 125
                .byte 167, 165, 127
                .byte 335, 335, 125
                .byte 0
                .word 0
; это по сути тоже структура, эти переменные не должны отделяться друг от друга
LiveBoxScrAddr: .word 0
LiveBoxDelay:   .word 7
LiveBoxTrack:   .word BoxTrckOffsets
                .word 0
; таблица смещений адреса ящиков, чтобы они летали по замысловатой траектории
; формат: .word задержка, смещение
                .word 10
BoxTrckOffsets: .word -676, 4
                .word 2,    10
                .word 702,  6
                .word 700,  4
                .word 676,  3
                .word -2,   4
                .word -702, 6
                .word -700
BoxTrckOffsetsEnd:
; ███████████████ S U B R O U T I N E ███████████████████████████████████████

; Вывод и анимация ящика с жизнью

LiveBoxAnim:    cmp     #4411, @#Lives  ; жизней и так максимум?
                bne     1$              ; нет
                return                  ; да - никаких ящиков

1$:             tst     (PC)+
LiveBoxCnt:     .word 324
                bne     3$
                mov     #500, @#LiveBoxCnt
                mov     #LiveBoxScrAddr, R5
                tst     (R5)            ; ящик на экране?
                beq     2$              ; нет - добавим
                return                  ; да - не надо добавлять новый
; ───────────────────────────────────────────────────────────────────────────

2$:             mov     @#177710, R4
                bic     #77, R4
                add     #42002, R4
                mov     R4, (R5)+       ; новый адрес ящика
                br      3$
; ───────────────────────────────────────────────────────────────────────────
                .word 11
                .word 12725
                .word BoxTrckOffsets
; ───────────────────────────────────────────────────────────────────────────

3$:             dec     @#LiveBoxCnt
                mov     #LiveBoxScrAddr, R5
                mov     (R5)+, R1       ; текущий адрес ящика
                bne     4$              ; если на экране - продолжаем
                return                  ; вне экрана - выход
; ───────────────────────────────────────────────────────────────────────────

4$:             mov     #sprLiveBox, R0
                trap    40              ; Стирание спрайта с экрана методом побитовой очистки
                                        ; Вход: R0 - адрес спрайта в памяти, первые 2 слова высота в строках и ширина в байтах
                                        ;       R1 - адрес экрана
                dec     (R5)+           ; LiveBoxDelay
                bne     6$              ; задержка ещё не истекла

5$:             mov     (R5), R4        ; LiveBoxTrack - указатель в массиве BoxTrckOffsets
                add     #2, R4          ; двигаем указатель
                mov     (R4)+, R3       ; берём новое смещение, ещё раз двигаем указатель
                mov     R4, (R5)        ; сохраняем новое значение указателя
                cmp     #BoxTrckOffsetsEnd+2, R4 ; дошли до конца массива?
                ble     8$              ; да
                mov     R3, -(R5)       ; это было не смещение, это была задержка
                tst     (R5)+

6$:             mov     R1, R2          ; адрес экрана
                add     @(R5)+, R2      ; прибавляем смещение
                mov     -(R5), R4       ; 
                cmp     #42300, R2      ; проверяем не вышло ли за экран
                bpl     5$
                cmp     #76000, R2
                bmi     5$
                bit     #76, R2
                beq     5$
                add     #3, R2
                bit     #76, R2
                bne     7$
                clr     @#LiveBoxScrAddr ; вышло за экран
                return
; ───────────────────────────────────────────────────────────────────────────

7$:             sub     #3, R2          ; не вышло - рисуем на новом месте
                mov     R2, R1
                trap    36              ; Вывод спрайта на экран методом наложения
                                        ; Вход: R0 - адрес спрайта в памяти, первые 2 слова высота в строках и ширина в байтах
                                        ;       R1 - адрес экрана
                mov     R2, @#LiveBoxScrAddr
                return
; ───────────────────────────────────────────────────────────────────────────

8$:             mov     #11, @#LiveBoxDelay
                mov     #BoxTrckOffsets, @#LiveBoxTrack
                br      6$
; End of function LiveBoxAnim

; ───────────────────────────────────────────────────────────────────────────
                .word 0
                .word 0
                .word 0
                .word 0
                .word 0
; две временные структуры для проверки, поймал ли игрок коробку
; временная структура игрока
TmpStructPlayer:.word 64724
                .word 2700
                .word 4
                .word 1
                .word 0
                .word 0
                .word 0
                .word 0
; временная структура коробки с L,F,S,N, для проверки на коллизии
TmpStructBox:   .word 0
                .word 1300
                .word 3
                .word 1
                .word 0
                .word 0
                .word 0
                .word 0

; ███████████████ S U B R O U T I N E ███████████████████████████████████████

; Проверка поймал ли игрок коробку с жизнью
; и если да - то увеличение жизней

LiveBoxCatch:   mov     #1, @#TmpStructPlayer+6
                mov     @#PlayerScrAddr, @#TmpStructPlayer ; Адрес спрайта игрока
                mov     #1, @#TmpStructBox+6
                mov     @#LiveBoxScrAddr, @#TmpStructBox
                mov     #TmpStructBox, R5
                mov     #TmpStructPlayer, R4
                mov     #sprLiveBox, R3
                mov     @#CurSprPlayer, R0 ; Адрес текущего спрайта игрока
                trap    54              ; Проверка на коллизию.
                                        ; Вход: R0 - адрес спрайта объекта 2
                                        ;       R3 - адрес спрайта объекта 1
                                        ;       R4 - структура объекта 2
                                        ;       R5 - структура объекта 1
                                        ; Формат структуры см в другом месте
                nop
                nop
                nop
                nop
                tst     @#TmpStructBox+6
                beq     2$

1$:             return
; ───────────────────────────────────────────────────────────────────────────

2$:             tst     @#TmpStructPlayer+6
                bne     1$
                mov     #EndLives, R0
                call    @#IncreaseValue ; Увеличение двоично-десятичного числа
                                        ; Вход: R0 - конец числа
                mov     #SoundLBoxCatch, R1
                trap    14
                clr     @#LiveBoxScrAddr
                mov     #Lives, R5
                mov     #41036, R1
                trap    60              ; Вывод числовых значений счёта, жизней и т.п.
                                        ; Вход: R5 - адрес данных
                                        ;       R1 - адрес экрана
                return
; End of function LiveBoxCatch

; ───────────────────────────────────────────────────────────────────────────
SoundLBoxCatch: .word 10
                .word 50
                .word 300
                .word 50
                .word 0
                .word 0
                .word 0
                .word 0
                .word 0
sprSpeedBox:    .word 13, 3
                .byte 120, 125, 5
                .byte 164, 167, 127
                .byte 335, 335, 125
                .byte 127, 1, 0
                .byte 135, 125, 5
                .byte 167, 167, 125
                .byte 334, 335, 125
                .byte 0, 100, 127
                .byte 125, 325, 125
                .byte 167, 167, 127
                .byte 334, 335, 25
                .byte 0
                .word 0
SpeedBoxScrAddr:.word 0
SpeedBoxDelay:  .word 2
SpeedBoxTrack:  .word BoxTrckOffsets+10
                .word 0

; ███████████████ S U B R O U T I N E ███████████████████████████████████████

; Вывод и анимация ящика с ускорением

SpeedBoxAnim:   cmp     #2, @#MoveSpeed ; Скорость передвижения
                bne     1$
                return
; ───────────────────────────────────────────────────────────────────────────

1$:             tst     (PC)+
SpeedBoxCnt:    .word 263
                bne     3$
                mov     #440, @#SpeedBoxCnt
                mov     #SpeedBoxScrAddr, R5
                tst     (R5)
                beq     2$
                return
; ───────────────────────────────────────────────────────────────────────────

2$:             mov     @#177710, R4
                bic     #77, R4
                add     #42002, R4
                mov     R4, (R5)+
                nop
                nop
                nop
                nop

3$:             dec     @#SpeedBoxCnt
                mov     #SpeedBoxScrAddr, R5
                mov     (R5)+, R1
                bne     4$
                return
; ───────────────────────────────────────────────────────────────────────────

4$:             mov     #sprSpeedBox, R0
                trap    40              ; Стирание спрайта с экрана методом побитовой очистки
                                        ; Вход: R0 - адрес спрайта в памяти, первые 2 слова высота в строках и ширина в байтах
                                        ;       R1 - адрес экрана
                dec     (R5)+
                bne     6$

5$:             mov     (R5), R4
                add     #2, R4
                mov     (R4)+, R3
                mov     R4, (R5)
                cmp     #BoxTrckOffsetsEnd+2, R4 ; Вывод и анимация ящика с жизнью
                ble     8$
                mov     R3, -(R5)
                tst     (R5)+

6$:             mov     R1, R2
                add     @(R5)+, R2
                mov     -(R5), R4
                cmp     #42300, R2
                bpl     5$
                cmp     #76000, R2
                bmi     5$
                bit     #76, R2
                beq     5$
                add     #3, R2
                bit     #76, R2
                bne     7$
                clr     @#SpeedBoxScrAddr
                return
; ───────────────────────────────────────────────────────────────────────────

7$:             sub     #3, R2
                mov     R2, R1
                trap    36              ; Вывод спрайта на экран методом наложения
                                        ; Вход: R0 - адрес спрайта в памяти, первые 2 слова высота в строках и ширина в байтах
                                        ;       R1 - адрес экрана
                mov     R2, @#SpeedBoxScrAddr
                return
; ───────────────────────────────────────────────────────────────────────────

8$:             mov     #11, @#SpeedBoxDelay
                mov     #BoxTrckOffsets, @#SpeedBoxTrack
                br      6$
; End of function SpeedBoxAnim

; ───────────────────────────────────────────────────────────────────────────
                .word 0
                .word 0
                .word 0
                .word 0
                .word 0

; ███████████████ S U B R O U T I N E ███████████████████████████████████████

; Проверка поймал ли игрок коробку с ускорением
; и если да - то увеличение скорости передвижения

SpeedBoxCatch:  mov     #1, @#TmpStructPlayer+6
                mov     @#PlayerScrAddr, @#TmpStructPlayer ; Адрес спрайта игрока
                mov     #1, @#TmpStructBox+6
                mov     @#SpeedBoxScrAddr, @#TmpStructBox
                mov     #TmpStructBox, R5
                mov     #TmpStructPlayer, R4
                mov     #sprSpeedBox, R3
                mov     @#CurSprPlayer, R0 ; Адрес текущего спрайта игрока
                trap    54              ; Проверка на коллизию.
                                        ; Вход: R0 - адрес спрайта объекта 2
                                        ;       R3 - адрес спрайта объекта 1
                                        ;       R4 - структура объекта 2
                                        ;       R5 - структура объекта 1
                                        ; Формат структуры см в другом месте
                nop
                nop
                nop
                nop
                tst     @#TmpStructBox+6
                beq     2$

1$:             return
; ───────────────────────────────────────────────────────────────────────────

2$:             tst     @#TmpStructPlayer+6
                bne     1$
                inc     @#MoveSpeed     ; Скорость передвижения
                mov     #SoundSBoxCatch, R1
                trap    14
                clr     @#SpeedBoxScrAddr
                return
; End of function SpeedBoxCatch

; ───────────────────────────────────────────────────────────────────────────
SoundSBoxCatch:       .word 4
                .word 400
                .word 200
                .word 100
                .word 40
                .word 0
                .word 0
                .word 0
sprNBox:           .word 13, 3
                .byte 25, 100, 5
                .byte 127, 101, 127
                .byte 135, 305, 125
                .byte 167, 125, 127
                .byte 335, 325, 125
                .byte 167, 127, 127
                .byte 335, 335, 125
                .byte 127, 167, 127
                .byte 135, 335, 125
                .byte 127, 161, 127
                .byte 135, 301, 125
                .byte 0
                .word 0
NBoxScrAddr:    .word 0
NBoxDelay:      .word 6
NBoxTrack:      .word BoxTrckOffsets+14
                .word 0

; ███████████████ S U B R O U T I N E ███████████████████████████████████████

; Вывод и анимация ящика N

NBoxAnim:       cmp     #2, @#NShooting ; Количество выстреливаемых очередей
                bne     1$
                return
; ───────────────────────────────────────────────────────────────────────────

1$:             tst     (PC)+
NBoxCnt:        .word 10
                bne     3$
                mov     #411, @#NBoxCnt
                mov     #NBoxScrAddr, R5
                tst     (R5)
                beq     2$
                return
; ───────────────────────────────────────────────────────────────────────────

2$:             mov     @#177710, R4
                bic     #77, R4
                add     #42002, R4
                mov     R4, (R5)+
                nop
                nop
                nop
                nop

3$:             dec     @#NBoxCnt
                mov     #NBoxScrAddr, R5
                mov     (R5)+, R1
                bne     4$
                return
; ───────────────────────────────────────────────────────────────────────────

4$:             mov     #sprNBox, R0
                trap    40              ; Стирание спрайта с экрана методом побитовой очистки
                                        ; Вход: R0 - адрес спрайта в памяти, первые 2 слова высота в строках и ширина в байтах
                                        ;       R1 - адрес экрана
                dec     (R5)+
                bne     6$

5$:             mov     (R5), R4
                add     #2, R4
                mov     (R4)+, R3
                mov     R4, (R5)
                cmp     #BoxTrckOffsetsEnd+2, R4 ; Вывод и анимация ящика с жизнью
                ble     8$
                mov     R3, -(R5)
                tst     (R5)+

6$:             mov     R1, R2
                add     @(R5)+, R2
                mov     -(R5), R4
                cmp     #42300, R2
                bpl     5$
                cmp     #76000, R2
                bmi     5$
                bit     #76, R2
                beq     5$
                add     #3, R2
                bit     #76, R2
                bne     7$
                clr     @#NBoxScrAddr
                return
; ───────────────────────────────────────────────────────────────────────────

7$:             sub     #3, R2
                mov     R2, R1
                trap    36              ; Вывод спрайта на экран методом наложения
                                        ; Вход: R0 - адрес спрайта в памяти, первые 2 слова высота в строках и ширина в байтах
                                        ;       R1 - адрес экрана
                mov     R2, @#NBoxScrAddr
                return
; ───────────────────────────────────────────────────────────────────────────

8$:             mov     #11, @#NBoxDelay
                mov     #BoxTrckOffsets, @#NBoxTrack
                br      6$
; End of function NBoxAnim

; ───────────────────────────────────────────────────────────────────────────
SoundNBoxCatch: .word 10
                .word 40
                .word 100
                .word 400
                .word 0

; ███████████████ S U B R O U T I N E ███████████████████████████████████████

; Проверка поймал ли игрок коробку с N
; и если да - то увеличение чего-то

NBoxCatch:      mov     #1, @#TmpStructPlayer+6
                mov     @#PlayerScrAddr, @#TmpStructPlayer ; Адрес спрайта игрока
                mov     #1, @#TmpStructBox+6
                mov     @#NBoxScrAddr, @#TmpStructBox
                mov     #TmpStructBox, R5
                mov     #TmpStructPlayer, R4
                mov     #sprNBox, R3
                mov     @#CurSprPlayer, R0 ; Адрес текущего спрайта игрока
                trap    54              ; Проверка на коллизию.
                                        ; Вход: R0 - адрес спрайта объекта 2
                                        ;       R3 - адрес спрайта объекта 1
                                        ;       R4 - структура объекта 2
                                        ;       R5 - структура объекта 1
                                        ; Формат структуры см в другом месте
                nop
                nop
                nop
                nop
                tst     @#TmpStructBox+6
                beq     2$

1$:             return
; ───────────────────────────────────────────────────────────────────────────

2$:             tst     @#TmpStructPlayer+6
                bne     1$
                inc     @#NShooting     ; Количество выстреливаемых очередей
                mov     #SoundNBoxCatch, R1
                trap    14
                clr     @#NBoxScrAddr
                return
; End of function NBoxCatch

; ───────────────────────────────────────────────────────────────────────────
sprForceBox:    .word 13, 3
                .byte 125, 125, 5
                .byte 167, 167, 127
                .byte 335, 335, 125
                .byte 167, 125, 127
                .byte 135, 325, 125
                .byte 167, 25, 0
                .byte 335, 135, 1
                .byte 167, 127, 1
                .byte 135, 5, 0
                .byte 167, 5, 0
                .byte 135, 5, 0
                .byte 0
                .word 0
ForceBoxScrAddr:.word 0
ForceBoxDelay:  .word 5
ForceBoxTrack:  .word BoxTrckOffsets
                .word 0

; ███████████████ S U B R O U T I N E ███████████████████████████████████████

; Вывод и анимация ящика F

ForceBoxAnim:   cmp     #1, @#ShootSpeed+2 ; стрельба максимально ускорена?
                bne     1$              ; нет ещё, можно значит
                return                  ; да - ничего не делаем
; ───────────────────────────────────────────────────────────────────────────

1$:             tst     (PC)+
ForceBoxCnt:    .word 161
                bne     3$
                mov     #333, @#ForceBoxCnt
                mov     #ForceBoxScrAddr, R5
                tst     (R5)
                beq     2$
                return
; ───────────────────────────────────────────────────────────────────────────

2$:             mov     @#177710, R4
                bic     #77, R4
                add     #42002, R4
                mov     R4, (R5)+
                nop
                nop
                nop
                nop

3$:             dec     @#ForceBoxCnt
                mov     #ForceBoxScrAddr, R5
                mov     (R5)+, R1
                bne     4$
                return
; ───────────────────────────────────────────────────────────────────────────

4$:             mov     #sprForceBox, R0
                trap    40              ; Стирание спрайта с экрана методом побитовой очистки
                                        ; Вход: R0 - адрес спрайта в памяти, первые 2 слова высота в строках и ширина в байтах
                                        ;       R1 - адрес экрана
                dec     (R5)+
                bne     6$

5$:             mov     (R5), R4
                add     #2, R4
                mov     (R4)+, R3
                mov     R4, (R5)
                cmp     #BoxTrckOffsetsEnd+2, R4 ; Вывод и анимация ящика с жизнью
                ble     8$
                mov     R3, -(R5)
                tst     (R5)+

6$:             mov     R1, R2
                add     @(R5)+, R2
                mov     -(R5), R4
                cmp     #42300, R2
                bpl     5$
                cmp     #76000, R2
                bmi     5$
                bit     #76, R2
                beq     5$
                add     #3, R2
                bit     #76, R2
                bne     7$
                clr     @#ForceBoxScrAddr
                return
; ───────────────────────────────────────────────────────────────────────────

7$:             sub     #3, R2
                mov     R2, R1
                trap    36              ; Вывод спрайта на экран методом наложения
                                        ; Вход: R0 - адрес спрайта в памяти, первые 2 слова высота в строках и ширина в байтах
                                        ;       R1 - адрес экрана
                mov     R2, @#ForceBoxScrAddr
                return
; ───────────────────────────────────────────────────────────────────────────

8$:             mov     #11, @#ForceBoxDelay
                mov     #BoxTrckOffsets, @#ForceBoxTrack
                br      6$
; End of function ForceBoxAnim

; ───────────────────────────────────────────────────────────────────────────
SoundFBoxCatch:       .word 10
                .word 400
                .word 100
                .word 400
                .word 0

; ███████████████ S U B R O U T I N E ███████████████████████████████████████

; Проверка поймал ли игрок коробку с F
; и если да - то уменьшение задержки стрельбы

FBoxCatch:      mov     #1, @#TmpStructPlayer+6
                mov     @#PlayerScrAddr, @#TmpStructPlayer ; Адрес спрайта игрока
                mov     #1, @#TmpStructBox+6
                mov     @#ForceBoxScrAddr, @#TmpStructBox
                mov     #TmpStructBox, R5
                mov     #TmpStructPlayer, R4
                mov     #sprForceBox, R3
                mov     @#CurSprPlayer, R0 ; Адрес текущего спрайта игрока
                trap    54              ; Проверка на коллизию.
                                        ; Вход: R0 - адрес спрайта объекта 2
                                        ;       R3 - адрес спрайта объекта 1
                                        ;       R4 - структура объекта 2
                                        ;       R5 - структура объекта 1
                                        ; Формат структуры см в другом месте
                nop
                nop
                nop
                nop
                tst     @#TmpStructBox+6
                beq     2$

1$:             return
; ───────────────────────────────────────────────────────────────────────────

2$:             tst     @#TmpStructPlayer+6
                bne     1$
                dec     @#ShootSpeed+2  ; Ускорение стрельбы (меньше - быстрее)
                mov     #SoundFBoxCatch, R1
                trap    14
                clr     @#ForceBoxScrAddr
                return
; End of function FBoxCatch

; ───────────────────────────────────────────────────────────────────────────
sprRoger:       .word 26, 4
                .byte 0, 120, 5, 0
                .byte 0, 164, 35, 0
                .byte 0, 164, 35, 0
                .byte 0, 20, 4, 0
                .byte 104, 100, 1, 21
                .byte 125, 21, 104, 125
                .byte 121, 101, 101, 125
                .byte 124, 1, 100, 25
                .byte 120, 1, 100, 5
                .byte 100, 5, 120, 1
                .byte 0, 25, 124, 0
                .byte 0, 124, 20, 0
                .byte 0, 120, 1, 0
                .byte 0, 100, 5, 0
                .byte 0, 4, 25, 0
                .byte 0, 25, 124, 0
                .byte 100, 5, 120, 1
                .byte 120, 1, 100, 5
                .byte 124, 1, 100, 25
                .byte 121, 1, 100, 125
                .byte 125, 1, 100, 125
                .byte 104, 0, 0, 21
RogerScrAddr:   .word 0                 ; Экранный адрес черепа с костями
RogerOffset:    .word 0                 ; Приращение экранного адреса черепа с костями

; ███████████████ S U B R O U T I N E ███████████████████████████████████████


RogerAnim:      tst     (PC)+
RogerCnt:       .word 201
                bne     3$
                tst     @#RogerScrAddr  ; Экранный адрес черепа с костями
                bne     4$
                mov     #244, @#RogerCnt
                mov     @#177710, R4
                bic     #7777, R4
                cmp     #sprPlayerRt, @#CurSprPlayer ; Адрес текущего спрайта игрока
                beq     1$
                add     #42201, R4
                br      2$
; ───────────────────────────────────────────────────────────────────────────

1$:             add     #42273, R4

2$:             mov     R4, @#RogerScrAddr ; Экранный адрес черепа с костями

3$:             dec     @#RogerCnt

4$:             mov     #sprRoger, R0
                mov     @#RogerScrAddr, R1 ; Экранный адрес черепа с костями
                bne     5$
                return
; ───────────────────────────────────────────────────────────────────────────

5$:             cmp     #sprPlayerRt, @#CurSprPlayer ; Адрес текущего спрайта игрока
                beq     6$
                mov     #1, R2
                br      7$
; ───────────────────────────────────────────────────────────────────────────

6$:             mov     #-1, R2

7$:             add     @#RogerOffset, R2 ; Приращение экранного адреса черепа с костями
                add     R1, R2
                trap    40              ; Стирание спрайта с экрана методом побитовой очистки
                                        ; Вход: R0 - адрес спрайта в памяти, первые 2 слова высота в строках и ширина в байтах
                                        ;       R1 - адрес экрана
                cmp     #74000, R2
                bmi     11$
                bit     #77, R2
                bne     8$
; End of function RogerAnim


; ███████████████ S U B R O U T I N E ███████████████████████████████████████


InitRoger:                              ; CODE XREF: ROM:013446P
                                        ; RogerAnim+170j
                clr     @#RogerScrAddr  ; Экранный адрес черепа с костями
                clr     @#RogerOffset   ; Приращение экранного адреса черепа с костями
                return
; End of function InitRoger

; ───────────────────────────────────────────────────────────────────────────

8$:             add     #4, R2
                bit     #77, R2
                beq     InitRoger
                sub     #4, R2
                mov     R2, R1
                trap    36              ; Вывод спрайта на экран методом наложения
                                        ; Вход: R0 - адрес спрайта в памяти, первые 2 слова высота в строках и ширина в байтах
                                        ;       R1 - адрес экрана
                mov     R1, @#RogerScrAddr ; Экранный адрес черепа с костями
                mov     #1, @#word_33364
                mov     @#RogerScrAddr, @#word_33356 ; Экранный адрес черепа с костями
                mov     #word_33356, R5
                mov     #sprRoger, R3
                tst     @#RogerOffset   ; Приращение экранного адреса черепа с костями
                bne     9$
                trap    56              ; Проверка попаданиями пулек игрока в объект
                                        ; Вход: R3 - спрайт объекта
                                        ;       R5 - структура объекта

9$:             nop
                tst     @#word_33364
                beq     10$
                return
; ───────────────────────────────────────────────────────────────────────────

10$:            mov     #400, @#RogerOffset ; Приращение экранного адреса черепа с костями
                mov     #5, @#0RogerCnt$
                nop
                nop
                return
; ───────────────────────────────────────────────────────────────────────────

11$:            bic     #77000, R1
                bis     #74000, R1
                clr     @#RogerOffset   ; Приращение экранного адреса черепа с костями
                mov     R1, @#RogerScrAddr ; Экранный адрес черепа с костями
                sub     #1500, R1
                bit     #1, @#0RogerCnt$
                beq     12$
                mov     #sprCloud1, R0
                br      13$
; ───────────────────────────────────────────────────────────────────────────

12$:            mov     #sprCloud2, R0

13$:            mov     #3, R3

14$:            trap    40              ; Стирание спрайта с экрана методом побитовой очистки
                                        ; Вход: R0 - адрес спрайта в памяти, первые 2 слова высота в строках и ширина в байтах
                                        ;       R1 - адрес экрана
                add     #1300, R1
                sob     R3, 14$
                tst     (PC)+
0RogerCnt$:     .word 0
                beq     18$
                mov     #LastItemPlrsBlltBuf, R5
                clr     (R5)+
                mov     (R5), @#102
                mov     #42310, (R5)+
                mov     #BlockWall2Anim, (R5)+
                mov     #100, (R5)+
                mov     #-1, (R5)+
                clr     (R5)+
                dec     @#0RogerCnt$
                bit     #1, @#0RogerCnt$
                beq     15$
                mov     #sprCloud1, R0
                br      16$
; ───────────────────────────────────────────────────────────────────────────

15$:            mov     #sprCloud2, R0

16$:            mov     #3, R3
                sub     #4100, R1

17$:            trap    36              ; Вывод спрайта на экран методом наложения
                                        ; Вход: R0 - адрес спрайта в памяти, первые 2 слова высота в строках и ширина в байтах
                                        ;       R1 - адрес экрана
                add     #1300, R1
                sob     R3, 17$
                mov     #Sound13$, R1
                trap    14
                return
; ───────────────────────────────────────────────────────────────────────────

18$:            clr     @#RogerScrAddr  ; Экранный адрес черепа с костями
                mov     #LastItemPlrsBlltBuf, R5
                mov     #5, R4

19$:            clr     (R5)+
                sob     R4, 19$
                mov     @#102, R1
                beq     20$
                mov     #sprBulletLt, R0
                trap    42              ; Стирание спрайта с экрана clrом
                                        ; Вход: R0 - адрес спрайта в памяти, первые 2 слова высота в строках и ширина в байтах
                                        ;       R1 - адрес экрана
20$:            return
; End of function RogerAnim

; ───────────────────────────────────────────────────────────────────────────
word_33356:     .word 52201
                .word 002600
                .word 4
word_33364:     .word 1
                .word 0

Sound13$:       .word 2
                .word 1000
                .word 100
                .word 0
sprUFO1:        .word 7, 3
                .byte 0, 250, 52
                .byte 0, 212, 210
                .byte 0, 252, 252
                .byte 374, 377, 77
                .byte 252, 252, 0
                .byte 42, 242, 0
                .byte 250, 52, 0
                .byte 0
sprUFO2:        .word 7, 3
                .byte 250, 52, 0
                .byte 42, 242, 0
                .byte 252, 252, 0
                .byte 374, 377, 77
                .byte 0, 252, 252
                .byte 0, 212, 210
                .byte 0, 250, 52
                .byte 0
SprUFOSize = sprUFO2 - sprUFO1

                .word 0
                .word 0
                .word 700
                .word 3
                .word 402
                .word 0

; ███████████████ S U B R O U T I N E ███████████████████████████████████████


UfoAnim:        tst     (PC)+
NewUFOCnt:     .word 57
                bne     5$
                mov     #101, @#NewUFOCnt
                mov     #<EnemyBulletBuffer+2>, R5
                mov     #EnemyBulletBufferItemsNum, R4

1$:             tst     (R5)
                beq     2$
                add     #EnemyBulletBufferItemSize, R5
                sob     R4, 1$
                br      5$
; ───────────────────────────────────────────────────────────────────────────

2$:             tst     -(R5)
                mov     #sprUFO1, (R5)+
                mov     @#177710, R4
                bic     #77, R4
                cmp     #sprPlayerRt, @#CurSprPlayer ; Адрес текущего спрайта игрока
                beq     3$
                add     #42201, R4
                mov     #1, R3
                br      4$
; ───────────────────────────────────────────────────────────────────────────

3$:             mov     #-1, R3
                add     #42274, R4

4$:             mov     R4, (R5)+
                mov     R3, (R5)+
                mov     #700, (R5)+
                mov     #3, (R5)+
                mov     #400, (R5)+
                clr     (R5)+

5$:             dec     @#NewUFOCnt
                mov     #EnemyBulletBuffer, R5
                mov     #EnemyBulletBufferItemsNum, R4

6$:             cmp     #sprUFO1, (R5)
                beq     8$
                cmp     #sprUFO2, (R5)
                beq     8$

7$:             add     #EnemyBulletBufferItemSize, R5
                sob     R4, 6$
                br      16$
; ───────────────────────────────────────────────────────────────────────────

8$:             tstb    13(R5)
                beq     17$
                mov     (R5)+, R0
                mov     (R5)+, R1
                beq     15$
                cmp     #sprPlayerRt, @#CurSprPlayer ; Адрес текущего спрайта игрока
                beq     9$
                mov     #1, R2
                br      10$
; ───────────────────────────────────────────────────────────────────────────

9$:             mov     #-1, R2

10$:            add     (R5), R2
                add     R1, R2
                trap    40              ; Стирание спрайта с экрана методом побитовой очистки
                                        ; Вход: R0 - адрес спрайта в памяти, первые 2 слова высота в строках и ширина в байтах
                                        ;       R1 - адрес экрана
                bit     #76, R2
                bne     12$

11$:            clr     -(R5)
                clr     -(R5)
                br      7$
; ───────────────────────────────────────────────────────────────────────────

12$:            add     #3, R2
                bit     #76, R2
                beq     11$
                sub     #3, R2
                cmp     #sprUFO2, R0
                bne     13$
                mov     #sprUFO1, R0
                br      14$
; ───────────────────────────────────────────────────────────────────────────

13$:            add     #SprUFOSize, R0

14$:            mov     R2, R1
                trap    36              ; Вывод спрайта на экран методом наложения
                                        ; Вход: R0 - адрес спрайта в памяти, первые 2 слова высота в строках и ширина в байтах
                                        ;       R1 - адрес экрана

15$:            mov     R1, -(R5)
                mov     R0, -(R5)
                br      7$
; ───────────────────────────────────────────────────────────────────────────

16$:            return
; ───────────────────────────────────────────────────────────────────────────

17$:            clr     (R5)+
                mov     (R5), R1
                clr     (R5)
                clr     -(R5)
                mov     R5, -(SP)
                mov     R4, -(SP)
                mov     R1, -(SP)
                mov     #Sound14$, R1
                trap    14
                mov     (SP)+, R1
                mov     #UFOScratchTbl, R3
                mov     #<EnemyBulletBuffer+2>, R5
                mov     #EnemyBulletBufferItemsNum, R4

18$:            tst     (R5)
                beq     21$
                add     #EnemyBulletBufferItemSize, R5

19$:            sob     R4, 18$

20$:            mov     (SP)+, R4
                mov     (SP)+, R5
                br      7$
; ───────────────────────────────────────────────────────────────────────────

21$:            mov     (R3)+, R2
                beq     20$
                tst     -(R5)
                mov     #sprBallBullet, (R5)+
                mov     R1, (R5)+
                mov     R2, (R5)+
                mov     #500, (R5)+
                mov     #2, (R5)+
                mov     #1, (R5)+
                clr     (R5)+
                tst     (R5)+
                br      19$
; End of function UfoAnim

; ───────────────────────────────────────────────────────────────────────────
UFOScratchTbl:  .word -400
                .word -202
                .word -176
                .word -301
                .word -277
                .word 0
Sound14$:       .word 2
                .word 400
                .word 1000
                .word 2000
                .word 1000
                .word 37
                .word 0

; ███████████████ S U B R O U T I N E ███████████████████████████████████████

; Уменьшаем игровую задержку

GameSpeedup:    sub     #500, @#2
                bpl     1$
                mov     #1, @#2

1$:             return
; End of function GameSpeedup

; ───────────────────────────────────────────────────────────────────────────
; Массив из 34 элементов по 2 слова на элемент
; буфер блоков
BlockBufItemsNum = 34
BlockBufItemSize = 4
BlockBuf:       .word 0, 0
                .word 0, 1
                .word 0, 10
                .word 0, 13
                .word 0, 13
                .word 0, 13
                .word 0, 13
                .word 0, 13
                .word 0, 13
                .word 0, 13
                .word 0, 13
                .word 0, 13
                .word 0, 13
                .word 0, 13
                .word 0, 13
                .word 0, 13
                .word 0, 13
                .word 0, 13
                .word 0, 13
                .word 0, 13
                .word 0, 13
                .word 0, 13
                .word 0, 13
                .word 0, 13
                .word 0, 13
                .word 0, 13
                .word 0, 13
                .word 0, 13

sprBlockB:      .word 15, 3
                .byte 125, 125, 125
                .byte 125, 125, 125
                .byte 5, 0, 120
                .byte 365, 377, 123
                .byte 65, 125, 125
                .byte 65, 0, 124
                .byte 365, 377, 120
                .byte 65, 125, 123
                .byte 65, 125, 123
                .byte 65, 0, 123
                .byte 365, 377, 124
                .byte 125, 125, 125
                .byte 125, 125, 125
                .byte 0
sprBlockO:      .word 15, 3
                .byte 374, 377, 77
                .byte 137, 125, 365
                .byte 127, 377, 325
                .byte 327, 377, 327
                .byte 367, 377, 337
                .byte 367, 327, 337
                .byte 367, 101, 337
                .byte 367, 327, 337
                .byte 367, 377, 337
                .byte 327, 377, 327
                .byte 127, 377, 325
                .byte 137, 125, 365
                .byte 374, 377, 77
                .byte 0

; ███████████████ S U B R O U T I N E ███████████████████████████████████████


BlockWallAnim:  tst     (PC)+
BlockWallCnt:   .word 146
                bne     7$
                mov     #207, @#BlockWallCnt
                mov     @#177710, R4
                bic     #177774, R4
                beq     BlockWallAnim
                mov     #BlockBuf, R5
                mov     @#177710, R3
                bic     #77, R3
                sub     #6000, R3
                bpl     1$
                clr     R3

1$:             add     #42200, R3
                cmp     #sprPlayerRt, @#CurSprPlayer ; Адрес текущего спрайта игрока
                beq     2$
                add     #1, R3
                mov     #1, @#12
                br      3$
; ───────────────────────────────────────────────────────────────────────────

2$:             add     #74, R3
                mov     #-1, @#12

3$:             mov     #24, R2

4$:             tst     (R5)+
                beq     6$

5$:             tst     (R5)+
                sob     R2, 4$
                br      7$
; ───────────────────────────────────────────────────────────────────────────

6$:             tst     (R5)
                beq     5$
                mov     R3, -(R5)
                add     #1500, R3
                sob     R4, 4$

7$:             dec     @#BlockWallCnt
                mov     #BlockBuf, R5
                mov     #24, R4
                mov     #sprBlockO, R0

8$:             mov     (R5)+, R1
                beq     12$
                tst     (R5)
                beq     9$
                trap    40              ; Стирание спрайта с экрана методом побитовой очистки
                                        ; Вход: R0 - адрес спрайта в памяти, первые 2 слова высота в строках и ширина в байтах
                                        ;       R1 - адрес экрана
                add     @#12, R1
                bit     #76, R1
                bne     10$

9$:             clr     -(R5)
                br      11$
; ───────────────────────────────────────────────────────────────────────────

10$:            add     #3, R1
                bit     #76, R1
                beq     9$
                sub     #3, R1
                trap    36              ; Вывод спрайта на экран методом наложения
                                        ; Вход: R0 - адрес спрайта в памяти, первые 2 слова высота в строках и ширина в байтах
                                        ;       R1 - адрес экрана
                mov     R1, -(R5)

11$:            tst     (R5)+

12$:            tst     (R5)+
                sob     R4, 8$
                return
; End of function BlockWallAnim


; ███████████████ S U B R O U T I N E ███████████████████████████████████████


BlockWall2Anim: mov     #BlockBuf, R2
                mov     #BlockBufItemsNum, R1

bw2.1$:         tst     (R2)
                bne     3$
                add     #BlockBufItemSize, R2

bw2.2$:         sob     R1, bw2.1$
                return
; ───────────────────────────────────────────────────────────────────────────

3$:             mov     #TmpBlockStruct, R5
                mov     (R2)+, (R5)+
                add     #4, R5
                mov     (R2), (R5)+
                mov     #TmpBlockStruct, R5
                mov     #sprBlockO, R3
                trap    56              ; Проверка попаданиями пулек игрока в объект
                                        ; Вход: R3 - спрайт объекта
                                        ;       R5 - структура объекта
                call    @#sub_36250
                tst     (PC)+
BlkShootCnt:     .word 10
                beq     4$
                dec     @#BlkShootCnt
                br      bw2.2$
; ───────────────────────────────────────────────────────────────────────────

4$:             mov     #20, @#BlkShootCnt
                mov     #EnemyBulletBuffer, R5
                mov     #EnemyBulletBufferItemsNum, R4

5$:             tst     2(R5)
                beq     6$
                add     #EnemyBulletBufferItemSize, R5
                sob     R4, 5$
                br      bw2.2$
; ───────────────────────────────────────────────────────────────────────────

6$:             mov     -4(R2), R0
                mov     @#PlayerScrAddr, R3 ; Адрес спрайта игрока
                trap    66
                mov     #sprBallBullet, (R5)+
                call    @#sub_36200
                mov     #500, (R5)+
                mov     #2, (R5)+
                mov     #1, (R5)+
                clr     (R5)+
                br      bw2.2$
; End of function BlockWall2Anim

; ───────────────────────────────────────────────────────────────────────────
                .word 0
                .word 0
                .word 0
                .word 0

; ███████████████ S U B R O U T I N E ███████████████████████████████████████


Trap66:         mov     #Sound8$, R1
                trap    14
                mov     R0, R1
                mov     R3, R2
                bic     #177700, R0
                bic     #177700, R3
                sub     R0, R3
                bic     #77, R1
                bic     #77, R2
                sub     R1, R2
                bpl     1$
                neg     R2
                call    @#sub_35266
                neg     R2
                br      2$
; ───────────────────────────────────────────────────────────────────────────

1$:             call    @#sub_35266

2$:             add     R3, R2
                mov     R2, 6(SP)
                return
; End of function Trap66


; ███████████████ S U B R O U T I N E ███████████████████████████████████████


sub_35266:      mov     R3, R5
                bpl     1$
                neg     R5

1$:             asr     R5
                beq     3$

2$:             asr     R2
                asr     R5
                bne     2$

3$:             bic     #77, R2
                tst     R3
                bpl     4$
                mov     #-2, R3
                br      5$
; ───────────────────────────────────────────────────────────────────────────

4$:             mov     #2, R3

5$:             return
; End of function sub_35266


; ███████████████ S U B R O U T I N E ███████████████████████████████████████


BlockWall3Anim: tst     (PC)+
BlockBOutCnt:   .word 1167
                beq     8$
                cmp     #sprPlayerRt, @#CurSprPlayer ; Адрес текущего спрайта игрока
                beq     1$
                dec     @#BlockBOutCnt
                beq     2$

1$:             return
; ───────────────────────────────────────────────────────────────────────────

2$:             mov     #<BlockBuf+120>, R5
                mov     #55500, R1
                mov     #3, R2

3$:             mov     #3, R3

4$:             cmp     #2, R2
                bne     5$
                cmp     #2, R3
                beq     7$

5$:             mov     R1, (R5)+
                tst     (R5)
                bne     6$
                clr     -(R5)
                tst     (R5)+

6$:             tst     (R5)+

7$:             add     #3, R1
                sob     R3, 4$
                add     #1467, R1
                sob     R2, 3$
                mov     #57203, @#100

8$:             clr     R3
                cmp     #sprPlayerRt, @#CurSprPlayer ; Адрес текущего спрайта игрока
                beq     9$
                mov     #2, R3

9$:             mov     #<BlockBuf+120>, R5
                mov     #10, R4
                mov     #sprBlockO, R0

10$:            mov     (R5), R1
                beq     11$
                trap    40              ; Стирание спрайта с экрана методом побитовой очистки
                                        ; Вход: R0 - адрес спрайта в памяти, первые 2 слова высота в строках и ширина в байтах
                                        ;       R1 - адрес экрана
                add     R3, (R5)

11$:            tst     (R5)+
                tst     (R5)+
                sob     R4, 10$
                mov     @#100, R1
                beq     14$
                mov     #sprBlockB, R0
                trap    40              ; Стирание спрайта с экрана методом побитовой очистки
                                        ; Вход: R0 - адрес спрайта в памяти, первые 2 слова высота в строках и ширина в байтах
                                        ;       R1 - адрес экрана
                add     R3, R1
                add     #6, R1
                bit     #76, R1
                bne     13$
                mov     #<BlockBuf+120>, R5
                mov     #10, R4

12$:            clr     (R5)+
                tst     (R5)+
                sob     R4, 12$
                mov     #2000, @#BlockBOutCnt
                return
; ───────────────────────────────────────────────────────────────────────────

13$:            sub     #6, R1
                mov     R1, @#100
                trap    36              ; Вывод спрайта на экран методом наложения
                                        ; Вход: R0 - адрес спрайта в памяти, первые 2 слова высота в строках и ширина в байтах
                                        ;       R1 - адрес экрана

14$:            mov     #sprBlockO, R0
                mov     #<BlockBuf+120>, R5
                mov     #10, R4

15$:            mov     (R5)+, R1
                beq     17$
                tst     (R5)
                bne     16$
                clr     -2(R5)
                br      17$
; ───────────────────────────────────────────────────────────────────────────

16$:            trap    36              ; Вывод спрайта на экран методом наложения
                                        ; Вход: R0 - адрес спрайта в памяти, первые 2 слова высота в строках и ширина в байтах
                                        ;       R1 - адрес экрана

17$:            tst     (R5)+
                sob     R4, 15$
                mov     #1, @#2
                return
; End of function BlockWall3Anim

; ───────────────────────────────────────────────────────────────────────────

PlayerDead:     mov     #30, R0

1$:             mov     #Sound14$, R1
                trap    14
                mov     R0, -(SP)
                call    @#FragScratchAnim ; Обработка разлёта осколков от объектов при попадании
                mov     (SP)+, R0
                sob     R0, 1$

2$:             bit     #100, @#177716
                beq     3$
                tst     @#177714
                beq     2$

3$:             jmp     @#RestartGame

; ███████████████ S U B R O U T I N E ███████████████████████████████████████

; Снятие ачивок при попадании в игрока

AchievesDown:   cmp     #3, @#ShootSpeed+2 ; скорость стрельбы и так минимальная?
                beq     1$              ; да
                inc     @#ShootSpeed+2  ; нет - уменьшаем

1$:             cmp     #1, @#MoveSpeed ; скорость передвижения и так минимальная?
                beq     2$              ; нет
                dec     @#MoveSpeed     ; да - уменьшаем
                nop

2$:             tst     @#NShooting     ; количество очередей одна?
                beq     3$              ; да
                dec     @#NShooting     ; нет - уменьшаем

3$:             return
; End of function AchievesDown


; ███████████████ S U B R O U T I N E ███████████████████████████████████████

; Проверка, есть ли блок Б и если есть, то добавление
; охранника, если нет - проверка на конец игры

CheckBlockB:    mov     @#100, R1       ; охранников генерировать?
                beq     5$              ; нет, больше не надо
                mov     #<BlockBuf+122>, R5
                mov     #8., R4         ; проверим, есть ли вокруг блока Б защитные блоки

1$:             tst     (R5)+
                bne     2$              ; есть ещё, значит можно добавлять охранников
                tst     (R5)+
                sob     R4, 1$
                mov     #sprBlockB, R0  ; кончились - всё, уничтожаем блок Б
                trap    40              ; Стирание спрайта с экрана методом побитовой очистки
                                        ; Вход: R0 - адрес спрайта в памяти, первые 2 слова высота в строках и ширина в байтах
                                        ;       R1 - адрес экрана
                call    @#sub_36140     ; Барак, генератор охранников уничтожен

2$:             tst     (PC)+           ; Нового охранника добавлять?
AddNewGuardCnt: .word 21
                beq     3$              ; пора
                dec     @#AddNewGuardCnt ; нет ещё
                return
; ───────────────────────────────────────────────────────────────────────────

3$:             mov     #140, @#AddNewGuardCnt ; добавим нового охранника
                mov     #Guard, R5
                mov     #EndGuard, R0
                cmp     #4411, (R5)     ; их и так максимум?
                beq     4$              ; да - выходим
                call    @#IncreaseValue ; Увеличение двоично-десятичного числа
                                        ; Вход: R0 - конец числа
                mov     #41062, R1
                trap    60              ; Вывод числовых значений счёта, жизней и т.п.
                                        ; Вход: R5 - адрес данных
                                        ;       R1 - адрес экрана
4$:             return
; ───────────────────────────────────────────────────────────────────────────

5$:             mov     #2000, @#BlockBOutCnt
                tst     @#Guard         ; охранники ещё остались?
                bne     4$              ; да - выходим
                tst     @#Guard+2
                bne     4$
                jmp     @#FinalGame     ; нет - конец игры
; End of function CheckBlockB


; ███████████████ S U B R O U T I N E ███████████████████████████████████████

; Барак, генератор охранников уничтожен

sub_36140:      clr     @#100
                mov     #Sound15$, R1
                trap    14
                trap    14
                return
; End of function sub_36140

; ───────────────────────────────────────────────────────────────────────────
Sound15$:       .word 10
                .word 100
                .word 400
                .word 1000
                .word 2000
                .word 1000
                .word 400
                .word 100
                .word 0

; ███████████████ S U B R O U T I N E ███████████████████████████████████████


sub_36200:      tst     R3
                bpl     1$
                neg     R3
                call    sub_36230
                neg     R3
                br      2$
; ───────────────────────────────────────────────────────────────────────────

1$:             call    sub_36230

2$:             mov     R0, (R5)+
                mov     R3, (R5)+
                return
; End of function sub_36200


; ███████████████ S U B R O U T I N E ███████████████████████████████████████


sub_36230:      cmp     #700, R3
                bpl     1$
                bic     #177700, R3
                bis     #700, R3

1$:             return
; End of function sub_36230


; ███████████████ S U B R O U T I N E ███████████████████████████████████████


sub_36250:      mov     @#TmpBlockStruct+6, (R2)+
                bne     1$
                mov     R1, -(SP)
                mov     #Sound16$, R1
                trap    14
                mov     (SP)+, R1

1$:             return
; End of function sub_36250

; ───────────────────────────────────────────────────────────────────────────
Sound16$:       .word 12
                .word 2000
                .word 0
; это битовый массив "GAME OVER"
datGAMEOVER:    .word ^B1111111101111111
                .word ^B0000000000000000
                .word ^B0000000000000000
                .word ^B0000000000000000
                .word ^B1101000100100110
                .word ^B0101101101010001
                .word ^B0101010101010001
                .word ^B1101010101010001
                .word ^B0101010101110101
                .word ^B0101010101010101
                .word ^B1101000101010110
                .word ^B0000000000000000
                .word ^B0000000000000000
                .word ^B0000000000000000
                .word ^B0111011101010010
                .word ^B1001000101010101
                .word ^B1001000101010101
                .word ^B1001011101010101
                .word ^B0111000101010101
                .word ^B1001000101010101
                .word ^B1001011100100010
                .word ^B0000000000000000
                .word ^B0000000000000000
                .word ^B0000000000000000
                .word ^B1111111101111111
; это битовый массив "Вход в шахту"
datShachta:     .word ^B0000011001100000
                .word ^B0000011001100000
                .word ^B0000011001100000
                .word ^B0000011001100000
                .word ^B0000011001100000
                .word ^B0000011001100000
                .word ^B0000011001100000
                .word ^B0000011001100000
                .word ^B1111111001111111
                .word ^B1111111001111111
                .word ^B0111111001111110
                .word ^B0111111001111110
                .word ^B0011111001111100
                .word ^B0011111001111100
                .word ^B0001111001111000
                .word ^B0001111001111000
                .word ^B0000111001110000
                .word ^B0000111001110000
                .word ^B0000011001100000
                .word ^B0000011001100000
                .word ^B0000001001000000
                .word ^B0000001001000000
                .word ^B0000001001000000
                .word ^B0000001001000000
                .word ^B0000001001000000
; это спрайт стены
sprWall:        .word 156735, 156535
                .word  73567, 73567
                .word 156735, 156535
                .word  73567, 73567
                .word  52525, 52525
                .word  73567, 73567
                .word 156535, 156735
                .word  73567, 73567
                .word 156535, 156735
                .word  52525, 52525
sprWallEnd:
; ───────────────────────────────────────────────────────────────────────────

NextFinal1$:    mov     #Trap50_2, @#off_Trp50s ; глушим опросы клавиатуры и джойстика
                mov     #Trap50_2, @#off_Trp52s
                mov     #datGAMEOVER, R0

1$:             mov     #40000, R1
                mov     R0, <0Offset$>
                add     #datShachta-datGAMEOVER, <0Offset$>

2$:             mov     #sprWall, R3

3$:             inc     @#177664
                mov     #20, R2
                mov     (R0), R5

4$:             ror     R5
                bcc     5$
                mov     (R3)+, (R1)+
                mov     (R3), (R1)+
                mov     -(R3), R4
                br      6$
; ───────────────────────────────────────────────────────────────────────────

5$:             clr     (R1)+
                clr     (R1)+

6$:             sob     R2, 4$
                add     #4, R3
                mov     #2000, R4
                sob     R4, .

                cmp     #sprWallEnd, R3
                bne     3$
                mov     (R0)+, R5
                cmp     (PC)+, R0
0Offset$:       .word sprWall
                bne     2$
                mov     #300, R5

7$:             clr     (R1)+
                sob     R5, 7$
                add     #6, @#177664
                cmp     #datShachta, R0
                bne     8$
                mov     #42234, @#PlayerScrAddr ; Адрес спрайта игрока
                br      9$
; ───────────────────────────────────────────────────────────────────────────

8$:             mov     #40036, @#PlayerScrAddr ; Адрес спрайта игрока

9$:             mov     R0, -(SP)

10$:            mov     #100, @#GrowPlayerAddr ; Приращение адреса игрока
                call    @#PlayerAnim    ; Обработка и анимация движения игрока
                                        ; Обработка стрельбы, заполнение массива выстреленных пуль.
                mov     #14000, R5
                sob     R5, .

                cmp     #74300, R1
                bpl     10$
                mov     (SP)+, R0
                mov     #Sound17$, R1
                trap    14
                cmp     #sprWall, R0
                bne     1$
                br      NextFinal2$
; ───────────────────────────────────────────────────────────────────────────
Sound17$:       .word 20
                .word 2000
                .word 1000
                .word 400
                .word 200
                .word 100
                .word 400
                .word 200
                .word 1000
                .word 0
; ───────────────────────────────────────────────────────────────────────────
NextFinal2$:    mov     #NextFinal3$, -(SP)
                mov     #addrText5$, R5
                mov     #datText5$, R2


; ███████████████ S U B R O U T I N E ███████████████████████████████████████


sub_37014:      mov     #134000, @#44
                trap    70              ; Очистка экрана
; End of function sub_37014


; ███████████████ S U B R O U T I N E ███████████████████████████████████████


sub_37024:      clr     @#46

1$:             mov     (R5)+, R1
                beq     3$
                trap    22              ; Вывод текста буквами тырк-тырк влево-вправо
                                        ; Вход: R1 - адрес экрана
                                        ;       R2 - адрес текста
                                        ;       @#44 - маска цвета для 1 бита символа
                                        ;       @#46 - масштаб по высоте
2$:             tstb    (R2)+
                bne     2$
                br      1$
; ───────────────────────────────────────────────────────────────────────────

3$:             trap    24              ; Вывод три зелёных полосы и на них копирайт спрайтами
                trap    72              ; Ждать нажатия чего-нибудь
                return
; End of function sub_37024

; ───────────────────────────────────────────────────────────────────────────

NextFinal3$:    trap    70              ; Очистка экрана
                mov     #60010, R1
                mov     #datText7$, @#46
                trap    6               ; Вывод текста сложного формата на экран
                                        ; Вход: R1 - адрес экрана
                                        ;       @#46 - адрес массива данных
                mov     #AddrText8$, R5
                mov     #datText8$, R2
                mov     #114000, @#44
                call    @#sub_37024
                trap    70              ; Очистка экрана
                mov     #60010, R1
                mov     #datText2$, @#46
                trap    6               ; Вывод текста сложного формата на экран
                                        ; Вход: R1 - адрес экрана
                                        ;       @#46 - адрес массива данных
                mov     #AddrText8$, R5
                mov     #datText4$, R2
                mov     #175000, @#44
                call    @#sub_37024
                mov     #datText6$, R2
                mov     #addrText6$, R5
                call    @#sub_37014
                trap    70              ; Очистка экрана
                jmp     @#NextFinal4$
; ───────────────────────────────────────────────────────────────────────────
addrText6$:     .word 50024
                .word 56010
                .word 60006
                .word 62014
                .word 64016
                .word 66012
                .word 70012
                .word 72022
                .word 74012
                .word 0
datText6$:      .asciz "RUNING"
                .asciz "ВАША ЗАДАЧА:"
                .asciz "ПРОБРАТЬСЯ НА"
                .asciz "ДНО ШАХТЫ,"
                .asciz "УНИЧТОЖАЯ"
                .asciz "СВИДЕТЕЛЕИ,"
                .asciz "СПАСАЯСЬ ОТ"
                .asciz "ДУХОВ И"
                .asciz "ПОКОИНИКОВ."
datText6End$:
datText4$:      .asciz " СЛЕДУЩАЯ ИГРА"
                .asciz "GAME 4"
datText4End$:

datText2$:      .byte 14, 231
                .asciz "RUNING"
datText2End$:
AddrText8$:     .word 47002
                .word 51424
                .word 0
datText8$:      .asciz "ПРЕДЫДУЩАЯ ИГРА"
                .asciz "GAME 2"
datText8End$:

datText7$:      .byte 14, 274
                .asciz "SECOND"
datText7End$:
; таблица адресов экрана для вывода строк текста, 0 - конец
; текст - ниже
addrText5$:     .word 45200
                .word 46602
                .word 50204
                .word 51616
                .word 60010
                .word 61406
                .word 63010
                .word 64404
                .word 66000
                .word 67406
                .word 71004
                .word 72402
                .word 0
datText5$:      .asciz "ВЫ РАЗДЕЛАЛИСЬ С"
                .asciz "ОХРАНОИ ПЛАНЕТЫ"
                .asciz "И ПРОБРАЛИСЬ В"
                .asciz "ЕЕ НЕДРА."
                .asciz "ПРИОБРЕТАИТЕ"
                .asciz "СЛЕДУЩУЮ ИГРУ"
                .asciz "И ВЫ СМОЖЕТЕ"
                .asciz "ПОСЛУЖИТЬ ДЕЛУ"
                .asciz "МИРА─ УНИЧТОЖИТЬ"
                .asciz "ВОЕННУЮ БАЗУ,"
                .asciz "ЗАЛОЖИВ МИНУ В"
                .ascii "НЕДРАХ ПЛАНЕТЫ."
datText5End$:
; ───────────────────────────────────────────────────────────────────────────

MV1$:           mov     (R3)+, -4422(R3)
                sob     R0, MV1$
                call    @(SP)+


.SCRIPT "Text Encode"
    mov #strScore, R1
2$: movb (R1), R0
    beq 1$
    bpl 3$
    sub #40, R0
3$: sub #20, R0
1$: movb R0, (R1)+
    cmp R1, #strGuardEnd
    blo 2$

    mov #strSplashTxt2, R1
5$: movb (R1), R0
    beq 4$
    bpl 6$
    sub #40, R0
6$: sub #20, R0
4$: movb R0, (R1)+
    cmp R1, #strSplashTxt2e
    blo 5$

    mov #datText11, R1
8$: movb (R1), R0
    beq 7$
    bpl 9$
    sub #40, R0
9$: sub #20, R0
7$: movb R0, (R1)+
    cmp R1, #datText11End
    blo 8$

    mov #datText5$, R1
11$: movb (R1), R0
    beq 10$
    bpl 12$
    sub #40, R0
12$: sub #20, R0
10$: movb R0, (R1)+
    cmp R1, #datText5End$
    blo 11$

    mov #datText4$, R1
14$: movb (R1), R0
    beq 13$
    bpl 15$
    sub #40, R0
15$: sub #20, R0
13$: movb R0, (R1)+
    cmp R1, #datText4End$
    blo 14$

    mov #datText8$, R1
17$: movb (R1), R0
    beq 16$
    bpl 18$
    sub #40, R0
18$: sub #20, R0
16$: movb R0, (R1)+
    cmp R1, #datText8End$
    blo 17$

    mov #datText6$, R1
20$: movb (R1), R0
    beq 19$
    bpl 21$
    sub #40, R0
21$: sub #20, R0
19$: movb R0, (R1)+
    cmp R1, #datText6End$
    blo 20$


.ENDS


.SCRIPT "Text Encode2"

    mov #datText7$, R1
    tst (R1)+
2$: movb (R1), R0
    beq 1$
    bpl 3$
    sub #40, R0
3$: sub #20, R0
1$: movb R0, (R1)+
    cmp R1, #datText7End$
    blo 2$

    mov #datText2$, R1
    tst (R1)+
5$: movb (R1), R0
    beq 4$
    bpl 6$
    sub #40, R0
6$: sub #20, R0
4$: movb R0, (R1)+
    cmp R1, #datText2End$
    blo 5$


    mov #strSplashTxt3, R1
    tst (R1)+
18$: movb (R1), R0
    beq 17$
    bpl 19$
    sub #40, R0
19$: sub #20, R0
17$: movb R0, (R1)+
    cmp R1, #strSplashTxt3e
    blo 18$

    mov #datText10, R1
    tst (R1)+
21$: movb (R1), R0
    beq 20$
    bpl 22$
    sub #40, R0
22$: sub #20, R0
20$: movb R0, (R1)+
    cmp R1, #datText10End
    blo 21$

.ENDS

.SCRIPT "Info Encode"
        mov #datInfo$, R5
1$:     tst (R5)+
        movb (R5)+, R3
        beq 4$
2$:     movb (R5), R0
        beq 4$
        bpl 3$
        sub #40, R0
3$:     sub #20, R0
        movb R0, (R5)+
        sob R3, 2$
        br 1$
4$:

.ENDS

                .END
