; Чуточку оптимизированный и причёсанный вариант.
; Чтобы было удобнее в коде ориентироваться.
; игра обессмерчена и обнеуязвимлена, если нужна честная игра,
; найдите строки, содержащие ###, и закомментируйте/раскомментируйте нужное.


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

; ═══════════════════════════════════════════════════════════════════════════
FONT = 112276   ; Начало шрифта в ПЗУ БК10

; Переменные

F$DataBlock = 40            ; Начало блока данных
; для функции 160
F$ScrAddr   = F$DataBlock   ; адрес экрана
F$YScale    = F$DataBlock+2 ; масштаб по высоте
F$ColorMask = F$DataBlock+4 ; маска цвета
; для функции 156
F$DataAddr  = F$DataBlock+2 ; адрес данных
F$Delay     = F$DataBlock+6 ; задержка
F$Tmp       = F$DataBlock+10 ; временно храним количество символов
; для функции 154
F$GmNmColor = F$DataBlock   ; цвет цифры 2
F$GmNmAddr  = F$DataBlock+2 ; адрес с которого выводить цифру 2
F$Screen    = F$DataBlock+4 ; начало экрана
F$DataAddr2 = F$DataBlock+6 ; адрес данных
F$Color     = F$DataBlock+10 ; цвет
F$MaxScale  = F$DataBlock+12 ; макс.масштаб
F$GameNum   = F$DataBlock+14 ; цифра 2
F$Cycles    = F$DataBlock+16 ; количество циклов
F$GameAddr  = F$DataBlock+24 ; адрес с которого начинать выводить слово GAME

NeedMkFrstAct       = 300   ; флаг, нужно сделать какое-либо одноразовое действие:
                            ; отобразить пушку спец.функцией на этапе 2
                            ; задать задержку на этапе 4
CannonHitCount      = 306   ; количество попаданий из пушки, которое выдерживает шар
AnimLetColor        = 312   ; цвет анимированных букв
MenuCursor          = 316   ; адрес курсора меню
FirePower           = 322   ; уровень горения горелки
BallonAddr          = 324   ; экранный адрес воздушного шара
PlatformStartAddr   = 330   ; экранный адрес платформы, с которой стартуем
Stage               = 332   ; текущий этап
FinishAddr          = 336   ; адрес экрана где происходит приземление (проверка на финиш)
PlatformFinishAddr  = 342   ; экранный адрес платформы, на которую садимся (для финиша не используется)
AirFlowDir          = 344   ; направление воздушного потока, исп. только в функции 26
MoonAddr            = 346   ; экранный адрес луны
MoonMovPPtr         = 350   ; указатель в таблице параметров движения луны
MoonAddrIncr        = 352   ; приращение адреса луны
MoonPass            = 354   ; счётчик обходов луны
CannonAddrDraw      = 364   ; адрес экрана пушки для рисования
CannonAddr          = 366   ; адрес экрана пушки
HC$Tmp              = 466   ; временная ячейка для хранения значения R4 в функции HitCheck
CometHitCount       = 502   ; количество попаданий комет, которое выдерживает шар
HeadAddr            = 504   ; экранный адрес бошки
HeadTimeLife        = 506   ; время жизни бошки
SR$Tmp              = 510   ; буфер хранения значений регистров

TopStack            = 760   ; вершина стека
TimerValue          = 21000 ; значение ВЕ-таймера

BulletBuffer = 36500    ; буфер пулек, один элемент - 2 слова: адрес и направление движения (вверх или вниз)
BulletsNum = 20         ; максимальное количество пулек на экране
BulletBufferSize = BulletsNum * 4 ; размер буфера
; буфер, где сохраняется содержимое экрана под спрайтом пушки, размер 163 байта
CanScrBuffer = BulletBuffer + BulletBufferSize
SpriteBuffer = 37000    ; тут сохраняется фон под спрайтом
TempBuffer = 37000      ; временный буфер для хранения адресов ячеек с кодами клавиш.
; буфер, где сохраняется содержимое экрана под спрайтом, когда шар опускается до уровня земли
BalScrBuffer = 40000 - BallonSprW * BallonSprH

Start0$:        jmp     Start1$         ; Запускаем игру

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


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     ; получаем мл. байт
                call    @TrapTbl(R5)
                mov     (SP)+, R5
                mov     (SP)+, R4
                mov     (SP)+, R3
                mov     (SP)+, R2
                mov     (SP)+, R1
                mov     (SP)+, R0
VecKbd:         rti
; End of function DisTrap

; ───────────────────────────────────────────────────────────────────────────
TrapTbl:        .word Func00            ; Очистка экрана диагонально зубчатыми линиями
                .word Func02            ; Инициализация некоторых переменных драйвера экрана
                .word Func04            ; Прорисовка мигающих звёздочек
                                        ; Вход: R2 - адрес блока параметров:
                                        ;            .word число элементов (пар адресов)
                                        ;            .word адрес спрайта в памяти
                                        ;            .word адрес экрана
                .word Func06            ; Рисование методом наложения
                                        ; Вход: R0 - адрес спрайта в памяти
                                        ;       R1 - адрес экрана
                                        ;       R2 - высота спрайта
                                        ;       R3 - ширина спрайта в байтах
                .word Func10            ; Стирание методом побитовой очистки
                                        ; Вход: R0 - адрес спрайта в памяти
                                        ;       R1 - адрес экрана
                                        ;       R2 - высота спрайта
                                        ;       R3 - ширина спрайта в байтах
                .word Func12            ; Вывод на экран платформы для воздушного шара
                                        ; Вход: R1 - адрес экрана
                                        ;       R2 - масштаб по высоте
                .word Func14            ; Звучание тонального набора
                                        ; Вход: R3 - адрес тонального набора - цепочка пар слов
                                        ;            .word длительность (0 - конец цепочки),
                                        ;            .word тон.
                .word Func16            ; Проверка на нажатие клавиши или кнопки джойстика, если нажата - выход
                .word Func20            ; Вывод звёзд в игре
                .word Func22            ; Стирание спрайта с экрана безусловное
                                        ; Вход: R1 - адрес экрана
                                        ;       R2 - высота спрайта
                                        ;       R3 - ширина спрайта в байтах
                .word Func24            ; Анимация огня горелки воздушного шара
                .word Func26            ; Анимация воздушных потоков
                                        ; Вход: R3 - адрес блока параметров
                .word Func30            ; Спецэффект бегущей волны искажения на экране
                .word Func32            ; Вспомогательная функция функции 30
                                        ; Вход: R0 - адрес экрана
                                        ;       R1 - ширина в байтах
                                        ;       R4 - тон звука
                .word Func34            ; Инициализация обходов Луны и функция 42
                .word Func36            ; Очистка со сравнением, экран очищается только там, где спрайт совпадает
                                        ; Вход: R0 - адрес спрайта в памяти
                                        ;       R1 - адрес экрана
                                        ;       R2 - высота спрайта
                                        ;       R3 - ширина спрайта в байтах
                .word Func40            ; Вывод со сравнением, спрайт выводится только там, где на экране пусто
                                        ; Вход: R0 - адрес спрайта в памяти
                                        ;       R1 - адрес экрана
                                        ;       R2 - высота спрайта
                                        ;       R3 - ширина спрайта в байтах
                .word Func42            ; Инициализация яч. MoonAddr, MoonMovPPtr
                .word Func44            ; Инициализация яч. FinishAddr и функция 46
                .word Func46            ; Очистка буфера BalScrBuffer
                .word Func50            ; Вкл/выкл фоновой музыки
                .word Func52            ; Резерв
                .word Func54            ; Если нажата клавиша горелки, делать анимацию огня горелки
                .word Func56            ; Резерв
                .word Func60            ; Выход: R0 - признак:
                                        ;       -1 - джойстик не нажат, и горелка не нажата
                                        ;       0 - джойстик нажат и ранее была нажата клавиша горелки
                                        ;       100250/100350 - ранее была нажата клавиша горелки, а джойстик не нажат
                .word Func62            ; Кажется, уменьшение счёта
                .word Func64            ; Инициализация счёта
                .word Func66            ; Вывод символа на экран
                                        ; Вход: R0 - адрес данных символа
                                        ;       R1 - адрес экрана
                .word Func70            ; Вывод строки на экран через буфер и скроллинг
                                        ; Вход: R3 - адрес экрана
                                        ;       R4 - адрес строки текста
                .word Func72            ; Вывод звука с повышением тона
                                        ; Вход: R4 - адрес блока параметров
                                        ;       .word длит.
                                        ;       .word тон,тон,..., 0 - конец цепочки
                .word Func74            ; Прокрутка экрана с попутной очисткой внутри рамки
                .word Func76            ; Отрисовка набора мигающих звёздочек
                .word Func100           ; Вывод текста очень широкими буквами
                                        ; Вход: R0 - коэффициент растяжения по вертикали
                                        ;       R1 - адрес экрана
                                        ;       R5 - адрес текста
                .word Func102           ; Очистка экрана горизонтальными линиями сверху и снизу
                .word Func104           ; вывод строки на экран
                                        ; Вход: R1 - адрес экрана
                                        ;       R4 - адрес строки, конец строки - 0
                                        ; Выход: R4 - адрес за концом строки
                .word Func106           ; Анимация букв
                                        ; Вход: R0 - адрес данных букв
                                        ;       R1 - адрес экрана
                                        ;       R2 - масштаб по высоте
                                        ; Выход: R1 - адрес экрана после действия
                .word Func110           ; мигают звёзды и ждём нажатия клавиши
                .word Func112           ; Проверка на нажатие кнопки паузы
                                        ; и если да, то пауза
                .word Func114           ; Вывод на экран строк об авторе, копирайт,
                                        ; и сделать остальной текст синим.
                .word Func116           ; Звук, ждать нажатия клавиши или джойстика, звук,
                                        ; очистка экрана с прокруткой
                .word Func120           ; Издать некий определённый звук
                .word Func122           ; Передвинуть пушку
                                        ; Вход: R1 - текущий адрес пушки
                                        ; Вход: R4 - приращение адреса
                .word Func124           ; Отобразить пушку
                .word Func126           ; Выстрел из пушки
                .word Func130           ; Полёт пули вверх
                                        ; Вход: R1 - адрес экран
                                        ;       R4 - адрес элемента в буфере + 4
                .word Func132           ; Полёт пули вниз
                                        ; Вход: R1 - адрес экран
                                        ;       R4 - адрес элемента в буфере + 4
                .word Func134           ; Прорисовка комет, летящих слева направо
                                        ; Вход: R4 - адрес текущего элемента массива
                .word Func136           ; Проверка на попадания кометы в шара
                                        ; Вход R4 - адрес текущего элемента массива комет
                .word Func140           ; Прорисовка комет, летящих справа налево
                                        ; Вход: R4 - адрес текущего элемента массива
                .word Func142           ; Просмотр массива на счёт врезавшихся друг в друга встречно летящих комет,
                                        ; если они врезались друг в друга - взаимоуничтожаются
                                        ; Вход: R0 - адрес буфера комет + 2
                .word Func144           ; проверка на коллизию встречно летящих комет,
                                        ; если они врезались друг в друга - взаимоуничтожаются
                                        ; Вход: R0 - адрес эл-та 1
                                        ;       R4 - адрес эл-та 2
                .word Func146           ; Отображаем бошку, проверяем время её жизни и встречу с воздушным шаром
                .word Func150           ; Прорисовка разлетающихся осколков от башки
                                        ; и проверка на попадание в воздушный шар
                .word Func152           ; Проигрыш музыки
                                        ; Вход: R4 - адрес массива мелодии
                .word Func154           ; выводит GAME 2
                .word Func156           ; Вывод скроллом текста, описания к игре 2
                .word Func160           ; Вывод символа на экран
                                        ; Вход: R2 - код символа
                                        ;       @#F$ScrAddr - адрес экрана, куда выводить
                                        ;       @#F$YScale - масштаб по высоте
                                        ;       @#F$ColorMask - маска цвета
                .word Func162           ; Вывод текста сложного формата на экран
                                        ; Вход: @#F$DataAddr2 - адрес массива данных
                                        ;       @#F$ScrAddr - адрес экрана, куда выводить
                .word 0


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

; Очистка экрана диагонально зубчатыми линиями

Func00:         mov     #100, R5
                mov     #77700, R4
                mov     #40077, R3
                br      4$
; ───────────────────────────────────────────────────────────────────────────

1$:             mov     R4, R0
                mov     R3, R1

2$:             mov     #4, R2

3$:             clrb    (R0)
                clrb    (R1)
                add     #100, R1
                sub     #100, R0
                sob     R2, 3$
                tst     R5
                beq     7$
                inc     R0
                dec     R1
                bit     #100100, R1
                beq     2$
                sub     #400, R4
                add     #400, R3

4$:             mov     R4, R0
                mov     R3, R1

5$:             mov     #4, R2

6$:             movb    #125, (R0)
                movb    #125, (R1)
                sub     #100, R0
                add     #100, R1
                sob     R2, 6$
                inc     R0
                dec     R1
                bit     #100100, R1
                beq     5$
                mov     #5000, R0

                sob     R0, .
                sob     R5, 1$
                br      1$
; ───────────────────────────────────────────────────────────────────────────

7$:             return
; End of function Func00


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

; Инициализация некоторых переменных драйвера экрана

Func02:         mov     #40, R0
                mov     #5, R1

1$:             clr     (R0)+
                sob     R1, 1$
                movb    #377, @#56
                mov     #162, R0
                mov     #2, (R0)+       ; 162
                mov     #3000, (R0)+    ; 164
                mov     #1330, @#177664
                mov     #202, R1
                mov     #40000, (R1)+   ; 202
                mov     #2000, (R1)+    ; 204
                mov     #40000, (R1)+   ; 206
                mov     #36000, (R1)+   ; 210
                clr     (R1)+           ; 212
                mov     #-1, (R1)+      ; 214
                clr     (R1)+           ; 216
                clr     (R1)+           ; 220
                comb    @#40
Func56:
Func52:         return
; End of function Func02



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

; Вывод звёзд в игре

Func20:         mov     #GameStars, R2  ; массив звёзд в игре
; End of function Func20

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

; Прорисовка мигающих звёздочек
; Вход: R2 - адрес блока параметров:
;            .word число элементов (пар адресов)
;            .word адрес спрайта в памяти
;            .word адрес экрана

Func04:         mov     (R2)+, R4       ; количество элементов

1$:             mov     (R2)+, R0       ; адрес спрайта текущего элемента
                mov     #9., R3         ; высота
                mov     (R2), R1        ; адрес экрана, куда выводить

2$:             mov     #2, R5          ; ширина

3$:             cmpb    (R0)+, (R1)     ; на экране данные совпадают?
                bne     4$
                clrb    (R1)            ; да - стираем спрайт

4$:             inc     R1
                sob     R5, 3$
                add     #76, R1
                sob     R3, 2$          ; и так весь спрайт
                mov     (PC)+, R0       ; адрес нового спрайта
5SprAddr$:      .word   StarSpr3
                mov     R0, R5
                mov     R0, -2(R2)      ; сохраним в таблице
                tst     (PC)+           ; звезда увеличивается?
6StarDirect$:   .word 0                 ; флаг - увеличивать звезду или уменьшать
                beq     8$              ; да
                cmp     #StarSpr0, R0   ; нет - уменьшается, а уменьшаться есть куда?
                beq     7$              ; нету, надо увеличивать
                sub     #StarSprLen, R5 ; уменьшаем - переходим к предыдущему спрайту
                br      10$
; ───────────────────────────────────────────────────────────────────────────

8$:             cmp     #StarSpr4, R0   ; увеличиваться есть куда?
                bne     9$              ; да
                sub     #<StarSprLen*2>, R5 ; нет - пора уменьшаться
7$:             com     6StarDirect$    ; изменяем уменьшение<->увеличение

9$:             add     #StarSprLen, R5 ; переходим к следующему спрайту

10$:            mov     R5, 5SprAddr$
                mov     (R2)+, R1       ; адрес экрана
                mov     #9., R3         ; теперь выведем его на пустое место

11$:            mov     #2, R5

12$:            tstb    (R1)
                bne     13$
                movb    (R0), (R1)

13$:            inc     R1
                inc     R0
                sob     R5, 12$
                add     #76, R1
                sob     R3, 11$
                sob     R4, 1$          ; и так всю таблицу
                return
; End of function Func04

; ───────────────────────────────────────────────────────────────────────────
; тут графические данные:
; Спрайт земли, ; ширина 40 байтов, высота 33
GroundSprite:   .word 0, 0, 0, 0, 1777, 0, 170000, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100000
                .word 5042, 0, 124000, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120000, 24250, 25000, 125000, 242
                .word 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 124000, 121252, 121200, 125200, 1212, 0, 0, 0, 0
                .word 0, 0, 0, 0, 0, 0, 0, 125000, 25252, 105052, 125242, 5052, 0, 0, 0, 0, 0, 0, 0, 0
                .word 0, 0, 176000, 125217, 105250, 24252, 125212, 24252, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 125000, 25050
                .word 121242, 121252, 125050, 101042, 12, 0, 0, 0, 0, 1760, 0, 0, 0, 0, 125200, 104242, 124212, 105252, 24242, 125210
                .word 50, 0, 0, 0, 0, 5050, 0, 0, 0, 0, 25240, 121212, 125052, 25252, 101212, 105250, 242, 0, 0, 0
                .word 0, 121202, 12, 0, 0, 0, 125250, 125050, 124242, 125252, 104050, 25252, 1212, 0, 0, 0, 100000, 124252, 242, 0
                .word 2, 0, 125252, 124242, 121212, 125252, 124202, 125252, 5050, 0, 0, 0, 120200, 105212, 5042, 100000, 10, 104000, 124252, 121212
                .word 105052, 105252, 125210, 125252, 24242, 0, 0, 0, 105250, 21042, 121052, 120000, 242, 25000, 125052, 105052, 24252, 20242, 252, 121252
                .word 121212, 2, 0, 0, 25012, 125252, 21252, 20012, 5012, 125200, 105240, 24252, 121252, 125010, 125012, 105240, 5052, 52, 0, 101000
                .word 124252, 1250, 21252, 124242, 120252, 121242, 121212, 121252, 125250, 25250, 124240, 25012, 124252, 52240, 52525, 105205, 121252, 124242, 125250, 125042
                .word 5012, 105010, 124052, 105212, 5242, 100252, 125252, 100250, 121252, 45012, 52525, 24241, 105252, 105012, 125202, 101052, 125242, 124202, 101250, 25242
                .word 120242, 125202, 125252, 25252, 105012, 20252, 52524, 125250, 125250, 25240, 125052, 121252, 25250, 125250, 25242, 125250, 125012, 125252, 1002, 125252
                .word 1240, 125240, 12402, 105252, 25242, 125252, 120240, 125252, 125252, 104252, 120012, 25002, 121240, 452, 52525, 125001, 52532, 405, 102652, 25052
                .word 105212, 125252, 105212, 125212, 1052, 125240, 5252, 100252, 25252, 52500, 52525, 525, 55240, 52525, 122401, 124212, 450, 125250, 1252, 120002
                .word 52500, 1005, 125252, 125240, 41240, 52525, 52525, 52525, 50005, 52525, 2525, 125252, 52502, 125201, 52412, 2525, 52525, 52525, 124001, 101212
                .word 52052, 52525, 52525, 52525, 52525, 52525, 52525, 25240, 52524, 425, 52520, 52525, 52525, 52525, 525, 125250, 50050, 52525, 52525, 52525
                .word 52525, 52525, 52525, 40005, 52525, 52525, 52525, 52525, 52525, 52525, 52525, 125001, 5242, 52520, 52525, 52525, 52525, 52525, 52525, 52525
                .word 52525, 52525, 52525, 52525, 52525, 52525, 52525, 100125, 124252, 40012, 52525, 52525, 52525, 52525, 52525, 52525, 52525, 52525, 52525, 52525
                .word 52525, 52525, 52525, 12525, 125200, 65252, 52525, 52525, 52525, 52525, 52525, 52525, 52525, 52525, 52525, 52525, 52525, 52525, 52525, 52525
                .word 425, 40001, 52525, 52525, 52525, 52525, 52525, 52525, 52525, 52525, 52525, 52525
; ───────────────────────────────────────────────────────────────────────────
; Платформа, ширина 10, высота 36
PlatformSprite: .byte 0, 0, 0, 0, 0, 0, 0, 0
                .byte 0, 0, 0, 0, 0, 0, 0, 0
                .byte 0, 0, 360, 0, 0, 74, 0, 0
                .byte 0, 0, 300, 377, 377, 17, 0, 0
                .byte 0, 0, 0, 307, 117, 3, 0, 0
                .byte 0, 0, 0, 34, 321, 0, 0, 0
                .byte 0, 0, 0, 360, 74, 0, 0, 0
                .byte 0, 0, 0, 300, 15, 0, 0, 0
                .byte 0, 0, 0, 300, 14, 0, 0, 0
                .byte 0, 0, 0, 360, 77, 0, 0, 0
                .byte 0, 0, 0, 160, 67, 0, 0, 0
                .byte 0, 0, 0, 60, 61, 0, 0, 0
                .byte 0, 0, 0, 160, 64, 0, 0, 0
                .byte 0, 0, 0, 374, 375, 0, 0, 0
                .byte 0, 0, 0, 354, 357, 0, 0, 0
                .byte 0, 0, 0, 214, 310, 0, 0, 0
                .byte 0, 0, 0, 54, 342, 0, 0, 0
                .byte 0, 0, 0, 213, 210, 3, 0, 0
                .byte 0, 0, 0, 43, 42, 3, 0, 0
                .byte 0, 0, 300, 277, 370, 17, 0, 0
                .byte 0, 0, 77, 376, 377, 362, 3, 0
                .byte 0, 377, 210, 310, 217, 210, 374, 3
                .byte 300, 42, 42, 42, 42, 42, 42, 16
                .byte 0, 377, 213, 310, 217, 210, 377, 3
                .byte 0, 0, 374, 62, 62, 376, 0, 0
                .byte 0, 0, 0, 277, 370, 3, 0, 0
                .byte 0, 0, 0, 300, 16, 0, 0, 0
                .byte 0, 0, 0, 300, 14, 0, 0, 0
                .byte 0, 0, 0, 300, 16, 0, 0, 0
                .byte 0, 0, 0, 0, 3, 0, 0, 0
PlatformSprEnd:
PlatformSprLen = PlatformSprEnd - PlatformSprite
PlatformSprH = 36
PlatformSprW = 10
PlatformSprPitch = 100 - PlatformSprW

; Маска платформы, ширина 10, высота 36
PlatformSprMask:.byte 0, 0, 0, 0, 0, 0, 0, 0
                .byte 0, 0, 0, 0, 0, 0, 0, 0
                .byte 0, 0, 360, 0, 0, 74, 0, 0
                .byte 0, 0, 300, 377, 377, 17, 0, 0
                .byte 0, 0, 0, 377, 377, 3, 0, 0
                .byte 0, 0, 0, 374, 377, 0, 0, 0
                .byte 0, 0, 0, 360, 77, 0, 0, 0
                .byte 0, 0, 0, 300, 17, 0, 0, 0
                .byte 0, 0, 0, 300, 17, 0, 0, 0
                .byte 0, 0, 0, 360, 77, 0, 0, 0
                .byte 0, 0, 0, 360, 77, 0, 0, 0
                .byte 0, 0, 0, 360, 77, 0, 0, 0
                .byte 0, 0, 0, 360, 77, 0, 0, 0
                .byte 0, 0, 0, 374, 377, 0, 0, 0
                .byte 0, 0, 0, 374, 377, 0, 0, 0
                .byte 0, 0, 0, 374, 377, 0, 0, 0
                .byte 0, 0, 0, 374, 377, 0, 0, 0
                .byte 0, 0, 0, 377, 377, 3, 0, 0
                .byte 0, 0, 0, 377, 377, 3, 0, 0
                .byte 0, 0, 300, 377, 377, 17, 0, 0
                .byte 0, 0, 377, 377, 377, 377, 3, 0
                .byte 0, 377, 377, 377, 377, 377, 377, 3
                .byte 300, 377, 377, 377, 377, 377, 377, 17
                .byte 0, 377, 377, 377, 377, 377, 377, 3
                .byte 0, 0, 374, 377, 377, 377, 0, 0
                .byte 0, 0, 0, 377, 377, 3, 0, 0
                .byte 0, 0, 0, 300, 17, 0, 0, 0
                .byte 0, 0, 0, 300, 17, 0, 0, 0
                .byte 0, 0, 0, 300, 17, 0, 0, 0
                .byte 0, 0, 0, 0, 3, 0, 0, 0
; ───────────────────────────────────────────────────────────────────────────
; Воздушный шар, ширина 4, высота 34
BallonSprite:   .byte 0, 274, 27, 0
                .byte 300, 277, 127, 1
                .byte 360, 257, 137, 5
                .byte 374, 253, 177, 25
                .byte 374, 253, 376, 25
                .byte 377, 253, 376, 125
                .byte 377, 252, 376, 127
                .byte 377, 252, 372, 127
                .byte 377, 252, 372, 127
                .byte 377, 252, 376, 127
                .byte 377, 253, 376, 125
                .byte 377, 253, 376, 125
                .byte 374, 253, 177, 25
                .byte 364, 257, 137, 25
                .byte 304, 277, 127, 21
                .byte 4, 275, 127, 20
                .byte 20, 1, 100, 4
                .byte 20, 4, 20, 4
                .byte 20, 4, 20, 4
                .byte 100, 4, 20, 1
                .byte 100, 360, 17, 1
                .byte 100, 257, 372, 1
                .byte 0, 377, 377, 0
                .byte 0, 376, 277, 0
                .byte 0, 256, 252, 0
                .byte 0, 376, 257, 0
                .byte 0, 256, 272, 0
                .byte 0, 374, 57, 0
BallonSprEnd:
BallonSprLen = BallonSprEnd - BallonSprite  ; размер спрайта воздушного шара
BallonSprH = 34
BallonSprW = 4
BallonSprPitch = 100 - BallonSprW

; Маска воздушного шара, ширина 4, высота 34
BallonSprMask:  .byte 0, 374, 77, 0
                .byte 300, 377, 377, 3
                .byte 360, 377, 377, 17
                .byte 374, 377, 377, 77
                .byte 374, 377, 377, 77
                .byte 377, 377, 377, 377
                .byte 377, 377, 377, 377
                .byte 377, 377, 377, 377
                .byte 377, 377, 377, 377
                .byte 377, 377, 377, 377
                .byte 377, 377, 377, 377
                .byte 377, 377, 377, 377
                .byte 374, 377, 377, 77
                .byte 374, 377, 377, 77
                .byte 314, 377, 377, 63
                .byte 14, 377, 377, 60
                .byte 60, 3, 300, 14
                .byte 60, 14, 60, 14
                .byte 60, 14, 60, 14
                .byte 300, 14, 60, 3
                .byte 300, 360, 17, 3
                .byte 300, 377, 377, 3
                .byte 0, 377, 377, 0
                .byte 0, 377, 377, 0
                .byte 0, 377, 377, 0
                .byte 0, 377, 377, 0
                .byte 0, 377, 377, 0
                .byte 0, 374, 77, 0
; ───────────────────────────────────────────────────────────────────────────
; спрайт нижней границы экрана, ширина 4, высота 21 (включая нижний спрайт)
Block2Sprite:   .byte 356, 340, 356, 356
                .byte 73, 270, 273, 273
                .byte 16, 356, 356, 356
                .byte 203, 273, 273, 273
                .byte 340, 356, 356, 356
                .byte 0, 0, 0, 0
                .byte 270, 273, 273, 73
                .byte 356, 356, 356, 16
                .byte 273, 273, 273, 203
                .byte 356, 356, 356, 340
                .byte 273, 273, 73, 270
                .byte 0, 0, 0, 0
; Кирпичик, используется как нижняя и верхняя граница в заставке
; ширина 4, высота 5
BlockSprite:    .byte 273, 273, 73, 273
                .byte 356, 356, 56, 356
                .byte 273, 273, 73, 273
                .byte 356, 356, 56, 356
                .byte 273, 273, 73, 273

; ───────────────────────────────────────────────────────────────────────────
; спрайты звёздочек, 5 штук
; ширина 2 байта, высота 9 строк
StarSpr0:       .word 0 ; нет звезды
                .word 0
                .word 0
                .word 0
                .word 0
                .word 0
                .word 0
                .word 0
                .word 0
StarSpr1:       .word ^B0000000000000000
                .word ^B0000000000000000
                .word ^B0000000000000000
                .word ^B0000000100000000
                .word ^B0000000100000000
                .word ^B0000000100000000
                .word ^B0000000000000000
                .word ^B0000000000000000
                .word ^B0000000000000000
StarSpr2:       .word ^B0000000000000000
                .word ^B0000000000000000
                .word ^B0000000100000000
                .word ^B0000000100000000
                .word ^B0000010101000000
                .word ^B0000000100000000
                .word ^B0000000100000000
                .word ^B0000000000000000
                .word ^B0000000000000000
StarSpr3:       .word ^B0000000000000000
                .word ^B0000000100000000
                .word ^B0000000100000000
                .word ^B0000010101000000
                .word ^B0001010101010000
                .word ^B0000010101000000
                .word ^B0000000100000000
                .word ^B0000000100000000
                .word ^B0000000000000000
StarSpr4:       .word ^B0000000100000000
                .word ^B0000000100000000
                .word ^B0000010101000000
                .word ^B0000010101000000
                .word ^B0101010101010100
                .word ^B0000010101000000
                .word ^B0000010101000000
                .word ^B0000000100000000
                .word ^B0000000100000000
StarSprLen = StarSpr1 - StarSpr0    ; размер спрайта в байтах
; ───────────────────────────────────────────────────────────────────────────
; ширина 5, высота 17
; Пушка
CannonSprite:   .byte 0, 0, 252, 0, 0
                .byte 0, 300, 377, 3, 0
                .byte 0, 300, 377, 3, 0
                .byte 0, 0, 252, 0, 0
                .byte 0, 0, 353, 0, 0
                .byte 0, 0, 276, 0, 0
                .byte 0, 0, 252, 0, 0
                .byte 0, 300, 377, 3, 0
                .byte 0, 374, 377, 77, 0
                .byte 360, 252, 252, 252, 17
                .byte 324, 377, 327, 377, 27
                .byte 125, 377, 125, 377, 125
                .byte 125, 377, 125, 377, 125
                .byte 125, 0, 125, 0, 125
                .byte 24, 0, 24, 0, 24
CannonSprEnd:   .even
CannonSprLen = CannonSprEnd - CannonSprite
CannonSprW = 5
CannonSprH = 17
CannonSprPitch = 100 - CannonSprW
; ширина 5, высота 17
CannonSprMask:  .byte 0, 0, 377, 0, 0
                .byte 0, 300, 377, 3, 0
                .byte 0, 300, 377, 3, 0
                .byte 0, 0, 377, 0, 0
                .byte 0, 0, 377, 0, 0
                .byte 0, 0, 377, 0, 0
                .byte 0, 0, 377, 0, 0
                .byte 0, 300, 377, 3, 0
                .byte 0, 374, 377, 77, 0
                .byte 360, 377, 377, 377, 17
                .byte 374, 377, 377, 377, 77
                .byte 377, 377, 377, 377, 377
                .byte 377, 377, 377, 377, 377
                .byte 377, 0, 377, 0, 377
                .byte 74, 0, 74, 0, 74
                .even
; ───────────────────────────────────────────────────────────────────────────
; Спрайт пулька вверх
; ширина 1 высота 7
BulletUpSprite: .byte ^B00111100
                .byte ^B00101000
                .byte ^B00111100
                .byte ^B00101000
                .byte ^B11101011
                .byte ^B10000010
                .byte ^B11000011
                .byte 0
; ширина 1 высота 7
BulletUpSprMask:
                .byte ^B00111100
                .byte ^B00111100
                .byte ^B00111100
                .byte ^B00111100
                .byte ^B11111111
                .byte ^B11000011
                .byte ^B11000011
                .byte 0
; ───────────────────────────────────────────────────────────────────────────
; Спрайт пулька вниз
; ширина 1 высота 7
BulletDnSprite: .byte ^B11000011
                .byte ^B10000010
                .byte ^B11101011
                .byte ^B00101000
                .byte ^B00111100
                .byte ^B00101000
                .byte ^B00111100
                .byte 0
; ширина 1 высота 7
BulletDnSprMask:
                .byte ^B11000011
                .byte ^B11000011
                .byte ^B11111111
                .byte ^B00111100
                .byte ^B00111100
                .byte ^B00111100
                .byte ^B00111100
                .byte 0
; ширина 1 высота 7
; выстрел из пушки
ShootSprite:    .byte ^B11000011
                .byte ^B00111100
                .byte ^B00111100
                .byte ^B11111111
                .byte ^B00111100
                .byte ^B00111100
                .byte ^B11000011
                .byte 0
; ───────────────────────────────────────────────────────────────────────────
; ширина 4, высота 21
SpriteBlow1:    .byte 0, 0, 0, 0
                .byte 0, 0, 300, 3
                .byte 300, 0, 60, 14
                .byte 60, 17, 60, 63
                .byte 260, 60, 214, 14
                .byte 14, 63, 63, 3
                .byte 60, 310, 10, 14
                .byte 300, 156, 314, 62
                .byte 60, 300, 41, 314
                .byte 74, 56, 362, 343
                .byte 303, 300, 14, 314
                .byte 43, 54, 62, 60
                .byte 74, 63, 63, 0
                .byte 300, 60, 310, 0
                .byte 0, 300, 63, 0
                .byte 0, 0, 14, 0
                .byte 0, 0, 0, 0
; ширина 4, высота 21
SpriteBlow2:    .byte 0, 0, 0, 0
                .byte 0, 34, 43, 0
                .byte 200, 0, 0, 14
                .byte 303, 0, 62, 0
                .byte 0, 7, 0, 0
                .byte 0, 300, 14, 63
                .byte 40, 60, 60, 0
                .byte 3, 314, 317, 10
                .byte 301, 300, 14, 114
                .byte 0, 314, 317, 300
                .byte 63, 60, 60, 4
                .byte 0, 2, 2, 314
                .byte 60, 0, 300, 0
                .byte 0, 60, 14, 0
                .byte 0, 40, 0, 2
                .byte 60, 3, 304, 60
                .byte 4, 0, 3, 0
; ширина 4, высота 21
SpriteBlow3:    .byte 0, 0, 0, 0
                .byte 0, 0, 0, 0
                .byte 0, 0, 0, 0
                .byte 0, 0, 60, 0
                .byte 0, 2, 2, 10
                .byte 0, 14, 0, 0
                .byte 0, 0, 3, 0
                .byte 0, 0, 0, 14
                .byte 1, 60, 63, 100
                .byte 0, 0, 0, 0
                .byte 300, 0, 3, 0
                .byte 0, 0, 300, 0
                .byte 0, 0, 0, 0
                .byte 200, 60, 20, 2
                .byte 0, 0, 0, 0
                .byte 0, 0, 0, 0
                .byte 0, 0, 0, 0
BlowSprLen = SpriteBlow2 - SpriteBlow1
BlowSprW = 4
BlowSprH = 21
; ───────────────────────────────────────────────────────────────────────────
; ширина 6 высота 12
SpriteCometL1:  .byte 300, 3, 3, 0, 0, 0
                .byte 374, 75, 40, 0, 0, 0
                .byte 234, 47, 0, 0, 0, 0
                .byte 377, 357, 4, 0, 200, 0
                .byte 377, 227, 300, 300, 0, 4
                .byte 376, 227, 0, 10, 40, 304
                .byte 377, 357, 20, 0, 1, 0
                .byte 234, 47, 0, 0, 300, 0
                .byte 374, 75, 0, 0, 40, 0
                .byte 300, 3, 3, 0, 0, 0
SpriteCometL2:  .byte 300, 3, 0, 0, 0, 0
                .byte 174, 77, 3, 0, 0, 0
                .byte 330, 66, 20, 100, 0, 0
                .byte 373, 377, 0, 14, 14, 0
                .byte 326, 377, 300, 200, 200, 300
                .byte 326, 277, 10, 200, 0, 0
                .byte 373, 377, 0, 4, 10, 14
                .byte 330, 66, 60, 300, 0, 0
                .byte 174, 77, 3, 0, 0, 0
                .byte 300, 3, 0, 0, 0, 0
SpriteCometLEnd:
SpriteCometR1:  .byte 0, 0, 0, 300, 300, 3
                .byte 0, 0, 0, 10, 174, 77
                .byte 0, 0, 0, 0, 330, 66
                .byte 0, 2, 0, 20, 373, 377
                .byte 20, 0, 3, 3, 326, 377
                .byte 23, 10, 40, 0, 326, 277
                .byte 0, 100, 0, 4, 373, 377
                .byte 0, 3, 0, 0, 330, 66
                .byte 0, 10, 0, 0, 174, 77
                .byte 0, 0, 0, 300, 300, 3
SpriteCometR2:  .byte 0, 0, 0, 0, 300, 3
                .byte 0, 0, 0, 300, 374, 75
                .byte 0, 0, 3, 14, 234, 47
                .byte 60, 40, 20, 0, 377, 357
                .byte 0, 0, 2, 40, 376, 227
                .byte 3, 2, 2, 3, 377, 227
                .byte 0, 60, 60, 0, 377, 357
                .byte 0, 0, 1, 4, 234, 47
                .byte 0, 0, 0, 300, 374, 75
                .byte 0, 0, 0, 0, 300, 3
SpriteCometREnd:
CometSprW = 6
CometSprH = 12
CometSprPitch = 100 - CometSprW
; ───────────────────────────────────────────────────────────────────────────
; спрайт, используется в функции 146
; ширина 3, высота 16
SpriteBoshka:   .byte 0
                .byte 252, 0, 300
                .byte 125, 17, 250
                .byte 125, 52, 324
                .byte 377, 27, 327
                .byte 377, 327, 353
                .byte 377, 353, 353
                .byte 175, 353, 365
                .byte 377, 137, 265
                .byte 175, 136, 327
                .byte 226, 327, 327
                .byte 226, 327, 324
                .byte 353, 27, 250
                .byte 125, 52, 360
                .byte 125, 17, 0
                .byte 0
BoshkaSprW = 3
BoshkaSprH = 16
BoshkaSprPitch = 100 - BoshkaSprW

SpiteHeadBullet:.byte ^B11101011
                .byte ^B10111110
                .byte ^B11010111
                .even
HeadBulletSprH = 3
HeadBulletSprW = 1
; ───────────────────────────────────────────────────────────────────────────


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

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

Func06:         mov     #100, R4        ; ширина экрана
                sub     R3, R4          ; pitch
1$:             mov     R3, R5

2$:             bisb    (R0)+, (R1)+
                sob     R5, 2$
                add     R4, R1

                sob     R2, 1$
                return
; End of function Func06


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

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

Func10:         mov     #100, R4
                sub     R3, R4
1$:             mov     R3, R5

2$:             bicb    (R0)+, (R1)+
                sob     R5, 2$
                add     R4, R1

                sob     R2, 1$
                return
; End of function Func10


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

; Вывод на экран платформы для воздушного шара
; Вход: R1 - адрес экрана
;       R2 - масштаб по высоте

Func12:         mov     #3, R5
                mov     R2, 12.ScaleY$
                mov     #PlatformSprite, R0 ; спрайт
                mov     #PlatformSprMask, R4 ; маска
                mov     #7, R2          ; размер немасштабируемого блока линий

1$:             mov     #PlatformSprW, R3 ; ширина

2$:             bicb    (R4)+, (R1)
                bisb    (R0)+, (R1)+
                sob     R3, 2$          ; выводим одну линию
                add     #PlatformSprPitch, R1
                sob     R2, 1$          ; выводим блок линий
                tst     R5
                beq     6$
                mov     (PC)+, R2
12.ScaleY$:     .word 37
; ───────────────────────────────────────────────────────────────────────────

3$:             mov     #2, R3          ; размер блока линий

4$:             mov     R5, -(SP)       ; сохраним R5
                mov     #PlatformSprW, R5 ; ширина

5$:             bicb    (R4)+, (R1)
                bisb    (R0)+, (R1)+
                sob     R5, 5$          ; выводим одну линию
                mov     (SP)+, R5       ; восстановим R5
                add     #PlatformSprPitch, R1
                sob     R3, 4$          ; выводим блок из двух линий
                sub     #20, R0         ; возвращаемся в начало блока
                sub     #20, R4
                sob     R2, 3$          ; повторяем сколько надо
                mov     #4, R2          ; размер немасштабируемого блока линий
                sob     R5, 1$          ; и так 3 раза
                mov     #17, R2         ; затем такой размер немасштабируемого блока линий
                br      1$              ; и повторяем
; ───────────────────────────────────────────────────────────────────────────

6$:             return
; End of function Func12


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

; Звучание тонального набора
; Вход: R3 - адрес тонального набора - цепочка пар слов
;            .word длительность (0 - конец цепочки),
;            .word тон.

Func14:         mov     (R3)+, R0       ; берём очередную длительность
                beq     2$              ; 0 - конец
                mov     (R3)+, R1       ; берём очередной тон

1$:             mov     R1, R2          ; в счётчик
                mov     #320, @#177716  ; 1

                sob     R2, .           ; пауза
                mov     #220, @#177716  ; 0
                mov     R1, R2          ; в счётчик

                sob     R2, .           ; пауза
                sob     R0, 1$          ; звучим сколько надо
                br      Func14          ; и продолжим
; ───────────────────────────────────────────────────────────────────────────

2$:             return
; End of function Func14


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


Func110:        mov     #VecKbd, @#60   ; заглушки на векторы прерывания
                mov     #VecKbd, @#274
; End of function Func110


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

; Проверка на нажатие клавиши или кнопки джойстика, если нажата - выход

Func16:
2$:             mov     #33000, R1      ; задержка
                sob     R1, .
                mov     #GameStars, R2  ; R2 <- адрес массива звёзд в игре
                call    Func04          ; Прорисовка мигающих звёздочек
                                        ; Вход: R2 - адрес блока параметров:
                                        ;            .word число элементов (пар адресов)
                                        ;            .word адрес спрайта в памяти
                                        ;            .word адрес экрана
                call    IsPressed$      ; проверка на нажатие клавиши или джойстика.
                                        ; Выход: если нажато - Z=1
                                        ;        если не нажато - Z=0
                bne     2$
                return
; End of function Func16

; проверка на нажатие клавиши или джойстика.
; Выход: если нажато - Z=1
;        если не нажато - Z=0
IsPressed$:     tst     @#177714        ; джойстик нажат?
                bne     1$              ; да - выход c Z
                bit     #100, @#177716  ; клавиша нажата?
                return
1$:             sez
                return


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

; Стирание спрайта с экрана безусловное
; Вход: R1 - адрес экрана
;       R2 - высота спрайта
;       R3 - ширина спрайта в байтах

Func22:         mov     #100, R4
                sub     R3, R4
1$:             mov     R3, R5

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


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

;  Если нажата клавиша горелки, делать анимацию огня горелки

Func54:         bit     @#177716, #100  ; клавиша нажата?
                bne     1$              ; нет
                cmp     @(PC)+, (PC)+   ; да, нажата горелка?
                .word 177662
KeyFire$:       .word 40
                beq     Func24          ; да

1$:             tst     @#177714        ; нет, а джойстик нажат?
                bne     Func24          ; да - делать анимацию
                return                  ; нет
; End of function Func54


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

; Анимация огня горелки воздушного шара

Func24:         mov     @#BallonAddr, R1
                add     #2101, R1       ; адрес экрана
                mov     #SpriteFlame, R0 ; адрес спрайта
                mov     #3, R2          ; высота
                mov     #2, R3          ; ширина, байт
                com     #0
                beq     1$
                add     #6, R0          ; меняем спрайт через раз
1$:             jmp     Func06          ; Рисование методом наложения
                                        ; Вход: R0 - адрес спрайта в памяти
                                        ;       R1 - адрес экрана
                                        ;       R2 - высота спрайта
                                        ;       R3 - ширина спрайта в байтах
; End of function Func24

; ───────────────────────────────────────────────────────────────────────────
; огонь горелки воздушного шара, тут 2 спрайта,
; ширина 2, высота 3

SpriteFlame:    .word ^B0000110000110000
                .word ^B0000110000110000
                .word ^B0000111111110000
                .word ^B0000001111000000
                .word ^B0000001111000000
                .word ^B0000111111110000

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

; Анимация воздушных потоков
; Вход: R3 - адрес блока параметров

Func26:         mov     #1, R4          ; направление движения, -1 - влево экрана, 1 - вправо
                mov     #10., R5

1$:             mov     #77, R0
                mov     (R3), R1        ; берём адрес экрана
                mov     R1, R2
                bic     #177700, R2     ; получим положение в линии
                bne     4$              ; не в начале - переход
                cmp     #-1, R4         ; чё тама?
                bne     4$              ; не -1 - переход
                bis     R0, (R3)        ; иначе будет в конце линии
                br      3$              ; и туда
; ───────────────────────────────────────────────────────────────────────────

4$:             cmp     R0, R2          ; в конце линии?
                bne     5$              ; нет, где то посередине
                cmp     #1, R4          ; чё тама?
                bne     5$              ; не 1 - переход
                bic     R0, (R3)        ; иначе будет в начале линии
3$:             tst     (R3)+           ; перемещаемся к параметрам
                br      6$
; ───────────────────────────────────────────────────────────────────────────

5$:             add     R4, (R3)+       ; продолжим движение

6$:             mov     #4, R2          ; за адресом 4 параметра - байта

7$:             clrb    (R1)+           ; очищаем место в экране
                movb    (R3)+, R0
                decb    R0              ; параметр == 1?
                bne     8$              ; нет
                add     #200, R1        ; да - адрес экрана вниз
                br      9$
; ───────────────────────────────────────────────────────────────────────────

8$:             decb    R0              ; параметр == 2?
                bne     9$              ; нет
                sub     #200, R1        ; да - адрес экрана вверх

9$:             sob     R2, 7$          ; и так все 4 осмотрим
                bit     #1, R5          ; через каждую пару
                beq     2$
                neg     R4              ; смена направления движения
2$:             sob     R5, 1$          ; и так все 5 пар

                sub     #74, R3         ; это размер массива параметров,
                                        ; возвращаемся к началу
                mov     #10., R5        ; в массиве 10 элементов
                mov     #200, R4
10$:            mov     (R3)+, R1       ; берём адрес
                mov     #4, R2          ; 4 параметра

11$:            movb    #273, (R1)+     ; рисуем на экране
                movb    @#177710, R0    ; в параметр псевдо случайное число
                bicb    #375, R0
                beq     13$             ; получился 0 - ничего не делать
                cmpb    #1, R0          ; 1?
                bne     12$             ; нет
                add     R4, R1          ; адрес вниз
                br      13$
; ───────────────────────────────────────────────────────────────────────────

12$:            sub     R4, R1          ; иначе адрес вверх

13$:            movb    R0, (R3)+       ; сохраним и следующий параметр
                sob     R2, 11$         ; обработать все 4
                sob     R5, 10$         ; обработать весь массив
                return
; End of function Func26


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

; Спецэффект бегущей волны искажения на экране

Func30:         mov     #14, R4         ; тон звука
                mov     #37, R5
                mov     #40000, R0
                mov     #2, R1

                trap    32              ; Вспомогательная функция функции 30
                                        ; Вход: R0 - адрес экрана
                                        ;       R1 - ширина в байтах
                                        ;       R4 - тон звука
                tst     (R1)+

1$:             trap    32              ; Вспомогательная функция функции 30
                                        ; Вход: R0 - адрес экрана
                                        ;       R1 - ширина в байтах
                                        ;       R4 - тон звука
                tst     (R0)+
                sob     R5, 1$
                tst     -(R1)

                trap    32              ; Вспомогательная функция функции 30
                                        ; Вход: R0 - адрес экрана
                                        ;       R1 - ширина в байтах
                                        ;       R4 - тон звука
                return
; End of function Func30


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

; Вспомогательная функция функции 30
; Вход: R0 - адрес экрана
;       R1 - ширина в байтах
;       R4 - тон звука

Func32:         mov     #100, R5        ; ширина экрана
                sub     R1, R5          ; pitch
                ror     R1
                mov     R1, 32.WidthW$
                mov     #400, R2        ; высота - весь экран


1$:             mov     (PC)+, R1
32.WidthW$:     .word 1

2$:             swab    (R0)+
                sob     R1, 2$
                add     R5, R0

                mov     R4, R3
                mov     #320, @#177716
                sob     R3, .

                mov     #220, @#177716
                mov     R4, R3
                sob     R3, .

                sob     R2, 1$
                return
; End of function Func32


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

; Инициализация обходов Луны и функция 42

Func34:         mov     #20., @#MoonPass
; End of function Func34


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

; Инициализация яч. MoonAddr, MoonMovPPtr

Func42:         mov     #MoonMovParam, R0
                mov     R0, R2
                mov     R0, @#MoonMovPPtr
                mov     #3, R1

1$:             mov     #25, (R0)+
                tst     (R0)+
                sob     R1, 1$
                inc     4(R2)
                mov     #72276, @#MoonAddr
                return
; End of function Func42


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

; Очистка со сравнением, экран очищается только там, где спрайт совпадает
; Вход: R0 - адрес спрайта в памяти
;       R1 - адрес экрана
;       R2 - высота спрайта
;       R3 - ширина спрайта в байтах

Func36:         mov     #100, R4
                sub     R3, R4
1$:             mov     R3, R5

2$:             cmpb    (R0)+, (R1)
                bne     3$
                clrb    (R1)

3$:             inc     R1
                sob     R5, 2$
                add     R4, R1
                sob     R2, 1$
                return
; End of function Func36


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

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

Func40:         mov     #100, R4
                sub     R3, R4
1$:             mov     R3, R5

2$:             tstb    (R1)
                bne     3$
                movb    (R0), (R1)

3$:             inc     R0
                inc     R1
                sob     R5, 2$
                add     R4, R1
                sob     R2, 1$
                return
; End of function Func40


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

; Инициализация яч. FinishAddr и функция 46

Func44:         mov     #67137, @#FinishAddr
; End of function Func44


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

; Очистка буфера BalScrBuffer

Func46:         mov     #BalScrBuffer, R0
                mov     #<BallonSprW * BallonSprH> / 2, R1

1$:             clr     (R0)+
                sob     R1, 1$
                return
; End of function Func46


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

; Вкл/выкл фоновой музыки

Func50:         tst     (PC)+
CheckBgMusic$:  .word 0
                bne     1$              ; не надо фоновую музыку
                call    BackgrndMusic$  ; звучим музыку
                br      2$
; ───────────────────────────────────────────────────────────────────────────

1$:             mov     #30000, R0
                sob     R0, .

2$:             bit     @#177716, #100  ; клавиша нажата?
                bne     4$              ; нет
                mov     @#177662, R0    ; да, а какая?
                cmp     (PC)+, R0       ; РУС?
KeyMusicOn$:    .word 16
                bne     3$              ; нет
                clr     @#CheckBgMusic$ ; да - включаем музыку
                return

3$:             cmp     (PC)+, R0       ; ЛАТ?
KeyMusicOff$:   .word 17
                bne     4$              ; нет
                mov     R0, @#CheckBgMusic$ ; да - выключаем музыку
4$:             return
; End of function Func50


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

; Выход: R0 - признак:
;       -1 - джойстик не нажат, и горелка не нажата
;       0 - джойстик нажат и ранее была нажата клавиша горелки
;       100250/100350 - ранее была нажата клавиша горелки, а джойстик не нажат

Func60:         mov     @#177716, R0    ; прочитаем состоянием бита 6, потом проверим, снаружи
                cmp     @#177662, @#KeyFire$ ; было когда-то нажато горение горелки?
                beq     1$              ; да
                mov     #-1, R0         ; нет

1$:             tst     @#177714        ; а джойстик нажат сейчас?
                beq     2$              ; нет
                clr     R0              ; да

2$:             mov     R0, 14(SP)      ; в R0 поместим признак
                return
; End of function Func60


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

; Уменьшение счёта

Func62:         mov     #<Score+4>, R0  ; начинаем отсюда

1$:             decb    -(R0)           ; уменьшаем
                cmpb    #<'0 - 1>, (R0) ; стало меньше нуля?
                bne     2$              ; нет - выходим
                                        ; да, переходим к старшему разряду
                movb    #'9, (R0)       ; в этом разряде теперь будет 9
                                        ; и переходим к более старшему разряду
                br      1$              ; продолжаем цикл

2$:             return
; End of function Func62


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

; Инициализация счёта

Func64:         mov     #1, MoonMoves$
                mov     #"25, Score ; счёт игры - 4 байта цифр
                mov     #"00, Score + 2
                return
; End of function Func64

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

; Вывод символа на экран
; Вход: R0 - адрес данных символа
;       R1 - адрес экрана

Func66:         mov     #10., R5        ; высота символа

1$:             movb    (R0)+, R4
                mov     R0, -(SP)
                mov     #2, R2          ; ширина символа - 2 слова

2$:             mov     #4, R3          ; 4 бита -> в слово
                clr     R0
3$:             ror     R0
                ror     R0
                ror     R0
                ror     R0
                bic     #170000, R0
                asr     R4
                bcc     4$
                bis     #175000, R0

4$:             sob     R3, 3$
                mov     R0, (R1)+
                sob     R2, 2$
                add     #74, R1
                mov     (SP)+, R0
                sob     R5, 1$
                return
; End of function Func66


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

; Вывод строки на экран через буфер и скроллинг
; Вход: R3 - адрес экрана
;       R4 - адрес строки текста

Func70:         mov     #CanScrBuffer, R1
                mov     R1, R2
1$:             clr     R0
                bisb    (R4)+, R0
                beq     3$
                call    GetFontData

                trap    66              ; Вывод символа на экран
                                        ; Вход: R0 - адрес данных символа
                                        ;       R1 - адрес экрана
                add     #4, R1
                br      1$
; ───────────────────────────────────────────────────────────────────────────

3$:             mov     #10., R0

4$:             mov     R3, R4
                mov     #40, R1
5$:             clr     (R4)+
                sob     R1, 5$

                inc     @#177664
                mov     #10000, R1
                sob     R1, .
                mov     #40, R1

6$:             mov     (R2)+, (R3)+
                sob     R1, 6$
                sob     R0, 4$
                return
; End of function Func70


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

; Издать некий определённый звук

Func120:        mov     #Sound14$, R4
; End of function Func120


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

; Вывод звука с повышением тона
; Вход: R4 - адрес блока параметров
;       .word длит.
;       .word тон,тон,..., 0 - конец цепочки

Func72:         mov     (R4)+, R0       ; берём длительность
                mov     #177716, R3

1$:             mov     (R4)+, R2       ; берём тон текущей ноты
                beq     3$              ; 0 - конец

                mov     R0, R5          ; длительность текущей ноты
2$:             mov     R2, R1          ; тон
                mov     #320, (R3)      ; 1
                sob     R1, .           ; задержка

                mov     #220, (R3)      ; 0
                mov     R2, R1          ; тон
                sob     R1, .           ; задержка

                dec     R2              ; тон со временем повышается
                sob     R5, 2$          ; длительность
                br      1$
; ───────────────────────────────────────────────────────────────────────────

3$:             return
; End of function Func72


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

; Прокрутка экрана с попутной очисткой внутри рамки

Func74:         mov     #5, R5          ; скролл 5 линий

1$:             inc     @#177664
                mov     #2000, R1       ; с такой задержкой
                mov     R1, R3          ; задержка
                sob     R3, .
                sob     R5, 1$

                mov     #366, R5        ; скролл столько линий

                mov     #40501, R4      ; с попутной очисткой экрана
2$:             clrb    (R4)+
                mov     #36, R3
3$:             clr     (R4)+
                sob     R3, 3$
                clrb    (R4)+
                tst     (R4)+
                inc     @#177664
                mov     R1, R3          ; задержка
                sob     R3, .
                sob     R5, 2$

                mov     #5, R5          ; скролл 5 линий

4$:             inc     @#177664
                mov     R1, R3          ; задержка
                sob     R3, .
                sob     R5, 4$
                return
; End of function Func74



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

; Отрисовка набора мигающих звёздочек

Func76:         mov     #StarsSet1, R0  ; адрес таблицы данных
                mov     (R0)+, R1       ; там 9 элементов

1$:             mov     (R0)+, R4       ; берём адрес спрайта
                mov     (R0), R3        ; берём адрес экрана
                mov     R3, R5
                sub     #100, R3        ; на строку вверх, потому что снаружи функции делается скроллинг экрана
                bit     #140000, R3     ; мы в пределах экрана ещё?
                bne     2$              ; да
                add     #36700, R3      ; нет - корректируем адрес

2$:             mov     #9., R2         ; сперва стираем текущий спрайт со своего места,
                                        ; со сравнением, стираем только те данные - которые принадлежат спрайту

3$:             cmpb    (R5), (R4)+
                bne     4$
                clrb    (R5)

4$:             inc     R5
                cmpb    (R5), (R4)+
                bne     5$
                clrb    (R5)

5$:             add     #77, R5
                sob     R2, 3$
                mov     R3, (R0)+       ; новый адрес экрана
                sob     R1, 1$          ; и так для всех спрайтов
                mov     #StarsSet1, R2  ; Набор звёзд в заставке, с воздушным шаром
                ; а теперь вывод всех
                jmp     Func04          ; Прорисовка мигающих звёздочек
                                        ; Вход: R2 - адрес блока параметров:
                                        ;            .word число элементов (пар адресов)
                                        ;            .word адрес спрайта в памяти
                                        ;            .word адрес экрана
; End of function Func76


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

; Вывод текста очень широкими буквами
; Вход: R0 - коэффициент растяжения по вертикали
;       R1 - адрес экрана
;       R5 - адрес текста

Func100:        mov     R0, 100.ScaleY$
                mov     #1160, R2
1$:             add     #1200, R2
                sob     R0, 1$
                mov     R2, 100.Offs$
                mov     2(SP), R5       ; берём адрес текста

2$:             clr     R0
                bisb    (R5)+, R0
                beq     9$
                mov     R5, -(SP)
                call    GetFontData

                mov     #10., R2

4$:             mov     #8., R3
                movb    (R0)+, R4

5$:             clr     R5
                asr     R4
                bcc     6$
                mov     #52525, R5

6$:             mov     R5, (R1)+
                sob     R3, 5$

                mov     (PC)+, R5
100.ScaleY$:    .word   0
                mov     R1, R4

7$:             sub     #20, R4
                add     #60, R1
                mov     #8., R3

8$:             mov     (R4)+, (R1)+
                sob     R3, 8$
                sob     R5, 7$
                add     #60, R1

                sob     R2, 4$
                sub     (PC)+, R1
100.Offs$:     .word    0
                mov     (SP)+, R5
                br      2$
; ───────────────────────────────────────────────────────────────────────────

9$:             return
; End of function Func100


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

; Очистка экрана горизонтальными линиями сверху и снизу

Func102:        mov     #125252, R4
                mov     #77, R5
                mov     #40000, R0
                mov     #100000, R1

1$:             mov     #200, R2

2$:             clr     (R0)+
                clr     -(R1)
                sob     R2, 2$
                tst     R5
                beq     4$
                mov     #200, R2

3$:             mov     R4, (R0)+
                mov     R4, -(R1)
                sob     R2, 3$
                add     #400, R1
                sub     #400, R0
                mov     #6000, R3
                sob     R3, .

                sob     R5, 1$
                br      1$
; ───────────────────────────────────────────────────────────────────────────

4$:             return
; End of function Func102


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

; вывод строки на экран
; Вход: R1 - адрес экрана
;       R4 - адрес строки, конец строки - 0
; Выход: R4 - адрес за концом строки

Func104:        clr     R0
                bisb    (R4)+, R0
                beq     1$
                call    GetFontData
                trap    66              ; Вывод символа на экран
                                        ; Вход: R0 - адрес данных символа
                                        ;       R1 - адрес экрана
                add     #4, R1
                br      Func104         ; и так всю строку
1$:             mov     R4, 4(SP)
                return
; End of function Func104


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

; Анимация букв
; Вход: R0 - адрес данных букв
;       R1 - адрес экрана
;       R2 - масштаб по высоте
; Выход: R1 - адрес экрана после действия

Func106:        mov     R2, -(SP)
                mov     #10, R5

1$:             mov     #8., R3         ; в байте 8 бит
                movb    (R0)+, R4

2$:             clr     R2
                ror     R4
                bcc     3$
                movb    @#AnimLetColor, R2 ; цвет анимированных букв

3$:             movb    R2, (R1)+
                sob     R3, 2$

                mov     R1, R2
                mov     (SP), R3

4$:             sub     #10, R2
                add     #70, R1
                mov     (R2)+, (R1)+
                mov     (R2)+, (R1)+
                mov     (R2)+, (R1)+
                mov     (R2)+, (R1)+
                sob     R3, 4$
                add     #70, R1
                sob     R5, 1$
                tst     (SP)+
                mov     #AnimLetColor, R4
                inc     (R4)            ; меняем цвет анимированных букв
                beq     5$
                dec     (R4)

5$:             add     #52525, (R4) ; меняем цвет анимированных букв
                mov     R1, 12(SP)
                return
; End of function Func106


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

; Проверка на нажатие кнопки паузы
; и если да, то пауза

Func112:        bit     @#177716, #100  ; проверим нажатие клавиши
                bne     112.2$          ; нет - выход
F112.1$:        cmp     @(PC)+, (PC)+   ; нажали кнопку паузы?
                .word 177662
KeyPause$:      .word '1
                bne     112.2$          ; нет - выходим
                                        ; да - пауза
                call    Func16          ; Проверка на нажатие клавиши или кнопки джойстика, если нажата - выход
                tst     @#177714        ; если нажали кнопку джойстика,
                beq     F112.1$         ; а если клавиатуру - то проверим, не кнопку ли паузы
112.2$:         return                  ; то просто выходим
; End of function Func112

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

; Вывод на экран строк об авторе, копирайт,
; и сделать остальной текст синим.

Func114:        call    OutAuthorInfo   ; вывод  информации об авторе
                mov     #42302, R0
                mov     #333, R3

1$:             mov     #36, R5

2$:             bic     #125252, (R0)+
                sob     R5, 2$
                add     #4, R0
                sob     R3, 1$
                return
; End of function Func114

; вывод  информации об авторе

OutAuthorInfo:  mov     #strAbout, R4
                mov     #datAbout, R3
                call    DrawText
                mov     #41004, R1
                mov     #strCopyright, R4 ; "(C)   BIL corp"
                trap    104             ; вывод строки на экран
                                        ; Вход: R1 - адрес экрана
                                        ;       R4 - адрес строки, конец строки - 0
                                        ; Выход: R4 - адрес за концом строки
                return

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

; Звук, ждать нажатия клавиши или джойстика, звук,
; очистка экрана с прокруткой

Func116:        mov     #Sound12$, R4
                trap    72              ; Вывод звука с повышением тона
                                        ; Вход: R4 - адрес блока параметров
                                        ;       .word длит.
                                        ;       .word тон,тон,..., 0 - конец цепочки
                call    CheckKey$       ; проверка нажатия любой клавиши или джойстика
                                        ; если что-то нажато - выход
                                        ; иначе- ждём в цикле
                mov     #Sound13$, R4
                trap    72              ; Вывод звука с повышением тона
                                        ; Вход: R4 - адрес блока параметров
                                        ;       .word длит.
                                        ;       .word тон,тон,..., 0 - конец цепочки
                jmp     Func74          ; Прокрутка экрана с попутной очисткой внутри рамки

; End of function Func116


; проверка нажатия любой клавиши или джойстика
; если что-то нажато - выход
; иначе- ждём в цикле
CheckKey$:
1$:             bit     #100, @#177716
                beq     2$
                tst     @#177714
                beq     1$
2$:             return


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

; Передвинуть пушку
; Вход: R1 - текущий адрес пушки
;       R4 - приращение адреса

Func122:        mov     R1, @#CannonAddrDraw ; адрес экрана пушки
                mov     #CanScrBuffer, R0 ; буфер сохранения экрана под пушкой
                mov     #27, R2         ; восстанавливаем экран

1$:             mov     #CannonSprW, R3

2$:             movb    (R0)+, (R1)+
                sob     R3, 2$
                add     #CannonSprPitch, R1
                sob     R2, 1$
                add     R4, @#CannonAddrDraw ; следующий адрес пушки
; End of function Func122


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

; Отобразить пушку

Func124:        mov     #CanScrBuffer, R0 ; буфер сохранения экрана под пушкой
                mov     @#CannonAddrDraw, R1 ; адрес экрана пушки
                mov     R1, R4
                mov     #27, R2         ; сохраняем экран в буфере

1$:             mov     #CannonSprW, R3

2$:             movb    (R4)+, (R0)+
                sob     R3, 2$
                add     #CannonSprPitch, R4
                sob     R2, 1$
                mov     #CannonSprMask, R0
                mov     R1, -(SP)       ; адрес экрана пушки
                ; рисуем пушку
                mov     #CannonSprW, R3
                mov     #6, R2
                trap    10              ; Стирание методом побитовой очистки
                                        ; Вход: R0 - адрес спрайта в памяти
                                        ;       R1 - адрес экрана
                                        ;       R2 - высота спрайта
                                        ;       R3 - ширина спрайта в байтах
                add     #600, R1
                add     #24, R0
                mov     #2, R2
                mov     #4, R5
3$:             trap    10              ; Стирание методом побитовой очистки
                                        ; Вход: R0 - адрес спрайта в памяти
                                        ;       R1 - адрес экрана
                                        ;       R2 - высота спрайта
                                        ;       R3 - ширина спрайта в байтах
                add     #200, R1
                sob     R5, 3$
                add     #12, R0
                mov     #11, R2
                trap    10              ; Стирание методом побитовой очистки
                                        ; Вход: R0 - адрес спрайта в памяти
                                        ;       R1 - адрес экрана
                                        ;       R2 - высота спрайта
                                        ;       R3 - ширина спрайта в байтах
                mov     #CannonSprite, R0
                mov     (SP)+, R1
                mov     #CannonSprW, R3
                mov     #6, R2          ; рисуем сперва 6 строк
                trap    6               ; Рисование методом наложения
                                        ; Вход: R0 - адрес спрайта в памяти
                                        ;       R1 - адрес экрана
                                        ;       R2 - высота спрайта
                                        ;       R3 - ширина спрайта в байтах
                add     #600, R1
                add     #24, R0
                mov     #2, R2          ; затем 2 строки повторяем
                mov     #4, R5
4$:             trap    6               ; Рисование методом наложения
                                        ; Вход: R0 - адрес спрайта в памяти
                                        ;       R1 - адрес экрана
                                        ;       R2 - высота спрайта
                                        ;       R3 - ширина спрайта в байтах
                add     #200, R1
                sob     R5, 4$
                add     #12, R0
                mov     #11, R2         ; затем остальные 9 строк
                trap    6               ; Рисование методом наложения
                                        ; Вход: R0 - адрес спрайта в памяти
                                        ;       R1 - адрес экрана
                                        ;       R2 - высота спрайта
                                        ;       R3 - ширина спрайта в байтах
                return
; End of function Func124


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

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

Func126:        mov     #500, R0
                mov     @#CannonAddr, R1
                sub     #1076, R1
                mov     #7, R2

1$:             movb    (R1)+, (R0)+    ; сохраним содержимое экрана в буфере
                add     #77, R1
                sob     R2, 1$
                mov     #7, R2
                sub     #700, R1
                mov     #ShootSprite, R0 ; нарисуем выстрел

2$:             movb    (R0)+, (R1)+
                add     #77, R1
                sob     R2, 2$
                mov     #Sound15$, R4
                trap    72              ; Вывод звука с повышением тона
                                        ; Вход: R4 - адрес блока параметров
                                        ;       .word длит.
                                        ;       .word тон,тон,..., 0 - конец цепочки
                sub     #700, R1        ; и восстановим экран
                mov     #7, R2
                mov     #500, R0

3$:             movb    (R0)+, (R1)+
                add     #77, R1
                sob     R2, 3$
                return
; End of function Func126


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

; Полёт пули вверх
; Вход: R1 - адрес экран
;       R4 - адрес элемента в буфере + 4

Func130:        mov     #BulletUpSprMask, R0
                mov     #7, R2          ; стираем пульку

1$:             clrb    (R1)+
                add     #77, R1
                sob     R2, 1$
                mov     #7, R2
                mov     #1, R3
                sub     #4, R4          ; адрес текущего элемента в массиве
                sub     #300, (R4)      ; изменяем адрес пули
                bit     #137000, R1     ; пуля до верха долетела?
                bne     2$              ; нет ещё
                dec     (R4)+           ; да - смещаем адрес, чтобы не прямо на том же месте было
                com     (R4)+           ; меняем направление движения
                return
; ───────────────────────────────────────────────────────────────────────────

2$:             mov     (R4)+, R1       ; новый адрес пули
                trap    10              ; Стирание методом побитовой очистки
                                        ; Вход: R0 - адрес спрайта в памяти
                                        ;       R1 - адрес экрана
                                        ;       R2 - высота спрайта
                                        ;       R3 - ширина спрайта в байтах
                sub     #BulletUpSprMask - BulletUpSprite, R0
                trap    6               ; Рисование методом наложения
                                        ; Вход: R0 - адрес спрайта в памяти
                                        ;       R1 - адрес экрана
                                        ;       R2 - высота спрайта
                                        ;       R3 - ширина спрайта в байтах
                jmp     HitCheck
; End of function Func130

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

; Полёт пули вниз
; Вход: R1 - адрес экран
;       R4 - адрес элемента в буфере + 4

Func132:        mov     #BulletDnSprMask+3, R0 ; тут у нас не вся пулька а только её часть
                mov     #4, R2

1$:             clrb    (R1)+
                add     #77, R1
                sob     R2, 1$
                mov     #4, R2          ; высота спрайта
                mov     #1, R3          ; ширина спрайта
                sub     #4, R4          ; адрес текущего элемента в массиве
                cmp     #71000, R1      ; до низа долетели?
                bgt     2$              ; нет
                                        ; да
                jmp     FallDnBullet    ; Обработка падения пули, она просто падает без последствий
                                        ; Вход: R4 - адрес текущего элемента в массиве
; ───────────────────────────────────────────────────────────────────────────

2$:             add     #200, (R4)      ; новый адрес пули
                mov     (R4)+, R1       ; рисуем
                trap    10              ; Стирание методом побитовой очистки
                                        ; Вход: R0 - адрес спрайта в памяти
                                        ;       R1 - адрес экрана
                                        ;       R2 - высота спрайта
                                        ;       R3 - ширина спрайта в байтах
                sub     #BulletDnSprMask - BulletDnSprite, R0
                jmp     Func06          ; Рисование методом наложения
                                        ; Вход: R0 - адрес спрайта в памяти
                                        ;       R1 - адрес экрана
                                        ;       R2 - высота спрайта
                                        ;       R3 - ширина спрайта в байтах
; End of function Func132


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

; Прорисовка комет, летящих слева направо
; Вход: R4 - адрес текущего элемента массива

Func134:        mov     (R4)+, R0       ; это адрес спрайта
                mov     (R4), R1        ; это адрес экрана
                ; стираем комету с текущего места
                mov     #CometSprH, R2

1$:             mov     #CometSprW, R3

2$:             clrb    (R1)+
                sob     R3, 2$
                add     #CometSprPitch, R1
                sob     R2, 1$
                trap    136             ; Проверка на попадания кометы в шара
                                        ; Вход R4 - адрес текущего элемента массива комет
                add     #77, (R4)       ; двигаем комету
                mov     (R4), R1
                mov     R1, R2
                bic     #177700, R2     ; до левого края дошла?
                cmp     #77, R2
                beq     F134Exit        ; да - всё
; ───────────────────────────────────────────────────────────────────────────
                ; рисуем комету
3$:             mov     #CometSprH, R2

4$:             mov     #CometSprW, R3

5$:             movb    (R0)+, (R1)+
                sob     R3, 5$
                add     #CometSprPitch, R1
                sob     R2, 4$
                cmp     #SpriteCometLEnd, R0 ; массив кончился?
                bne     6$              ; нет
                mov     #SpriteCometL1, -(R4) ; снова делаем начальную
                return
; ───────────────────────────────────────────────────────────────────────────

6$:             add     #CometSprW*CometSprH, -(R4) ; переходим к следующему спрайту
                return

F134Exit:       clr     (R4)            ; да - всё нету её, улетела
                clr     -(R4)
                return
; End of function Func134

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

; Проверка на попадания кометы в шара
; Вход R4 - адрес текущего элемента массива комет

Func136:        mov     (R4), R1
                mov     @#BallonAddr, R2       ; адрес вывода спрайта воздушного шара
                mov     R1, R3
                add     #1106, R3
                cmp     R3, R2
                ble     0ret$

1$:             mov     R2, R3
                add     #3304, R3
                cmp     R1, R3
                bge     0ret$

2$:             bic     #177700, R1
                bic     #177700, R2
                mov     R1, R3
                add     #5, R3
                cmp     R3, R2
                ble     0ret$

3$:             mov     R2, R3
                add     #4, R3
                cmp     R1, R3
                bge     0ret$

4$:             mov     #Sound22$, R4
                call    Func72          ; Вывод звука с повышением тона
                                        ; Вход: R4 - адрес блока параметров
                                        ;       .word длит.
                                        ;       .word тон,тон,..., 0 - конец цепочки
                tst     @#CometHitCount ; предел прочности достигнут?
                beq     5$              ; да, всё, подбили
                mov     #F134Exit, 16(SP) ; выходом из функции будет переход туда, а там ещё один return на уровень выше
                tst     @#CometHitCount ; нет ещё, уменьшаем счётчик попаданий  ### это для бессмертия
                ;dec     @#CometHitCount ; нет ещё, уменьшаем счётчик попаданий  ### это для честной игры
0ret$:          return
; ───────────────────────────────────────────────────────────────────────────

5$:             jmp     GoFailS$
; End of function Func136


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

; Прорисовка комет, летящих справа налево
; Вход: R4 - адрес текущего элемента массива

Func140:        mov     (R4)+, R0
                mov     (R4), R1
                mov     #CometSprH, R2

1$:             mov     #CometSprW, R3

2$:             clrb    (R1)+
                sob     R3, 2$
                add     #CometSprPitch, R1
                sob     R2, 1$
                mov     (R4), R1
                trap    136             ; Проверка на попадания кометы в шара
                                        ; Вход R4 - адрес текущего элемента массива комет
                mov     R1, R2
                bic     #177700, R2
                cmp     #72, R2
                beq     F134Exit

3$:             add     #101, (R4)
                mov     (R4), R1
                mov     #CometSprH, R2

4$:             mov     #CometSprW, R3

5$:             movb    (R0)+, (R1)+
                sob     R3, 5$
                add     #CometSprPitch, R1
                sob     R2, 4$
                cmp     #SpriteCometREnd, R0
                bne     6$
                mov     #SpriteCometR1, -(R4)
                return
; ───────────────────────────────────────────────────────────────────────────

6$:             add     #CometSprW*CometSprH, -(R4)
                return
; End of function Func140

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

; Просмотр массива на счёт врезавшихся друг в друга встречно летящих комет,
; если они врезались друг в друга - взаимоуничтожаются
; Вход: R0 - адрес буфера комет + 2

Func142:        mov     #CometsNum4, R5

1$:             mov     R5, R1
                mov     R0, R4          ; адрес текущего элемента

2$:             add     #4, R4
                trap    144             ; проверка на коллизию встречно летящих комет
                                        ; если они врезались друг в друга - взаимоуничтожаются
                                        ; Вход: R0 - адрес эл-та 1
                                        ;       R4 - адрес эл-та 2
                sob     R1, 2$
                add     #4, R0
                sob     R5, 1$
                return
; End of function Func142


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

; проверка на коллизию встречно летящих комет
; если они врезались друг в друга - взаимоуничтожаются
; Вход: R0 - адрес эл-та 1
;       R4 - адрес эл-та 2
Func144:        mov     (R0), R2        ; адрес экрана эл-та 1
                beq     1$              ; 0 - там пусто, нечего делать
                mov     (R4), R1        ; адрес экрана эл-та 2
                beq     1$              ; 0 - там пусто, нечего делать
                mov     R1, R3          ; сперва сравним, на одной ли высоте, пересекаются?
                add     #1106, R3
                cmp     R3, R2
                ble     1$

2$:             mov     R2, R3
                add     #1106, R3
                cmp     R1, R3
                bge     1$

3$:             bic     #177700, R1     ; теперь сравним  по координате X
                bic     #177700, R2
                mov     R1, R3
                add     #6, R3
                cmp     R3, R2
                ble     1$

4$:             mov     R2, R3
                add     #6, R3
                cmp     R1, R3
                bge     1$

5$:             mov     (R0), R1        ; если пересеклись
                mov     (R4), R2
                clr     (R0)            ; то взаимоуничтожаются
                clr     -(R0)
                clr     (R4)
                clr     -(R4)
                mov     #CometSprH, R3  ; убираем с экрана

6$:             mov     #CometSprW, R4

7$:             clrb    (R1)+
                clrb    (R2)+
                sob     R4, 7$
                add     #CometSprPitch, R1
                add     #CometSprPitch, R2
                sob     R3, 6$
                mov     #Sound22$, R4
                jmp     Func72          ; Вывод звука с повышением тона
                                        ; Вход: R4 - адрес блока параметров
                                        ;       .word длит.
                                        ;       .word тон,тон,..., 0 - конец цепочки
1$:             return
; End of function Func144


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

; Отображаем бошку, проверяем время её жизни и встречу с воздушным шаром

Func146:        mov     @#HeadAddr, R1
                cmp     #37777, R1    ; адрес в пределах экрана?
                bgt     1$
                cmp     #77777, R1
                blt     1$
                ; да, используем его
                mov     #BoshkaSprH, R2
                mov     #BoshkaSprW, R3
                trap    22              ; Стирание спрайта с экрана безусловное
                                        ; Вход: R1 - адрес экрана
                                        ;       R2 - высота спрайта
                                        ;       R3 - ширина спрайта в байтах
                dec     @#HeadTimeLife  ; ещё живёт?
                bne     2$              ; да
                ; нет
                add     #701, R1        ; её центр
                mov     R1, HeadBlowCenter ; сохраним туда
3$:             clr     @#HeadAddr      ; всё бошки нет, она взорвалась

1$:             return
; ───────────────────────────────────────────────────────────────────────────
                ; нарисуем в новом месте
2$:             mov     #SpriteBoshka, R0
                add     #400, R1        ; бошка просто спускается вниз вертикально
                mov     R1, @#HeadAddr
                trap    6               ; Рисование методом наложения
                                        ; Вход: R0 - адрес спрайта в памяти
                                        ;       R1 - адрес экрана
                                        ;       R2 - высота спрайта
                                        ;       R3 - ширина спрайта в байтах
                ; проверка на встречу воздушного шара с башкой
                mov     @#BallonAddr, R2
                mov     R1, R3
                add     #1503, R3
                cmp     R3, R2
                ble     1$

                mov     R2, R3
                add     #3304, R3
                cmp     R1, R3
                bge     1$

                bic     #177700, R1
                bic     #177700, R2
                mov     R1, R3
                add     #3, R3
                cmp     R3, R2
                ble     1$

                mov     R2, R3
                add     #4, R3
                cmp     R1, R3
                bge     1$
                ; фатально - встречаться нельзя
                ;jmp     GoFailS$        ; ### это для честной игры
                br      3$              ; ### это для бессмертия
; End of function Func146


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

; Прорисовка разлетающихся осколков от башки
; и проверка на попадание в воздушный шар

Func150:        mov     #HeadScratchBuffer, R0
                mov     R0, R2
                mov     #HeadBulletNum, R1

1$:             mov     (R2)+, R3       ; адрес пульки
                beq     3$              ; нету
                mov     #3, R4          ; есть - стираем с экрана

2$:             clrb    (R3)
                add     #100, R3
                sob     R4, 2$
3$:             sob     R1, 1$          ; весь массив

                mov     #HeadBlowCenter, R2 ; эпицентр
                mov     (R2), R3        ; берём адрес
                beq     5$              ; нету - игнорируем
                mov     #HeadBulletNum, R1
                clr     (R2)+           ; адрес стираем, чтоб потом на метку 5$ переходить

4$:             mov     R3, (R2)+       ; заполняем массив пулек начальным адресом
                sob     R1, 4$
                mov     #Sound24$, R4   ; звук взрыва башки
                trap    72              ; Вывод звука с повышением тона
                                        ; Вход: R4 - адрес блока параметров
                                        ;       .word длит.
                                        ;       .word тон,тон,..., 0 - конец цепочки
5$:             mov     #HeadBulletNum, R1
                ;mov     #HeadScratchBuffer, R0
                mov     #HdScrtchOffsTbl, R2 ; массив приращений адресов

6$:             mov     (R0)+, R3       ; пулька есть?
                beq     10$             ; нету
                ; проверим не вышла ли за пределы экрана
                ; если улетела вверх, появляется снизу экрана
                ; если вниз - то сверху экрана
                cmp     #40400, R3
                blt     7$
                add     #23000, R3
                br      8$

7$:             cmp     #65000, R3
                bgt     8$
                sub     #23000, R3

8$:             add     (R2)+, R3       ; добавим приращение
                mov     R3, -2(R0)      ; вот новый адрес
                mov     #SpiteHeadBullet, R4 ; рисуем пульку
                mov     #HeadBulletSprH, R5

9$:             movb    (R4)+, (R3)
                add     #100, R3
                sob     R5, 9$
                sub     #200, R3        ; проверяем, попали в шар?
                mov     @#BallonAddr, R4
                cmp     R3, R4
                blt     10$
                sub     #100, R3
                add     #3304, R4
                cmp     R3, R4
                bgt     10$
                bic     #177700, R4
                bic     #177700, R3
                cmp     R3, R4
                bgt     10$
                sub     #4, R4
                cmp     R3, R4
                bge     11$

10$:            sob     R1, 6$
                return
; ───────────────────────────────────────────────────────────────────────────

11$:            tst     @#CannonHitCount ; Попали!  ### это для бессмертия
                ;dec     @#CannonHitCount ; Попали!  ### это для честной игры
                beq     13$             ; жизни кончились? - переход
                mov     -(R0), R3       ; нет ещё
                mov     #3, R4

12$:            clrb    (R3)
                add     #100, R3
                sob     R4, 12$
                clr     (R0)+
                mov     #Sound25$, R4
                trap    72              ; Вывод звука с повышением тона
                                        ; Вход: R4 - адрес блока параметров
                                        ;       .word длит.
                                        ;       .word тон,тон,..., 0 - конец цепочки
                br      10$
; ───────────────────────────────────────────────────────────────────────────
                ; всё, начинаем сначала
13$:            jmp     GoFailS$
; End of function Func150


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

; Проигрыш музыки
; Вход: R4 - адрес массива мелодии

Func152:        mov     R4, R5
                mov     R4, word_32312

1$:             mov     (R5), R2
                bit     #1760, (R5)
                beq     9$
                bic     #176000, R2
                mov     word_32314, R1
                mov     R1, R0
                bit     #2000, (R5)
                bne     2$
                bit     #4000, (R5)
                beq     3$
                asr     R0

2$:             asr     R0
                asr     R0
                sub     R0, R1
                asl     R0
                br      4$
; ───────────────────────────────────────────────────────────────────────────

3$:             mov     #1, R0

4$:             clr     R4

5$:             inc     R4
                sub     R2, R1
                bpl     5$
                mov     (R5), R3
                bic     #107777, R3
                swab    R3
                asrb    R3
                asrb    R3
                asrb    R3
                asrb    R3

6$:             asl     R4
                asl     R0
                sob     R3, 6$
                mov     (R5)+, R3
                bic     #77777, R3
                beq     7$
                mov     R4, R3
                asr     R3
                add     R3, R4

7$:             mov     R2, R1
                mov     #320, @#177716
                sob     R1, .

                mov     R2, R1
                mov     #220, @#177716
                sob     R1, .

                sob     R4, 7$

                sob     R0, .

8$:             cmp     #70007, (R5)
                bne     1$
18$:            return
; ───────────────────────────────────────────────────────────────────────────

9$:             bit     #100000, (R5)+
                beq     12$
                bic     #170000, R2
                clr     R3

10$:            add     #1000, R3
                sob     R2, 10$
                mov     R3, word_32314

11$:            br      1$
; ───────────────────────────────────────────────────────────────────────────

12$:            bit     #10, R2
                bne     15$
                bic     #170070, R2
                mov     word_32314, R3
                asr     R3
                asr     R3

13$:            asl     R3
                sob     R2, 13$
                mov     #7, R2

14$:            mov     R3, R1
                sob     R1, .
                sob     R2, 14$
                br      8$
; ───────────────────────────────────────────────────────────────────────────

15$:            cmp     #70011, R2
                bne     17$
                tst     word_32310
                beq     16$
                clr     word_32310
                br      8$
; ───────────────────────────────────────────────────────────────────────────

16$:            inc     word_32310
                mov     word_32312, R5
                br      11$
; ───────────────────────────────────────────────────────────────────────────

17$:            mov     R5, word_32312
                br      11$
; End of function Func152

; ───────────────────────────────────────────────────────────────────────────
word_32310:     .word 0
word_32312:     .word 0
word_32314:     .word 4000
; ───────────────────────────────────────────────────────────────────────────


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

; выводит GAME 2

Func154:        mov     @#F$Screen, R5  ; адрес начала экрана

1$:             clr     (R5)+           ; очищаем эран
                tst     R5
                bpl     1$
                mov     #1, 154.ScaleY$ ; масштаб по высоте символа
                mov     @#F$GameAddr, R1 ; адрес начала вывода

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

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

4$:             mov     (PC)+, R4
154.ScaleY$:    .word 0

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

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

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

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

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

10$:            mov     #36, R4
                mov     R4, R3
                mov     #320, @#177716
                sob     R3, .
                mov     #220, @#177716
                sob     R4, .
                sob     R0, 10$

                cmp     @#F$MaxScale, 154.ScaleY$ ; до предела дошли?
                bne     2$
                mov     @#F$GmNmAddr, R1 ; адрес вывода
                mov     @#F$GameNum, R0 ; что выводить
                swab    R0              ; старший байт есть?
                beq     11$             ; нету
                call    DrawDigit       ; есть - вывод цифры
11$:            swab    R0              ; теперь младший
; End of function Func154


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


DrawDigit:      bic     #177700, R0
                asl     R0
                mov     R0, R2
                asl     R0
                asl     R0
                add     R0, R2
                add     #FONT + <'0 - 40>*10. + 1, R2
                mov     @#F$GmNmColor, R0
2$:             mov     @#F$Cycles, R3

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

4$:             ror     R4
                bcs     7$
                cmp     (R1)+, (R1)+
                br      6$
; ───────────────────────────────────────────────────────────────────────────

7$:             tst     (R1)+
                bne     5$
                mov     R0, -2(R1)

5$:             tst     (R1)+
                bne     6$
                mov     R0, -2(R1)

6$:             sob     R5, 4$
                add     #40, R1
                sob     R3, 3$
                tstb    (R2)+
                bne     2$
                mov     @#F$GmNmAddr, R1
                add     #40, R1
                return
; End of function DrawDigit


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

; Вывод скроллом текста, описания к игре 2

Func156:        mov     @#F$ScrAddr, R4 ; адрес экрана
                mov     R4, R1          ; адрес в регистр, где он используется
                mov     #40, R2

1$:             clr     (R4)+           ; очищаем строку экрана
                sob     R2, 1$
                mov     @#F$DataAddr, R5 ; адрес данных
                clr     R4
                bisb    (R5)+, R4       ; берём очередной байт
                beq     3$              ; если 0, то пропустим
                ; если не 0, то это число повторов
2$:             call    F156.MovAddrDn  ; очистка следующей строки экрана и скроллинг
                sob     R4, 2$          ; скроллим экран на заданное кол-во строк

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

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

5$:             ; это код символа
                call    GetFontData
                mov     R0, (R1)+       ; адрес данных символа сохраним в буфере
                sob     R3, 4$          ; и так всю строку
                clr     (R1)+           ; конец строки
                mov     R5, @#F$DataAddr ; указатель на данные сохраним

                mov     @#F$ScrAddr, R1 ; адрес экрана
                mov     #10., R5        ; это высота символа

7$:             mov     R5, -(SP)
                mov     #300, R0        ; адрес буфера
                add     @#F$Tmp, R1     ; сместимся к месту вывода строки

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

9$:             mov     #2, R4          ; два бита -> в байт
                clr     R5
10$:            rorb    R5
                rorb    R5
                rorb    R5
                rorb    R5
                bicb    #360, R5
                rorb    R2
                bcc     11$
                bisb    @#F$ColorMask, R5        ; маска цвета букв

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

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

13$:            call    F156.ScrlUp     ; Проверка, на границы экрана, чтоб адрес за них не вышел и скролл на 1 строку
                mov     (SP)+, R5
                sob     R5, 7$          ; и так все 8 строк символа
                mov     R1, @#F$ScrAddr ; новый адрес сохраним
                br      Func156         ; и всё сначала
; End of function Func156


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

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

F156.MovAddrDn: add     #100, R1        ; на строку экрана вниз
; End of function F156.MovAddrDn


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

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

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

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

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

3$:             return
; End of function F156.ScrlUp


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

; Вывод символа на экран
; Вход: R2 - код символа
;       @#F$ScrAddr - адрес экрана, куда выводить
;       @#F$YScale - масштаб по высоте
;       @#F$ColorMask - маска цвета

Func160:        mov     @#F$ScrAddr, R1
                bic     #177400, R2
                asl     R2
                mov     R2, R0
                asl     R2
                asl     R2
                add     R2, R0
                add     #FONT-240+1, R0

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

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

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

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


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

; Вывод текста сложного формата на экран
; Вход: @#F$DataAddr2 - адрес массива данных
;       @#F$ScrAddr - адрес экрана, куда выводить

Func162:        mov     @#F$DataAddr2, R0 ; адрес массива

1$:             clr     R1
                bisb    (R0)+, R1       ; берём байт
                mov     R1, @#F$YScale  ; это масштаб по высоте
                clr     R1
                bisb    (R0)+, R1       ; берём второй байт
                mov     R1, @#F$ColorMask ; это маска цвета

2$:             clr     R2
                bisb    (R0)+, R2       ; берём следующий байт
                bne     3$              ; если 0 - то конец
                return
; ───────────────────────────────────────────────────────────────────────────

3$:             cmp     #320, R2        ; если 320,
                beq     1$              ; то надо снова брать параметры
                cmp     #377, R2        ; если 377
                bne     6$
                clr     R1
                bisb    (R0)+, R1       ; то берём следующий байт
                swab    R1              ; умножаем на 100
                ror     R1
                asr     R1
                add     @#F$ScrAddr, R1 ; прибавляем адрес экрана
                bis     #77, R1
                inc     R1              ; переход в начало следующей строки
                mov     R1, @#F$ScrAddr ; новый адрес экрана
5$:             br      2$              ; и идём за новыми данными
; ───────────────────────────────────────────────────────────────────────────

6$:             cmp     R2, #320        ; если данные меньше 320
                ble     8$              ;  переход, выведем символ
                sub     #320, R2        ; иначе, вычитаем 320
                add     R2, @#F$ScrAddr ;  и это смещение в строке
7$:             br      2$              ; и идём за новыми данными
; ───────────────────────────────────────────────────────────────────────────

8$:             trap    160             ; выводим символ
                add     #10, @#F$ScrAddr ; ширина - фиксированная
                br      2$
; End of function Func162

; ///////////////////////////////////////////////////////////////////////////
; Подпрограммы анимации заставки

; рисуем спускающийся воздушный шар
Splash1:        sub     #2, @#177664    ; начальная позиция скроллинга
                mov     #BallonSprEnd, R0 ; конечный адрес спрайта воздушного шара
                mov     #77756, R1      ; адрес экрана
                mov     #34, R5

1$:             mov     #2, R2          ; ширина спрайта 2 слова, 4 байта

2$:             mov     #8., R3         ; в слове 8 двухбитий
                mov     -(R0), R4       ; берём очередное слово

3$:             clr     (R1)            ; по текущему адресу пока 0
                asl     R4              ; смотрим очередной бит
                bcc     4$              ; если 0 - то и на экране 0
                bis     #125252, (R1)   ; иначе - зелёное слово

4$:             asl     R4              ; смотрим очередной бит
                bcc     5$              ; если 0 - то переход
                bis     #52525, (R1)    ; иначе - синее слово

5$:             tst     -(R1)           ; вот, таким образом мы 2 бита расширяем в слово
                                        ; переходим к следующему слову
                sob     R3, 3$          ; и так все 16 бит
                sob     R2, 2$          ; и так всю ширину спрайта
                tst     (R1)+           ; возвращаем назад указатель, он сейчас указывает на
                                        ; начало строки, которую надо продублировать
                                        ; её ширина - 20 слов
                mov     #10, R4         ; масштаб одной строки спрайта
                mov     R1, R2

6$:             add     #40, R2         ; это конец строки источника
                sub     #40, R1         ; это конец строки приёмника
                trap    76              ; рисуем мигающие звёздочки
                dec     @#177664        ; скролл
                bis     #1000, @#177664
                mov     #20, R3         ; дублируем строку

7$:             mov     -(R2), -(R1)
                sob     R3, 7$
                sob     R4, 6$          ; и так сколько надо
                trap    76              ; рисуем мигающие звёздочки
                dec     @#177664        ; снова скролл
                bis     #1000, @#177664
                sub     #42, R1         ; корректируем адрес
                sob     R5, 1$          ; и так пока не нарисуем весь
; тут слегка замедляется, для эффекта
                mov     #2, R5

8$:             dec     @#177664        ; скролл
                bis     #1000, @#177664
                mov     #14000, R1      ; пауза
                sob     R1, .
                sob     R5, 8$
; теперь он спускается вниз за экран
                mov     #400, R5
                mov     #100000, R1     ; делается обычная очистка экрана со скроллингом

9$:             mov     #40, R2

10$:            clr     -(R1)
                sob     R2, 10$
                dec     @#177664        ; скролл
                bis     #1000, @#177664
                mov     #1000, R2
                trap    76              ; рисуем мигающие звёздочки
                sob     R2, .
                sob     R5, 9$          ; пока весь не исчезнет

                mov     #Sound1$, R4
                trap    72              ; Вывод звука с повышением тона
                                        ; Вход: R4 - адрес блока параметров
                                        ;       .word длит.
                                        ;       .word тон,тон,..., 0 - конец цепочки
                trap    102             ; Очистка экрана горизонтальными линиями сверху и снизу
                return

; теперь снизу выезжает посадочная платформа
Splash2:        mov     #77630, 0PlatformScrAddr$ ; начальный адрес экрана

1$:             mov     (PC)+, R1
0PlatformScrAddr$:.word 70230

                mov     #PlatformSprH, R5
                mov     #PlatformSprite, R0 ; адрес спрайта

2$:             mov     #PlatformSprW, R2 ; ширина спрайта

3$:             mov     #4, R3          ; в байте 4 двухбития
                movb    (R0)+, R4       ; берём очередной байт
                clr     (R1)

4$:             ror     (R1)
                ror     (R1)
                ror     (R1)
                ror     (R1)
                bic     #170000, (R1)   ; тут мы два бита расширяем в 4, дублируя их
                ror     R4
                bcc     5$
                bis     #50000, (R1)

5$:             ror     R4
                bcc     6$
                bis     #120000, (R1)

6$:             sob     R3, 4$          ; расширяем байт в слово
                tst     (R1)+
                sob     R2, 3$          ; по всей ширине спрайта
                mov     R1, R2
                sub     #20, R2
                add     #60, R1
                mov     #10, R3         ; продублируем строку

7$:             mov     (R2)+, (R1)+
                sob     R3, 7$
                add     #60, R1
                nop
                bit     #100000, R1     ; здесь без скроллинга, как только доходим до конца экрана
                beq     8$
                sub     #200, @#0PlatformScrAddr$ ; уменьшаем начальный адрес начинаем рисовать заново
                br      1$
; ───────────────────────────────────────────────────────────────────────────

8$:             sob     R5, 2$

                mov     #Sound2$, R4
                trap    72              ; Вывод звука с повышением тона
                                        ; Вход: R4 - адрес блока параметров
                                        ;       .word длит.
                                        ;       .word тон,тон,..., 0 - конец цепочки
                return

; сверху в экран заезжает мелкий воздушный шар
Splash3:        mov     #40134, 0BallonScrAddr$

1$:             mov     (PC)+, R1
0BallonScrAddr$: .word 47134

                mov     #BallonSprEnd-4, R0
                mov     #34, R5

2$:             mov     #4, R2          ; ширина спрайта 4 байта

3$:             mov     #4, R3
                movb    (R0)+, R4
                clr     (R1)

4$:             ror     (R1)
                ror     (R1)
                ror     (R1)
                ror     (R1)
                bic     #170000, (R1)    ; та же фигня - байт в слово
                ror     R4
                bcc     5$
                bis     #50000, (R1)

5$:             ror     R4
                bcc     6$
                bis     #120000, (R1)

6$:             sob     R3, 4$
                tst     (R1)+
                sob     R2, 3$
                mov     R1, R2
                sub     #100, R1        ; дублируем строку
                mov     -(R2), -(R1)
                mov     -(R2), -(R1)
                mov     -(R2), -(R1)
                mov     -(R2), -(R1)
                sub     #10, R0
                sub     #100, R1
                bit     #140000, R1     ; и снизу вверх до границы экрана
                bne     7$
                add     #200, @#0BallonScrAddr$
                br      1$
; ───────────────────────────────────────────────────────────────────────────

7$:             sob     R5, 2$
                return

; и опускается на платформу
Splash4:        mov     #40000, R0
                mov     #100, R1

8$:             clr     (R0)+
                sob     R1, 8$
                mov     #40234, R0
                mov     #SpriteBuffer, R1
                mov     #70, R2
                mov     #4, R3

9$:             mov     (R0)+, (R1)+
                sob     R3, 9$
                add     #70, R0
                mov     #213, R5
                mov     #36, R4
                mov     #47244, R0

10$:            mov     R0, R1
                add     #100, R1
                mov     #72, R2

11$:            mov     -(R0), -(R1)
                mov     -(R0), -(R1)
                mov     -(R0), -(R1)
                mov     -(R0), -(R1)
                sub     #70, R0
                sub     #70, R1
                sob     R2, 11$
                add     #7300, R0
                mov     #16, R3

12$:            mov     R4, R1
                mov     #320, @#177716
                sob     R1, .

                mov     R4, R1
                mov     #220, @#177716
                sob     R1, .

                sob     R3, 12$
                inc     R4
                sob     R5, 10$

                mov     #Sound3$, R4
                trap    72              ; Вывод звука с повышением тона
                                        ; Вход: R4 - адрес блока параметров
                                        ;       .word длит.
                                        ;       .word тон,тон,..., 0 - конец цепочки
                return

Splash5:        mov     #40004, R1
                mov     #strCopyright, R4 ; "(C)   BIL corp"
                trap    104             ; вывод строки на экран
                                        ; Вход: R1 - адрес экрана
                                        ;       R4 - адрес строки, конец строки - 0
                                        ; Выход: R4 - адрес за концом строки
                mov     #Sound4$, R4
                trap    72              ; Вывод звука с повышением тона
                                        ; Вход: R4 - адрес блока параметров
                                        ;       .word длит.
                                        ;       .word тон,тон,..., 0 - конец цепочки
; ───────────────────────────────────────────────────────────────────────────
; вывод информации об авторе
                mov     #42, R5
                mov     #ScrAboutChr, R2 ; адреса экрана, куда выводить
                mov     #strAbout, R3   ; буквы

2$:             clr     R0
                bisb    (R3)+, R0
                beq     2$              ; 0 пропускаем
                call    GetFontData

                mov     (R2)+, R1
                trap    66              ; Вывод символа на экран
                                        ; Вход: R0 - адрес данных символа
                                        ;       R1 - адрес экрана
                mov     #Sound5$, R4
                trap    72              ; Вывод звука с повышением тона
                                        ; Вход: R4 - адрес блока параметров
                                        ;       .word длит.
                                        ;       .word тон,тон,..., 0 - конец цепочки
                sob     R5, 2$
                return

; выводим текст "GAME"
Splash6:        mov     #42000, R0
                mov     #17000, R1

1$:             clr     (R0)+
                sob     R1, 1$
                mov     #9., R3
                mov     #strGame, R5    ; "GAME"
                mov     #62000, R1
                mov     #1, R0
2$:             trap    100             ; Вывод текста очень широкими буквами
                                        ; Вход: R0 - коэффициент растяжения по вертикали
                                        ;       R1 - адрес экрана
                                        ;       R5 - адрес текста
                mov     #Sound6$, R4
                trap    72              ; Вывод звука с повышением тона
                                        ; Вход: R4 - адрес блока параметров
                                        ;       .word длит.
                                        ;       .word тон,тон,..., 0 - конец цепочки
                inc     R0
                sub     #500, R1
                sob     R3, 2$
; выводим цифру 1 очень большим шрифтом
                mov     #43014, R1
                mov     #FONT + <'1 - 40>*10. + 1, R0     ; цифра 1
                mov     #8., R2         ; количество байтов в знаке

3$:             mov     #8., R3         ; количество битов в байте
                movb    (R0)+, R4

4$:             clr     R5
                asr     R4
                bcc     5$
                mov     #-1, R5

5$:             mov     R3, -(SP)
                mov     #3, R3          ; один бит - три слова

7$:             tst     (R1)+
                bne     8$
                mov     R5, -2(R1)

8$:             sob     R3, 7$
                mov     (SP)+, R3
                sob     R3, 4$

                mov     R1, R3
                mov     #37, R4

9$:             sub     #60, R3
                add     #20, R1
                mov     #30, R5

10$:            tst     (R1)
                bne     11$
                cmp     #-1, (R3)
                bne     11$
                mov     (R3), (R1)

11$:            cmp     (R1)+, (R3)+
                sob     R5, 10$
                sob     R4, 9$
                add     #20, R1
                sob     R2, 3$
                return

; ///////////////////////////////////////////////////////////////////////////

; ///////////////////////////////////////////////////////////////////////////
; Подпрограммы игрового меню

DrawMenu1:
; рамка вокруг экрана
                mov     #2, R4
                mov     #4, R3
                mov     #BlockSprite, R0
                mov     #77300, R1
                mov     #5, R2

1$:             mov     #20, R5
2$:             trap    6               ; Рисование методом наложения
                                        ; Вход: R0 - адрес спрайта в памяти
                                        ;       R1 - адрес экрана
                                        ;       R2 - высота спрайта
                                        ;       R3 - ширина спрайта в байтах
                add     #4, R1
                sob     R5, 2$
                mov     #40000, R1
                sob     R4, 1$
                mov     #40000, R0
                mov     #200, R1
                mov     #273, R5
                mov     #356, R4
                mov     #76, R2

3$:             movb    R5, (R0)+
                add     R2, R0
                movb    R5, (R0)+
                movb    R4, (R0)+
                add     R2, R0
                movb    R4, (R0)+
                sob     R1, 3$
                return

DrawMenu2:
; Рисуем поверхность земли
                mov     #<GroundSprite+2>, R0
                mov     #75520, R1
                mov     #15, R2
                mov     #40, R3
                trap    6               ; Рисование методом наложения
                                        ; Вход: R0 - адрес спрайта в памяти
                                        ;       R1 - адрес экрана
                                        ;       R2 - высота спрайта
                                        ;       R3 - ширина спрайта в байтах
; рисуем причальную мачту для воздушного шара
                mov     #45001, R1
                mov     #37, R2
                trap    12              ; Вывод на экран платформы для воздушного шара
                                        ; Вход: R1 - адрес экрана
                                        ;       R2 - масштаб по высоте
; ещё одну
                add     #66, R1
                trap    12              ; Вывод на экран платформы для воздушного шара
                                        ; Вход: R1 - адрес экрана
                                        ;       R2 - масштаб по высоте
; рисуем воздушный шар
                mov     #41603, R1
                mov     #BallonSprW, R3
                mov     #BallonSprite, R0
                mov     #BallonSprH, R2
                trap    6               ; Рисование методом наложения
                                        ; Вход: R0 - адрес спрайта в памяти
                                        ;       R1 - адрес экрана
                                        ;       R2 - высота спрайта
                                        ;       R3 - ширина спрайта в байтах
; и ещё один
                add     #66, R1
                trap    6               ; Рисование методом наложения
                                        ; Вход: R0 - адрес спрайта в памяти
                                        ;       R1 - адрес экрана
                                        ;       R2 - высота спрайта
                                        ;       R3 - ширина спрайта в байтах
                return

DrawMenu3:      mov     #strMenu, R4
                mov     #datMenu, R3
                call    DrawText
                mov     #60024, R1
                trap    104             ; вывод строки на экран
                                        ; Вход: R1 - адрес экрана
                                        ;       R4 - адрес строки, конец строки - 0
                                        ; Выход: R4 - адрес за концом строки
                add     #24, R1
                mov     #Stage, R4      ; тут хранится число, номер этапа
                trap    104             ; вывод строки на экран
                                        ; Вход: R1 - адрес экрана
                                        ;       R4 - адрес строки, конец строки - 0
                                        ; Выход: R4 - адрес за концом строки
                mov     #60024, R0
                mov     #12, R1

1$:             mov     #14, R2

2$:             bic     #52525, (R0)+
                sob     R2, 2$
                add     #50, R0
                sob     R1, 1$
                return

; здесь выводим название игры буквами, меняющими высоту
AnimMenu1:      mov     #5, R3
                mov     #AnimGameName, R5

2$:             movb    (R5)+, R4       ; направление
                beq     4$              ; 0 - уменьшение, !0 - рост
                incb    (R5)            ; увеличиваем размер
                cmpb    #12, (R5)       ; дошли до максимума?
                bne     3$              ; нет ещё
                comb    -(R5)           ; да - сменим рост на уменьшение
                inc     R5

3$:             movb    (R5)+, R2       ; размер буквы
                mov     (R5)+, R0       ; адрес символа
                sub     #400, (R5)      ; буква растёт
                mov     (R5)+, R1       ; адрес экрана
                trap    106             ; выводим символ
                                        ; Вход: R0 - адрес данных букв
                                        ;       R1 - адрес экрана
                                        ;       R2 - масштаб по высоте
                                        ; Выход: R1 - адрес экрана после действия
                br      8$
; ───────────────────────────────────────────────────────────────────────────

4$:             decb    (R5)            ; уменьшаем размер
                cmpb    #1, (R5)        ; до минимума дошли?
                bne     5$              ; нет ещё
                comb    -(R5)           ; да - сменим уменьшение на рост
                inc     R5

5$:             movb    (R5)+, R2       ; размер буквы
                mov     (R5)+, R0       ; адрес символа
                mov     (R5), R1        ; адрес экрана
                mov     #4, R4

6$:             clr     (R1)+
                clr     (R1)+
                clr     (R1)+
                clr     (R1)+
                add     #70, R1
                sob     R4, 6$          ; стираем не нужную часть буквы
                mov     R1, (R5)+       ; буква уменьшается
                trap    106             ; выводим символ
                                        ; Вход: R0 - адрес данных букв
                                        ;       R1 - адрес экрана
                                        ;       R2 - масштаб по высоте
                                        ; Выход: R1 - адрес экрана после действия
                mov     #4, R4

7$:             clr     (R1)+
                clr     (R1)+
                clr     (R1)+
                clr     (R1)+
                add     #70, R1
                sob     R4, 7$          ; низ тоже стираем

8$:             sob     R3, 2$
                return

; ///////////////////////////////////////////////////////////////////////////

; ///////////////////////////////////////////////////////////////////////////
; Подпрограммы прорисовки начального экрана игры

; прорисовка игрового экрана
DrawGameScr1:
; рисуем землю
                mov     #GroundSprite, R0 ; адрес спрайта
                mov     #71203, R1      ; адрес экрана
                mov     #33, R2         ; высота спрайта
                mov     #40, R3         ; ширина спрайта в байтах
                trap    6               ; Рисование методом наложения
                                        ; Вход: R0 - адрес спрайта в памяти
                                        ;       R1 - адрес экрана
                                        ;       R2 - высота спрайта
                                        ;       R3 - ширина спрайта в байтах
                add     #40, R1         ; и ещё раз
                trap    6               ; Рисование методом наложения
                                        ; Вход: R0 - адрес спрайта в памяти
                                        ;       R1 - адрес экрана
                                        ;       R2 - высота спрайта
                                        ;       R3 - ширина спрайта в байтах
; рисуем море
                add     #3237, R1
                mov     #477, R0        ; теперь заполняем синим

1$:             mov     #52525, (R1)+
                sob     R0, 1$
                mov     #20, R4         ; потом замостим низ экрана
; рисуем нижнюю границу
2$:             mov     #Block2Sprite, R0
                mov     #21, R2
                mov     #4, R3
                trap    6               ; Рисование методом наложения
                                        ; Вход: R0 - адрес спрайта в памяти
                                        ;       R1 - адрес экрана
                                        ;       R2 - высота спрайта
                                        ;       R3 - ширина спрайта в байтах
                add     #4, R1
                sob     R4, 2$
                return

; подымаем платформу с шаром вверх
AnimGameScr0:   mov     #35, R5
                mov     #71200, R1
                mov     #3, R2

5$:             mov     #Melody3$, R3
                trap    14              ; Звучание тонального набора
                                        ; Вход: R3 - адрес тонального набора - цепочка пар слов
                                        ;            .word длительность (0 - конец цепочки),
                                        ;            .word тон.
                mov     R2, R4
                mov     #PlatformSprMask, R0
                mov     #7, R2
                mov     #PlatformSprW, R3
                trap    10              ; Стирание методом побитовой очистки
                                        ; Вход: R0 - адрес спрайта в памяти
                                        ;       R1 - адрес экрана
                                        ;       R2 - высота спрайта
                                        ;       R3 - ширина спрайта в байтах
                sub     #3176, R1
                mov     #BallonSprMask, R0
                mov     #BallonSprH, R2
                mov     #BallonSprW, R3
                trap    10              ; Стирание методом побитовой очистки
                                        ; Вход: R0 - адрес спрайта в памяти
                                        ;       R1 - адрес экрана
                                        ;       R2 - высота спрайта
                                        ;       R3 - ширина спрайта в байтах
                mov     #BallonSprite, R0
                sub     #600, R1
                trap    6               ; Рисование методом наложения
                                        ; Вход: R0 - адрес спрайта в памяти
                                        ;       R1 - адрес экрана
                                        ;       R2 - высота спрайта
                                        ;       R3 - ширина спрайта в байтах
                add     #3176, R1
                mov     #3736, R0
                mov     R4, R2
                inc     R2
                trap    12              ; Вывод на экран платформы для воздушного шара
                                        ; Вход: R1 - адрес экрана
                                        ;       R2 - масштаб по высоте
                trap    20              ; Вывод звёзд в игре
                sob     R5, 5$
                return

AnimGameScr1:   mov     @#PlatformStartAddr, R1 ; берём текущий адрес платформы
                mov     #PlatformSprMask, R0
                mov     #11, R2
                mov     #3, R4

1$:             mov     #PlatformSprW, R3
                trap    10              ; Стирание методом побитовой очистки
                                        ; Вход: R0 - адрес спрайта в памяти
                                        ;       R1 - адрес экрана
                                        ;       R2 - высота спрайта
                                        ;       R3 - ширина спрайта в байтах
2$:             add     #100, R1
                add     #PlatformSprW, R0
                sob     R2, 2$
                tst     (R1)+
                mov     (R1), R3

3$:             add     #200, R1
                cmp     (R1), R3
                beq     3$
                tst     -(R1)
                mov     #4, R2
                sob     R4, 1$

                add     #600, @#PlatformStartAddr ; опускаем платформу
                mov     @#PlatformStartAddr, R1
                mov     #PlatformSprite, R0
                mov     PlatfScaleYDn$, R2
                trap    12              ; Вывод на экран платформы для воздушного шара
                                        ; Вход: R1 - адрес экрана
                                        ;       R2 - масштаб по высоте
                return


AnimGameScr2:   mov     #72537, R1
                sub     PlatfMoveRt$, R1
                mov     #SpriteBuffer, R0 ; восстановим сохранённую ранее часть экрана
                mov     #44, R2

5$:             mov     #PlatformSprW, R3

6$:             movb    (R0)+, (R1)+
                sob     R3, 6$
                add     #PlatformSprPitch, R1
                sob     R2, 5$
                sub     #4377, R1       ; новый адрес
                mov     R1, R4
                mov     #SpriteBuffer, R0 ; сохраним новую часть экрана
                mov     #44, R2

7$:             mov     #PlatformSprW, R3

8$:             movb    (R1)+, (R0)+
                sob     R3, 8$
                add     #PlatformSprPitch, R1
                sob     R2, 7$
                mov     R4, R1          ;рисуем платформу на новом месте
                mov     #1, R2
                trap    12              ; Вывод на экран платформы для воздушного шара
                                        ; Вход: R1 - адрес экрана
                                        ;       R2 - масштаб по высоте
                return

AnimGameScr3:   mov     @#PlatformFinishAddr, R1
                mov     #7, R2
                sub     PlatfScaleYUp$, R2
                mov     R2, R4
                dec     PlatfScaleYUp$
                mov     #PlatformSprMask, R0
                mov     #7, R2
                mov     #PlatformSprW, R3
                trap    10              ; Стирание методом побитовой очистки
                                        ; Вход: R0 - адрес спрайта в памяти
                                        ;       R1 - адрес экрана
                                        ;       R2 - высота спрайта
                                        ;       R3 - ширина спрайта в байтах
                mov     R4, R2
                sub     #600, R1
                mov     R1, @#PlatformFinishAddr
                trap    12              ; Вывод на экран платформы для воздушного шара
                                        ; Вход: R1 - адрес экрана
                                        ;       R2 - масштаб по высоте
                return

; прорисовка воздушного шара на фоне поверхности
; Вход: R5 - приращение адреса к BallonAddr
DrawBallon4:    ; восстанавливаем содержимое экрана из буфера
                mov     #BalScrBuffer, R0
                mov     @#BallonAddr, R1
                mov     R1, -(SP)
                mov     #BallonSprW, R3
                mov     #BallonSprH, R2

13$:            mov     R3, R4

14$:            movb    (R0)+, (R1)+
                sob     R4, 14$
                add     #BallonSprPitch, R1
                sob     R2, 13$
                mov     (SP)+, R1
                add     R5, R1
                mov     R1, -(SP)
                ; сохраняем экран в новом месте
                mov     #BalScrBuffer, R0
                mov     #BallonSprH, R2

15$:            mov     R3, R4

16$:            movb    (R1)+, (R0)+
                sob     R4, 16$
                add     #BallonSprPitch, R1
                sob     R2, 15$
                ; выводим шар на новом месте
                mov     (SP)+, R1
                mov     R1, @#BallonAddr
                mov     #BallonSprMask, R0
                mov     #BallonSprH, R2
                trap    10              ; Стирание методом побитовой очистки
                                        ; Вход: R0 - адрес спрайта в памяти
                                        ;       R1 - адрес экрана
                                        ;       R2 - высота спрайта
                                        ;       R3 - ширина спрайта в байтах
                mov     #BallonSprite, R0

17$:            mov     R3, R4

18$:            tstb    (R1)
                bne     19$
                bisb    (R0), (R1)

19$:            inc     R0
                inc     R1
                sob     R4, 18$
                add     #BallonSprPitch, R1
                sob     R2, 17$
                return


; ///////////////////////////////////////////////////////////////////////////


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

; Проверка на удачное финиширование
; Вход: R2 - адрес спрайта воздушного шара

FinishCheck:    cmp     R2, @#FinishAddr
                beq     1$
                inc     R2
                cmp     R2, @#FinishAddr
                beq     1$
                inc     R2
                cmp     R2, @#FinishAddr
                beq     1$
                dec     R2
                return
; ───────────────────────────────────────────────────────────────────────────

1$:             mov     #TopStack, SP
                ; обработка завершения этапа
; End of function FinishCheck

FinishStage$:   trap    30              ; Спецэффект бегущей волны искажения на экране
                mov     #40000, R3
                mov     #77300, R4
                mov     #10000, R1      ; задержка
                mov     #5, R0

1$:             inc     @#177664
                mov     #40, R2
2$:             mov     (R4)+, (R3)+
                sob     R2, 2$
                mov     R1, R2
                sob     R2, .

                sob     R0, 1$
                mov     #42, R0

3$:             inc     @#177664
                mov     #40, R2
4$:             clr     (R3)+
                sob     R2, 4$
                mov     R1, R2
                sob     R2, .

                sob     R0, 3$

                mov     #7, R5
                mov     #strSuccess, R4
21$:            trap    70              ; Вывод строки на экран через буфер и скроллинг
                                        ; Вход: R3 - адрес экрана
                                        ;       R4 - адрес строки текста
                add     #21, R4
                add     #1200, R3
                mov     #20, R0

22$:            inc     @#177664
                mov     #40, R2
23$:            clr     (R3)+
                sob     R2, 23$
                mov     R1, R2
                sob     R2, .

                sob     R0, 22$
                sob     R5, 21$
                mov     #36, R0

24$:            inc     @#177664
                mov     #40, R2
25$:            clr     (R3)+
                sob     R2, 25$
                mov     R1, R2
                sob     R2, .

                sob     R0, 24$
                mov     #5, R0

26$:            inc     @#177664
                mov     R1, R2
                sob     R2, .

                sob     R0, 26$
                mov     #200, R5
                mov     #40000, R0

27$:            movb    #167356, (R0)+
                add     #76, R0
                movb    #135673, (R0)+
                movb    #135673, (R0)+
                add     #76, R0
                movb    #167356, (R0)+
                sob     R5, 27$

                mov     #Sound26$, R4
                trap    72              ; Вывод звука с повышением тона
                                        ; Вход: R4 - адрес блока параметров
                                        ;       .word длит.
                                        ;       .word тон,тон,..., 0 - конец цепочки
                mov     #StarSetMenu, R2  ; Набор мигающих звёзд в меню
31$:            trap    4               ; Прорисовка мигающих звёздочек
                                        ; Вход: R2 - адрес блока параметров:
                                        ;            .word число элементов (пар адресов)
                                        ;            .word адрес спрайта в памяти
                                        ;            .word адрес экрана
                call    IsPressed$      ; проверка на нажатие клавиши или джойстика.
                                        ; Выход: если нажато - Z=1
                                        ;        если не нажато - Z=0
                beq     32$
                mov     #30000, R4
                sob     R4, .
                br      31$
; ───────────────────────────────────────────────────────────────────────────

32$:            mov     #Sound27$, R4
                trap    72              ; Вывод звука с повышением тона
                                        ; Вход: R4 - адрес блока параметров
                                        ;       .word длит.
                                        ;       .word тон,тон,..., 0 - конец цепочки
                trap    74              ; Прокрутка экрана с попутной очисткой внутри рамки
                inc     @#Stage         ; переходим к следующему этапу
                cmp     #'6, @#Stage    ; а они закончились?
                bne     33$              ; ещё нет
                jmp     GameFinishEnd$  ; да - Игра полностью пройдена
; ───────────────────────────────────────────────────────────────────────────

33$:            ; переходим к следующему этапу
                mov     @#Stage, R0     ; номер этапа
                bic     #60, R0         ; делаем номер 1..5
                asl     R0              ; *4
                asl     R0
                mov     #Score, R1      ; счёт игры - 4 байта цифр, как обычно число '1'-20
                mov     (R1)+, <ScoreStore-10>(R0) ; эта фигня работает только для этапов 2..5
                mov     (R1)+, <ScoreStore-6>(R0)
                jmp     GameMenu$
; ───────────────────────────────────────────────────────────────────────────
; сохранённые счета для этапов, которые нигде больше не используются
ScoreStore:     .ascii "2344"           ; для этапа 2
                .ascii "2347"           ; для этапа 3
                .ascii "2337"           ; для этапа 4
                .ascii "2367"           ; для этапа 5
ScoreStoreEnd:
; ───────────────────────────────────────────────────────────────────────────

StarsSet1:      .word 9.                ; Набор звёзд в заставке, с воздушным шаром
                .word StarSpr1, 55005
                .word StarSpr1, 53670
                .word StarSpr0, 65040
                .word StarSpr1, 64662
                .word StarSpr2, 42307
                .word StarSpr3, 40775
                .word StarSpr4, 51240
                .word StarSpr3, 73335
                .word StarSpr2, 53114

StarSetMenu:    .word 17.               ; Набор мигающих звёзд в меню
                .word StarSpr2, 40107
                .word StarSpr3, 41037
                .word StarSpr4, 44075
                .word StarSpr3, 50040
                .word StarSpr2, 54066
                .word StarSpr1, 54122
                .word StarSpr0, 56070
                .word StarSpr1, 60017
                .word StarSpr2, 47005
                .word StarSpr3, 60036
                .word StarSpr4, 66000
                .word StarSpr3, 70042
                .word StarSpr2, 74012
                .word StarSpr1, 74072
                .word StarSpr0, 63027
                .word StarSpr1, 76640
                .word StarSpr2, 66076
; массив звёзд в игре
GameStars:      .word 17.               ; количество элементов в массиве
                .word StarSpr4, 50050   ; спрайт, адрес
                .word StarSpr3, 43066
                .word StarSpr2, 52010
                .word StarSpr1, 55066
                .word StarSpr0, 51036
                .word StarSpr1, 43005
                .word StarSpr2, 63412
                .word StarSpr3, 66071
                .word StarSpr4, 55030
                .word StarSpr3, 57060
                .word StarSpr2, 44045
                .word StarSpr1, 46016
                .word StarSpr0, 70020
                .word StarSpr1, 63034
                .word StarSpr2, 54054
                .word StarSpr3, 70247
                .word StarSpr4, 60000

Sound1$:        .word 60
                .word 61, 101, 121, 141
                .word 71, 111, 131, 151
                .word 101, 121, 141, 161
                .word 401, 301, 201, 101
                .word 301, 201, 101, 201
                .word 101, 0

Sound2$:        .word 140
                .word 700, 400, 200, 500
                .word 141, 0

Sound3$:        .word 200
                .word 301, 1111, 0

Sound4$:        .word 100
                .word 101, 201, 301, 401
                .word 501, 601, 701, 0

Sound5$:        .word 60
                .word 201, 141, 0

Sound6$:        .word 30
                .word 201, 0

Sound7$:        .word 1110
                .word 1111, 0

Sound8$:        .word 14
                .word 1000, 400, 0

Sound14$:       .word 60
                .word 400, 200, 0

Sound9$:        .word 10
                .word 1400, 1600, 2000, 400
                .word 0

Sound10$:       .word 50
                .word 111, 161, 51, 0

Sound11$:       .word 100
                .word 141, 341, 241, 141
                .word 241, 101, 0

Sound12$:       .word 24
                .word 1000, 1400, 0
Sound13$:       .word 60
                .word 300, 400, 300, 0

Sound15$:       .word 10
                .word 500, 100, 0

Sound27$:       .word 300
                .word 700, 301, 0

Sound29$:       .word 10
                .word 200
                .word 1000
                .word 600
                .word 0

Sound26$:       .word 50
                .word 200, 240, 100, 60
                .word 240, 122, 60, 200
                .word 144, 100, 144, 0

Sound16$:       .word 10
                .word 140, 1000, 0

Sound17$:       .word 22
                .word 100, 1000, 100, 0

Sound18$:       .word 30
                .word 1000, 100, 0

Sound19$:       .word 30
                .word 700, 200, 0

Sound20$:       .word 30
                .word 600, 300, 0

Sound21$:       .word 30
                .word 1600, 1000, 1200, 0

Sound22$:       .word 2
                .word 1000, 1400, 400, 1400
                .word 1000, 400, 0

Sound23$:       .word 20
                .word 100, 200, 300, 400
                .word 300, 200, 100, 0

Sound31$:       .word 10, 10
                .word 10, 20
                .word 10, 10
                .word 0

Sound24$:       .word 10
                .word 100, 600, 100, 300
                .word 100, 0

Sound25$:       .word 10
                .word 300, 400, 1000, 70
                .word 0
; ───────────────────────────────────────────────────────────────────────────
Melody3$:       .word 1, 100
                .word 0
                .word 140, 100
                .word 140, 200
                .word 0
; ───────────────────────────────────────────────────────────────────────────
; это приращения адреса для каждой из пулек взорвавшейся башки
HdScrtchOffsTbl:.word -3
                .word -300
                .word 3
                .word 300
                .word -102
                .word -177
                .word 102
                .word 177
; ───────────────────────────────────────────────────────────────────────────
AnimGameName:   .byte 0, 12             ; параметры - рост/уменьшение, размер
                .word FONT + <'B - 40>*10. + 1 ; адрес символа буквы
                .word 42014             ; адрес экрана
                .byte 377, 2
                .word FONT + <'A - 40>*10. + 1
                .word 45024
                .byte 0, 11
                .word FONT + <'L - 40>*10. + 1
                .word 42434
                .byte 377, 2
                .word FONT + <'L - 40>*10. + 1
                .word 46044
                .byte 0, 5
                .word FONT + <'Y - 40>*10. + 1
                .word 44454
; ───────────────────────────────────────────────────────────────────────────
; массив параметров, в массиве 10. элементов:
; .word адрес экрана
; .byte n,n,n,n - 4 байта
AirFlowData:    .word 40407             ; адрес воздушного потока
                .byte 2, 0, 2, 0        ; параметры
                .word 43047
                .byte 2, 0, 2, 0
                .word 45002
                .byte 2, 0, 2, 0
                .word 47056
                .byte 2, 0, 0, 2
                .word 51030
                .byte 0, 2, 0, 2
                .word 53076
                .byte 0, 2, 0, 2
                .word 55021
                .byte 0, 2, 0, 0
                .word 57063
                .byte 2, 0, 2, 0
                .word 61035
                .byte 2, 0, 2, 0
                .word 64001
                .byte 2, 0, 2, 0
; ───────────────────────────────────────────────────────────────────────────
; Луна, ширина 3, высота 23
MoonSprite:     .byte 0, 0, 0
                .byte 300, 77, 0
                .byte 374, 377, 3
                .byte 17, 377, 17
                .byte 0, 360, 17
                .byte 0, 300, 77
                .byte 0, 300, 77
                .byte 0, 300, 77
                .byte 0, 0, 377
                .byte 0, 0, 377
                .byte 0, 0, 377
                .byte 0, 0, 377
                .byte 0, 300, 77
                .byte 0, 300, 77
                .byte 0, 300, 77
                .byte 0, 360, 17
                .byte 17, 377, 17
                .byte 374, 377, 3
                .byte 300, 77, 0
MoonSpriteEnd:  .even
MoonSprLen = MoonSpriteEnd - MoonSprite
MoonSprH = 23
MoonSprW = 3
MoonSprPitch = 100 - MoonSprW

; движения луны
; первый параметр - количество движений, второй - приращение адреса
MoonMovParam:   .word 11, 177377    ; подъём
                .word 26, 177777    ; горизонтально
                .word 25, 377       ; спуск
; ───────────────────────────────────────────────────────────────────────────
ReklColorTbl:   .word 177777
                .word 31463
                .word 125252
                .word 21042
                .word 52525
                .word 10421
                .word 167356
                .word 63146
                .word 73567
ReklColorTblEnd:.word 77520
; адреса вывода каждой буквы по отдельности
ScrAboutChr:    .word 64004, 62410, 61014, 57420
                .word 56024, 54430, 53034, 56050
                .word 57454, 61060, 62464, 64070
                .word 50010, 47414, 47020, 46424
                .word 46030, 45440, 46044, 46450
                .word 47054, 47460, 50064, 73004
                .word 73010, 73014, 73020, 73024
                .word 73030, 73050, 73054, 73060
                .word 73064, 73070
; вот этих вот букв
strAbout:       .asciz "БОРТНИК"
                .asciz "БОРИС"
                .ascii "город"
                .ascii "МОСКВА"
                .ascii "26.02.1990."

strCopyright:   .asciz "(C)   BIL corp"

strGame:        .asciz "GAME"

Text13$:        .asciz "НЕ ДАВИ НА РАЗУМ"

strReklama:     .asciz "РЕКЛАМА "

strSuccess:     .asciz "    ВЫ УДАЧНО   "
                .asciz "    ЗАКОНЧИЛИ   "
                .asciz "    ЭТОТ ЭТАП   "
                .asciz "  С РЕЗУЛЬТАТОМ "
                .ascii "      "
Score:          .ascii "2486"           ; счёт игры - 4 байта цифр, как обычно число '1'-20
                .asciz "      "
                .asciz "   ПРИМИТЕ МОИ  "
                .asciz "  ПОЗДРАВЛЕНИЯ! "
                .even
; ───────────────────────────────────────────────────────────────────────────
strMenu:        .asciz "1 ИГРА"
                .asciz "2 УПРАВЛЕНИЕ"
                .asciz "3 ИНФОРМАЦИЯ"
                .asciz "4 ВЫХОД"
                .asciz "ЭТАП "

strInformation1:.asciz "ВАША ЗАДАЧА:"
                .asciz "ИСПОЛЬЗУЯ"
                .asciz "ПОТОКИ ВЕТРА,"
                .asciz "КОРРЕКТИРУЯ"
                .asciz "ВЫСОТУ ПОЛЕТА"
                .asciz "ГОРЕЛКОЙ, СЕСТЬ"
                .asciz "НА ВЫШКУ,"
                .asciz "СТОЯЩУЮ ВНИЗУ"
                .asciz "В ЦЕНТРЕ ЭКРАНА"
                .asciz "О НАПРАВЛЕНИИ"
                .asciz "ВЕТРА В ЛЮБОМ"
                .asciz "УЧАСТКЕ НЕБА"
                .asciz "МОЖНО СУДИТЬ ПО"
                .asciz "ПОЛЕТУ ОБЛАКОВ."
                .asciz "ВРЕМЯ ИГРЫ:"
                .asciz "20 ОБХОДОВ ЛУНЫ"
                .asciz "С УВЕЛИЧЕНИЕМ"
                .asciz "ЭТАПА"
                .asciz "УВЕЛИЧИВАЕТСЯ"
                .asciz "СЛОЖНОСТЬ ИГРЫ"
                .asciz "МУЖАЙТЕСЬ!"
                .asciz "ДОЙТИ ДО КОНЦА"
                .asciz "ДАНО НЕ КАЖДОМУ"
                .asciz "МАХ РЕЗУЛЬТАТ"
                .asciz "ЭТАПА ─ 2368."
                .asciz "УПРАВЛЕНИЕ"
                .asciz "ШАРОМ МОЖЕТ"
                .asciz "ПРОИЗВОДИТЬСЯ И"
                .asciz "ОТ ДЖОЙСТИКА."
                .asciz "ВО ВСЕХ"
                .asciz "ОСТАЛЬНЫХ"
                .asciz "(НЕ ИГРОВЫХ)"
                .asciz "СЛУЧАЯХ"
                .asciz "ДЖОЙСТИК"
                .asciz "ДУБЛИРУЕТ"
                .asciz "КЛАВИШУ 'ВВОД'"

strControls:    .asciz "УПРАВЛЕНИЕ"
                .asciz "ГОРЕЛКА"
                .asciz "ВКЛ.  МУЗЫКИ"
                .asciz "ВЫКЛ. МУЗЫКИ"
                .asciz "ПАУЗА"
                .asciz "ВЫХОД К МЕНЮ"

strInfoStg2:    .asciz "В ЭТОМ ЭТАПЕ"
                .asciz "ВАМ СЛЕДУЕТ"
                .asciz "УВЕРТЫВАТЬСЯ"
                .asciz "ОТ СНАРЯДОВ!"
                .asciz "УСПЕХА ВАМ!"

strInfoStg3:    .asciz "ОПАСАЙТЕСЬ"
                .asciz "МЕТЕОРИТОВ!"

strYouDied:     .asciz "ПОДВОДНАЯ ЛОДКА"
                .asciz "В СТЕПЯХ УКРАИНЫ"
                .asciz "ПОГИБЛА"
                .asciz "В НЕРАВНОМ"
                .asciz "ВОЗДУШНОМ БОЮ!"

Text11$:        .asciz "ХВАТИТ ЛОМАТЬСЯ!"
                .asciz "ИДИ ОСТЫНЬ!"
                .asciz "ТВОЕ ВРЕМЯ"
                .asciz "ИСТЕКЛО!"
                .even
; ───────────────────────────────────────────────────────────────────────────
datAbout:       .word   76006
                .word   40
                .word   0

datMenu:        .word  66010
                .word  1400
                .word  1400
                .word  1400
                .word  0

datInformation1:.word   50010
                .word   3406
                .word   1370
                .word   1404
                .word   1374
                .word   1374
                .word   1416
                .word   1370
                .word   1372
                .word   0

datInformation2:.word   50006
                .word   1400
                .word   1402
                .word   1372
                .word   1400
                .word   5010
                .word   1370
                .word   0

datInformation3:.word   46006
                .word   1420
                .word   1360
                .word   1376
                .word   4010
                .word   1370
                .word   1376
                .word   4004
                .word   1400
                .word   0

datInformation4:.word   47014
                .word   1376
                .word   1370
                .word   1404
                .word   1414
                .word   1374
                .word   1372
                .word   1412
                .word   1376
                .word   1376
                .word   1366
                .word   0

datControls:    .word   50014
                .word   10004
                .word   1370
                .word   1400
                .word   1414
                .word   1364
                .word   0

datInfoStg2:    .word   52010
                .word   1402
                .word   1376
                .word   1400
                .word   4002
                .word   0

datInfoStg3:    .word   55414
                .word   1776
                .word   0

datYouDied:     .word   50002
                .word   1376
                .word   1422
                .word   1372
                .word   1370
                .word   0

datText11$:     .word   50002
                .word   2412
                .word   2402
                .word   1404
                .word   0
; ───────────────────────────────────────────────────────────────────────────

Start1$:        clr     @#36
EntryPoint$:    mov     #'1, @#Stage    ; инициализируем номер текущего этапа
                mov     #MoonAddr, R0
                mov     #10, R1

1$:             clr     (R0)+
                sob     R1, 1$
; сюда переходим после нажатия на клавишу СТОП
StartOverTT4$:  mov     #DisTrap, @#34  ; инициализируем вектор 10
                mov     #TimerValue, @#177706 ; инициализируем таймер
                mov     #20, @#177712   ; запускаем таймер
                mov     #TrapTo4, @#4   ; вектор 4
                mov     #SkipSplash, @#60 ; любое нажатие на клавишу пропустит заставку
                mov     #SkipSplash, @#274 ; и сделает переход к меню игры
                mov     #TopStack, SP   ; инициализация стека
                mov     #220, @#177716  ; инициализация спикера, зачем-то так
                trap    2               ; Инициализация некоторых переменных драйвера экрана
                mov     @#177662, R0    ; сброс готовности клавиатуры, чтобы на нажатие была реакция
                trap    0               ; Очистка экрана диагонально зубчатыми линиями
                call    Splash1
                call    Splash2
                call    Splash3
                call    Splash4
                call    Splash5
                trap    110             ; мигают звёзды и ждём нажатия клавиши
                call    Splash6

GoTryAgain:     mov     #Sound7$, R4
                trap    72              ; Вывод звука с повышением тона
                                        ; Вход: R4 - адрес блока параметров
                                        ;       .word длит.
                                        ;       .word тон,тон,..., 0 - конец цепочки
; ───────────────────────────────────────────────────────────────────────────
; конец заставок и начало игрового меню
SkipSplash:
; вход в игровое меню после этапа
StartGameMenu:  trap    2               ; Инициализация некоторых переменных драйвера экрана
                trap    102             ; Очистка экрана горизонтальными линиями сверху и снизу
; рисуем игровое меню
GameMenu$:      call    DrawMenu1
                call    DrawMenu2
                call    DrawMenu3
                mov     #125250, @#AnimLetColor ; цвет анимированных букв
                mov     #66007, @#MenuCursor ; адрес курсора меню
                mov     #VecKbd, @#60
                mov     #VecKbd, @#274
                mov     #Sound8$, R4
                trap    72              ; Вывод звука с повышением тона
                                        ; Вход: R4 - адрес блока параметров
                                        ;       .word длит.
                                        ;       .word тон,тон,..., 0 - конец цепочки
MenuLoop$:      call    AnimMenu1
                mov     @#MenuCursor, R1 ; адрес курсора меню
                com     #0
                beq     10$
; выводим курсор меню
                call    SelCursor
10$:            mov     #StarSetMenu, R2 ; Набор мигающих звёзд в меню
                trap    4               ; Прорисовка мигающих звёздочек
                                        ; Вход: R2 - адрес блока параметров:
                                        ;            .word число элементов (пар адресов)
                                        ;            .word адрес спрайта в памяти
                                        ;            .word адрес экрана
                mov     #1000, R0       ; ждём нажатия чего-нибудь

11$:            tst     @#177714
                bne     0pressJoy$      ; нажали джойстик - переход
                bit     #100, @#177716
                beq     13$             ; нажали клавишу - переход

12$:            sob     R0, 11$
                br     MenuLoop$        ; и крутимся в цикле
; ───────────────────────────────────────────────────────────────────────────

13$:            ; что нажали?
                mov     @#177662, R2
                mov     R1, R3          ; старый адрес курсора сохраним
                cmp     #33, R2         ; стрелку вниз?
                bne     14$             ; нет
                cmp     #72407, R1      ; да, а до низа дошли?
                beq     12$             ; да - ничего не делать
                add     #1400, R1       ; движемся вниз
                br      15$
; ───────────────────────────────────────────────────────────────────────────

14$:            cmp     #32, R2         ; стрелку вверх?
                bne     18$             ; нет
                cmp     #66007, R1      ; да, а до верха дошли?
                beq     12$             ; да - ничего не делать
                sub     #1400, R1       ; движемся вверх

15$:            mov     R1, @#MenuCursor
                tst     (R3)            ; если курсор был высвечен
                beq     17$
                mov     R3, R1
                call    SelCursor       ; погасить его

17$:            mov     #Sound10$, R4
                trap    72              ; Вывод звука с повышением тона
                                        ; Вход: R4 - адрес блока параметров
                                        ;       .word длит.
                                        ;       .word тон,тон,..., 0 - конец цепочки
                br      MenuLoop$       ; и возвращаемся в цикл

18$:            cmp     #12, R2         ; нажали ввод?
                bne     12$             ; нет - продолжаем цикл
; кнопка джойстика работает как ввод
0pressJoy$:     bic     #170777, R1     ; выделяем уникальный разряд
                cmp     #6000, R1       ; первый пункт?
                bne     22$             ; нет
                jmp     StartGame       ; да - начинаем игру
; ───────────────────────────────────────────────────────────────────────────

22$:            cmp     #7000, R1       ; второй пункт?
                bne     23$             ; нет
                jmp     SetControls     ; да - зададим управление
; ───────────────────────────────────────────────────────────────────────────

23$:            cmp     #1000, R1       ; третий пункт?
                bne     24$             ; нет
                jmp     ShowInfo        ; да - показать информацию
; ───────────────────────────────────────────────────────────────────────────

24$:            emt     14              ; Выход из игры
                mov     #1000, @#264    ; адрес загрузки поменяем, чтоб никто не догадался
                mov     #DisTrap, @#34
                mov     #FONT + <'S - 40>*10., R0 ; выведем букву S
                mov     #40000, R1
                trap    66              ; Вывод символа на экран
                                        ; Вход: R0 - адрес данных символа
                                        ;       R1 - адрес экрана
                halt                    ; и выходим в монитор
; ───────────────────────────────────────────────────────────────────────────

SelCursor:      mov     R1, R0
                mov     #10., R2

9$:             comb    (R0)+
                com     (R0)+
                com     (R0)+
                add     #73, R0
                sob     R2, 9$
                return

; Задать управление
SetControls:    trap    120             ; Издать некий определённый звук
                trap    74              ; Прокрутка экрана с попутной очисткой внутри рамки
; ───────────────────────────────────────────────────────────────────────────
; вывод информации о действиях
                mov     #strControls, R4
                mov     #datControls, R3
                call    DrawText
                call    OutAuthorInfo ; вывод  информации об авторе
; делаем текст зелёным
                mov     #50002, R0
                mov     #52525, R4
                call    UnColored
; а этот - синим
                mov     #125252, R4
                call    UnColored

                mov     #5, R3          ; у нас 5 пунктов меню управления
                mov     #60010, R0      ; адрес экрана пункта меню
                mov     #TempBuffer, R4 ; буфер кодов управления
                mov     R4, R5
                mov     #KeyFire$, (R4)+ ; адреса, где находятся коды управляющих клавиш
                mov     #KeyMusicOn$, (R4)+
                mov     #KeyMusicOff$, (R4)+
                mov     #KeyPause$, (R4)+
                mov     #KeyMenu$, (R4)+ ; клавиша выхода в меню игры

5$:             call    SelectMenu      ; выделяем первый пункт меню управления
8$:             bit     #100, @#177716  ; ждём нажатия клавиши
                bne     8$              ; джойстик не предусмотрен
                mov     @#177662, @(R5)+ ; сохраняем код нажатой клавиши
                mov     #Sound11$, R4
                trap    72              ; Вывод звука с повышением тона
                                        ; Вход: R4 - адрес блока параметров
                                        ;       .word длит.
                                        ;       .word тон,тон,..., 0 - конец цепочки
                call    SelectMenu      ; развыделяем текущий пункт меню
                add     #1400, R0       ; переходим к следующему
                sob     R3, 5$
                jmp     StartGameMenu   ; возвращаемся в игровое меню
; ───────────────────────────────────────────────────────────────────────────
; выделяем/развыделяем текущий пункт меню
SelectMenu:     mov     R0, R4
                mov     #10., R1

9$:             mov     #30, R2

10$:            com     (R4)+
                sob     R2, 10$
                add     #20, R4
                sob     R1, 9$
                return

UnColored:      mov     #100, R3
1$:             mov     #36, R5

2$:             bic     R4, (R0)+
                sob     R5, 2$
                add     #4, R0
                sob     R3, 1$
                return

; ───────────────────────────────────────────────────────────────────────────
ShowInfo:       trap    120             ; Издать некий определённый звук
                trap    74              ; Прокрутка экрана с попутной очисткой внутри рамки
; выводим первый экран с информацией
                mov     #strInformation1, R4
                mov     #datInformation1, R3
                call    DrawText
                trap    114             ; Вывод на экран строк об авторе, копирайт, и сделать остальной текст синим.
; ───────────────────────────────────────────────────────────────────────────
                mov     #51210, R1
                mov     #3, R2

1$:             mov     #57, R3

2$:             movb    #-1, (R1)+      ; рисуем красную линию
                sob     R3, 2$
                add     #21, R1
                sob     R2, 1$
                trap    116             ; Звук, ждать нажатия клавиши или джойстика, звук,
                                        ; очистка экрана с прокруткой
; ───────────────────────────────────────────────────────────────────────────
; выводим второй экран с информацией
                mov     #datInformation2, R3
                call    DrawText

                trap    114             ; Вывод на экран строк об авторе, копирайт, и сделать остальной текст синим.
                trap    116             ; Звук, ждать нажатия клавиши или джойстика, звук,
                                        ; очистка экрана с прокруткой
; ───────────────────────────────────────────────────────────────────────────
; выводим третий экран с информацией
                mov     #datInformation3, R3
                call    DrawText

                trap    114             ; Вывод на экран строк об авторе, копирайт, и сделать остальной текст синим.
                trap    116             ; Звук, ждать нажатия клавиши или джойстика, звук,
                                        ; очистка экрана с прокруткой
; ───────────────────────────────────────────────────────────────────────────
; выводим четвёртый экран с информацией
                mov     #datInformation4, R3
                call    DrawText
                trap    114             ; Вывод на экран строк об авторе, копирайт, и сделать остальной текст синим.
                trap    116             ; Звук, ждать нажатия клавиши или джойстика, звук,
                                        ; очистка экрана с прокруткой
                jmp     GameMenu$       ; возврат в меню
; ───────────────────────────────────────────────────────────────────────────
; Начать игру
StartGame:      mov     #Sound9$, R4
                trap    72              ; Вывод звука с повышением тона
                                        ; Вход: R4 - адрес блока параметров
                                        ;       .word длит.
                                        ;       .word тон,тон,..., 0 - конец цепочки
                mov     #5, @#CannonHitCount  ; шар выдерживает 5 попаданий пули
                mov     @#Stage, R0     ; номер текущего этапа 61..65
                sub     #'1, R0
                asl     R0              ; *4
                asl     R0
                add     R0, PC
                jmp     StartStage1     ; начинаем первый этап
                jmp     StartStage2     ; начинаем второй этап
                jmp     StartStage3     ; начинаем третий этап
                jmp     StartStage4     ; начинаем четвёртый этап
                jmp     StartStage5     ; начинаем пятый этап
; ───────────────────────────────────────────────────────────────────────────

; начинаем первый этап
StartStage1:    mov     #73572, @#CannonAddr
                mov     #1, @#NeedMkFrstAct
                mov     #BulletBuffer, R0 ; очищаем буфер пулек
                mov     #BulletsNum * 2, R1

1$:             clr     (R0)+
                sob     R1, 1$

                trap    64              ; Инициализация счёта
                trap    2               ; Инициализация некоторых переменных драйвера экрана
                trap    0               ; Очистка экрана диагонально зубчатыми линиями

                call    DrawGameScr1    ; прорисовка игрового экрана

                mov     #72500, R0
                mov     #SpriteBuffer, R1 ; сохраняем часть экрана в буфере
                mov     #44, R2         ; это пригодится в будущем

3$:             mov     #PlatformSprW/2, R3

4$:             mov     (R0)+, (R1)+
                sob     R3, 4$
                add     #PlatformSprPitch, R0
                sob     R2, 3$
                call    AnimGameScr0    ; подымаем платформу с шаром вверх

                trap    16              ; Проверка на нажатие клавиши или кнопки джойстика, если нажата - выход
                trap    34              ; Инициализация обходов Луны и Инициализация яч. MoonAddr, MoonMovPPtr
                trap    44              ; Инициализация яч. FinishAddr и Очистка буфера BalScrBuffer
                trap    30              ; Спецэффект бегущей волны искажения на экране

                mov     #40202, @#BallonAddr ; адрес вывода спрайта воздушного шара
                clr     @#FirePower     ; уровень горелки
                mov     #Melody2$, @#CurrMelNote$ ; адрес текущей играемой ноты мелодии
                mov     #72537, @#PlatformFinishAddr
                mov     #5, PlatfScaleYUp$  ; на сколько подымать платформу
                mov     #37, PlatfMoveRt$   ; на сколько двигать вправо платформу
                mov     #37, PlatfScaleYDn$ ; на сколько опускать платформу
                mov     #43400, @#PlatformStartAddr

LoopGCBig$:     ; большой цикл игры, с охватом начальных анимаций
; тут платформа опускается, после того как шар стартанул
                tst     (PC)+           ; высота платформы
PlatfScaleYDn$: .word   0
                beq     4$
                call    AnimGameScr1
                dec     PlatfScaleYDn$  ; уменьшаем высоту платформы
                br      10$             ; тем временем, продолжается игра
; ───────────────────────────────────────────────────────────────────────────
; тут платформа движется вправо, после того как опустится
4$:             tst     (PC)+           ; сколько двигать вправо
PlatfMoveRt$:   .word   0
                beq     9$
                call    AnimGameScr2
                dec     PlatfMoveRt$
                br      10$             ; тем временем, продолжается игра
; ───────────────────────────────────────────────────────────────────────────
; тут платформа немного движется вверх
9$:             tst     (PC)+           ; сколько подымать вверх
PlatfScaleYUp$: .word   0
                beq     10$
                call    AnimGameScr3

10$:            mov     #GameStars, R2  ; массив звёзд в игре
                trap    4               ; Прорисовка мигающих звёздочек
                                        ; Вход: R2 - адрес блока параметров:
                                        ;            .word число элементов (пар адресов)
                                        ;            .word адрес спрайта в памяти
                                        ;            .word адрес экрана
                ; обработка уровня горения горелки
                mov     #FirePower, R1  ; адрес уровня горения горелки, 0..400 с шагом 20
                tst     @#177714        ; джойстик нажат?
                bne     11$             ; да - переход (любая кнопка джойстика - как горелка)
                bit     #100, @#177716  ; нет, а клавиша нажата?
                bne     13$             ; нет
                cmp     KeyFire$, @#177662 ; да, нажали горелку?
                bne     13$             ; нет

11$:            cmp     #400, (R1)      ; максимум?
                beq     14$             ; да - делать нечего
                add     #20, (R1)       ; нет - ещё есть куда увеличивать
12$:            br      14$
; ───────────────────────────────────────────────────────────────────────────

13$:            bic     #20, (R1)       ; уровень горелки падает
                tst     (R1)            ; упал до нуля?
                beq     14$             ; да - всё, некуда уменьшать
                sub     #40, (R1)       ; уменьшаем уровень горения горелки
14$:            ; обработка смещения шара в воздушных потоках
                mov     @#BallonAddr, R0 ; адрес вывода спрайта воздушного шара
                clr     R4
                bic     #170777, R0     ; здесь определяем высоту,
                beq     15$             ; и по ней - смещение в воздушных потоках
                cmp     #1000, R0
                beq     19$
                cmp     #2000, R0
                beq     20$
                cmp     #3000, R0
                beq     16$
                sub     #4000, R0
                bne     17$
                mov     #-1, R5
                br      25$

17$:            clr     R5
                br      25$

16$:            com     #-1
                bne     20$
22$:            mov     #-1, R5
                br      24$

19$:            com     #-1
                bne     15$
20$:            clr     R5
                br      24$

15$:            mov     #1, R5          ; тут вычисляется смещение к новому адресу воздушного шара

24$:            neg     R5
                com     R4
                bne     24$

25$:            mov     (R1), R4        ; уровень горения горелки, 0..400 с шагом 20
                bic     #77, R4
                neg     R4              ; чем больше уровень
                add     R4, R5          ; тем выше поднимется шар
                add     #100, R5
                mov     @#BallonAddr, R0
                cmp     #40300, R0      ; достиг верхней границы?
                blt     26$             ; да
                bic     #177600, R5

26$:            cmp     #63000, R0      ; достигли нижней границы?
                bgt     27$             ; нет
                ; да - проверим сели или промахнулись
; проверяем условие "Шар достиг уровня финишной платформы"
                inc     R5
                bic     #277, R5
                bis     #100, R5
                cmp     #63300, R0
                bge      29$

                mov     R0, R2
                add     #3375, R2
                call    FinishCheck     ; Проверка на удачное финиширование
                                        ; Вход: R2 - адрес спрайта воздушного шара
                ; при удачном финишировании сюда не возвращаемся
                                        ; ### если раскомментировать след. строку
                jmp     FinishStage$    ; ### то будет завершение этапа при любой посадке
; ───────────────────────────────────────────────────────────────────────────
                ; доп. проверка на финиш, если сели не сильно криво
3$:             add     #3, R2
                mov     #5, R1
                cmp     @#FinishAddr, R2
                bne     5$
                mov     #-1, R5
                br      29$
; ───────────────────────────────────────────────────────────────────────────

5$:             dec     R2
6$:             cmp     @#FinishAddr, R2
                bne     8$
                bic     #100, R5
                br      29$
; ───────────────────────────────────────────────────────────────────────────

8$:             dec     R2
                sob     R1, 6$
                cmp     @#FinishAddr, R2
                bne     1$
                mov     #1, R5
                br      29$
; ───────────────────────────────────────────────────────────────────────────
                ; проверим, не опустился ли на уровень земли
1$:             cmp     #65600, R0
                bge     29$

                cmp     #73000, R0
                bgt     2$
                bic     #100, R5
                trap    60              ; Выход: R0 - признак:
                                        ;       -1 - джойстик не нажат, и горелка не нажата
                                        ;       0 - джойстик нажат и ранее была нажата клавиша горелки
                                        ;       100250/100350 - ранее была нажата клавиша горелки, а джойстик не нажат
; ───────────────────────────────────────────────────────────────────────────
                bic     #177677, R0
                bne     30$
                ; тут прорисовка воздушного шара на фоне поверхности
2$:             call    DrawBallon4
                br      30$             ; продолжаем игру
                ; проверка на боковые границы экрана
27$:            trap    46              ; Очистка буфера BalScrBuffer
                bic     #177700, R0
                bne     28$             ; не дошли до левого
                bic     #76, R5         ; дошли - смещаться влево не будем

28$:            cmp     #74, R0         ; дошли до правого?
                bne     29$             ; нет
                bic     #1, R5          ; да - смещаться вправо не будем

29$:            mov     @#BallonAddr, R1 ; адрес вывода спрайта воздушного шара
                mov     #BallonSprite, R0
                mov     #BallonSprH, R2
                mov     #BallonSprW, R3
                trap    22              ; Стирание спрайта с экрана безусловное
                                        ; Вход: R1 - адрес экрана
                                        ;       R2 - высота спрайта
                                        ;       R3 - ширина спрайта в байтах
                add     R5, R1          ; новый адрес
                mov     R1, @#BallonAddr ; сохраняем
                trap    6               ; Рисование методом наложения
                                        ; Вход: R0 - адрес спрайта в памяти
                                        ;       R1 - адрес экрана
                                        ;       R2 - высота спрайта
                                        ;       R3 - ширина спрайта в байтах
30$:            trap    50              ; Вкл/выкл фоновой музыки
                trap    62              ; уменьшение счёта
                trap    112             ; Проверка на нажатие кнопки паузы
                                        ; и если да, то пауза

                bit     #100, @#177716  ; клавиша нажата?
                bne     112$            ; нет
                cmp     (PC)+, @(PC)+   ; да, а какая?
KeyMenu$:       .word '2                ; клавиша выхода в меню игры
                .word 177662
                beq     113$            ; да
112$:           call    StoreRegs       ; сохраняем все регистры
                jmp     ProcHiSt$       ; пойдём обрабатывать доп условия верхних этапов
                                        ; но потом неизменно возвращаемся в ProcCommonDiffs$

113$:           jmp     StartGameMenu   ; выходим в меню
; ───────────────────────────────────────────────────────────────────────────

; обработка основных механик игры: луна, ветер, проверка на посадку.
ProcCommonDiffs$:call    RestoreRegs    ; восстанавливаем регистры
                trap    54              ; Если нажата клавиша горелки, делать анимацию огня горелки
                mov     #AirFlowData, R3
                trap    26              ; Анимация воздушных потоков
                ; обрабатываем луну
                tst     (PC)+
MoonMoves$:     .word 0                 ; общее количество движений луны по экрану
                bne     3$
                mov     #1, MoonMoves$
                mov     @#MoonMovPPtr, R0
                dec     (R0)+
                bne     2$
                cmp     #377, (R0)
                bne     1$

5$:             trap    42              ; Инициализация яч. MoonAddr, MoonMovPPtr
                mov     #100, MoonMoves$
                ;tst     @#MoonPass      ; Луна прошла, уменьшаем счётчик ### это для бессмертия
                dec     @#MoonPass      ; Луна прошла, уменьшаем счётчик ### это для честной игры
                bne     4$              ; нет - продолжаем
                ; всё, время вышло
6$:             jmp     StageTimeOut
; ───────────────────────────────────────────────────────────────────────────

1$:             add     #4, R0

2$:             mov     (R0), @#MoonAddrIncr
                tst     -(R0)
                mov     R0, @#MoonMovPPtr
                ; передвигаем луну
3$:             mov     @#MoonAddr, R1
                mov     #MoonSprite, R0
                mov     #MoonSprH, R2
                mov     #MoonSprW, R3
                trap    36              ; Очистка со сравнением, экран очищается только там, где спрайт совпадает
                                        ; Вход: R0 - адрес спрайта в памяти
                                        ;       R1 - адрес экрана
                                        ;       R2 - высота спрайта
                                        ;       R3 - ширина спрайта в байтах
                add     @#MoonAddrIncr, R1
                clr     @#MoonAddrIncr
                mov     R1, @#MoonAddr
                trap    40              ; Вывод со сравнением, спрайт выводится только там, где на экране пусто
                                        ; Вход: R0 - адрес спрайта в памяти
                                        ;       R1 - адрес экрана
                                        ;       R2 - высота спрайта
                                        ;       R3 - ширина спрайта в байтах
                dec     MoonMoves$

4$:             jmp     LoopGCBig$      ; продолжаем игру
; ───────────────────────────────────────────────────────────────────────────

; начинаем второй этап
StartStage2:    trap    74              ; Прокрутка экрана с попутной очисткой внутри рамки
                mov     #datInfoStg2, R3
                mov     #strInfoStg2, R4
NextStartStage3.1$:
                call    DrawText        ; выводим информацию по второму этапу
                mov     #1, @#NeedMkFrstAct
                trap    114             ; Вывод на экран строк об авторе, копирайт,
                                        ; и сделать остальной текст синим.
                mov     #Sound12$, R4
                trap    72              ; Вывод звука с повышением тона
                                        ; Вход: R4 - адрес блока параметров
                                        ;       .word длит.
                                        ;       .word тон,тон,..., 0 - конец цепочки
                call    CheckKey$       ; проверка нажатия любой клавиши или джойстика
                                        ; если что-то нажато - выход
                                        ; иначе- ждём в цикле
NextStartStage4.1$:
                mov     #Sound8$, R4
                trap    72              ; Вывод звука с повышением тона
                                        ; Вход: R4 - адрес блока параметров
                                        ;       .word длит.
                                        ;       .word тон,тон,..., 0 - конец цепочки
                jmp     StartStage1     ; начинаем первый этап

; ───────────────────────────────────────────────────────────────────────────
; начинаем третий этап
StartStage3:    trap    74              ; Прокрутка экрана с попутной очисткой внутри рамки
                mov     #CometBuffer, R0 ; очистка буфера комет
; элемент массива - 2 слова: адрес спрайта кометы, адрес экрана
                mov     #CometsNum*2, R1

1$:             clr     (R0)+
                sob     R1, 1$
                mov     #2, @#CometHitCount ; шар выдержит 3 попадания
                mov     #strInfoStg3, R4
                mov     #datInfoStg3, R3
                jmp     NextStartStage3.1$
; ───────────────────────────────────────────────────────────────────────────
; начинаем пятый этап
StartStage5:    mov     #Sound23$, R4
                trap    72              ; Вывод звука с повышением тона
                                        ; Вход: R4 - адрес блока параметров
                                        ;       .word длит.
                                        ;       .word тон,тон,..., 0 - конец цепочки
                clr     @#HeadAddr
                clr     @#HeadTimeLife
                mov     #2, @#HeadCnt
; ───────────────────────────────────────────────────────────────────────────
; начинаем четвёртый этап
StartStage4:    mov     #2, @#CometHitCount ; шар выдержит 3 попадания
; элемент массива - 2 слова: адрес спрайта кометы, адрес экрана
                mov     #CometBuffer, R1    ; очищаем буфер комет
                mov     #CometsNum4 * 2 + 2, R2 ; зачем-то +2

1$:             clr     (R1)+
                sob     R2, 1$
                jmp     NextStartStage4.1$
; ───────────────────────────────────────────────────────────────────────────

ProcHiSt$:      mov     #TopStack, SP
                mov     @#Stage, R0
                sub     #'1, R0
                asl     R0
                asl     R0
                add     R0, PC
                jmp     ProcCommonDiffs$
                jmp     Proc2St$
                jmp     Proc3St$
                jmp     Proc4St$
                jmp     Proc5St$

; ───────────────────────────────────────────────────────────────────────────
; Обрабатываем усложнения второго этапа
Proc2St$:       tst     @#NeedMkFrstAct ; начальное отображение пушки?
                beq     1$              ; не, уже было, теперь движение только
                clr     @#NeedMkFrstAct ; сбросим флаг
                mov     @#CannonAddr, @#CannonAddrDraw ; и покажем пушку на экране
                trap    124             ; Отобразить пушку

1$:             mov     @#CannonAddr, R1 ; адрес пушки
                tst     PlatfScaleYUp$  ; платформа ещё не достигла финишного положения
                bne     4$              ; да - пропускаем действия
                mov     @#BallonAddr, R0 ; адрес воздушного шара
                bic     #177700, R0
                mov     R1, R2
                bic     #177700, R2     ; положение пушки по горизонтали
                cmp     R0, R2          ; где они относительно друг-друга?
                ble     2$              ; пушка правее шара
                ; пушка левее шара
                cmp     #100 - CannonSprW, R2 ; до правого края доехали?
                beq     4$              ; да - ничего не делать
                mov     #1, R4          ; нет - двигаться вправо
                br      3$
; ───────────────────────────────────────────────────────────────────────────
                ; пушка правее шара
2$:             tst     R2              ; до левого края доехали?
                beq     4$              ; да - ничего не делать
                mov     #-1, R4         ; нет - двигаться влево
3$:             trap    122             ; Передвинуть пушку
                                        ; Вход: R1 - текущий адрес пушки
                                        ; Вход: R4 - приращение адреса
                add     R4, R1
                mov     R1, @#CannonAddr ; и корректируем адрес

4$:             ; тут стрельба пушки
                bic     #177730, ShootCounter
                tst     (PC)+           ; стрелять пора?
ShootCounter:   .word 4
                bne     14$             ; нет ещё
                mov     #36, R3         ; если где-то посередине
                mov     #6, R0

11$:            cmp     R2, R3
                beq     14$             ; то пушка не стреляет, там посадочная платформа
                inc     R3
                sob     R0, 11$
                mov     #50, ShootCounter ; иначе инициализируем счётчик до следующего выстрела
                mov     #BulletBuffer, R2 ; в буфере пуль
                mov     #BulletsNum, R0

12$:            tst     (R2)+           ; ищем пустое место
                beq     13$             ; нашли - можно стрелять
                tst     (R2)+
                sob     R0, 12$
                br      14$             ; не нашли - все пули в воздухе
; ───────────────────────────────────────────────────────────────────────────

13$:            trap    126             ; Выстрел из пушки
                sub     #3176, R1       ; это начальный адрес пули
                clr     (R2)            ; направление - вверх
                mov     R1, -(R2)
                ; теперь осмотрим буфер, и обработаем полёты пуль
14$:            mov     #BulletBuffer, R4
                mov     #BulletsNum, R0
15$:            mov     (R4)+, R1       ; адрес
                beq     19$             ; 0 - тут пусто
                tst     (R4)+           ; куда летит?
                bne     16$             ; вниз
                trap    130             ; Полёт пули верх
                                        ; Вход: R1 - адрес экрана
                                        ;       R4 - адрес элемента в буфере + 4
                br      17$
; ───────────────────────────────────────────────────────────────────────────

16$:            trap    132             ; Полёт пули вниз
                                        ; Вход: R1 - адрес экрана
                                        ;       R4 - адрес элемента в буфере + 4
17$:            tst     @#CannonHitCount ; Шар подбили?
                bne     18$             ; нет ещё
                jmp     GoFail$
; ───────────────────────────────────────────────────────────────────────────
19$:            tst     (R4)+
18$:            sob     R0, 15$         ; до конца буфера дошли?
                                        ; нет - продолжаем

                dec     ShootCounter    ; уменьшаем счётчик до следующего выстрела
                jmp     ProcCommonDiffs$


; обработка доп. усложнений для этапа 3
Proc3St$:       tst     (PC)+           ; комету запускать?
CometLaunchCnt: .word 7                 ; счётчик запуска комет
                bne     5$              ; рано ещё
                mov     #15, CometLaunchCnt ;инициализируем счётчик
                mov     #CometBuffer, R0
                mov     #CometsNum, R2

2$:             tst     (R0)+           ; ищем свободное место в буфере
                bne     4$
                mov     @#177710, R4    ; нашли
                add     #40000, R4      ; генерируем случайный адрес
                bic     #76, R4
                bis     #73, R4
                mov     R4, (R0)
                mov     #SpriteCometL1, -(R0) ; комета у нас всегда левая
                br      5$
; ───────────────────────────────────────────────────────────────────────────

4$:             tst     (R0)+
                sob     R2, 2$

5$:             dec     CometLaunchCnt ; уменьшаем счётчик
                ; осмотрим буфер, обработаем полёт всех комет
                mov     #CometBuffer, R4
                mov     #CometsNum, R2

6$:             mov     (R4), R0        ; пусто?
                beq     8$              ; да - идём дальше
                cmp     R0, #SpriteCometLEnd
                bge     8$              ; комета правая, тут игнорируем
                trap    134             ; Прорисовка комет, летящих слева направо
                                        ; Вход: R4 - адрес текущего элемента массива
8$:             add     #4, R4
                sob     R2, 6$
                jmp     ProcCommonDiffs$

; ───────────────────────────────────────────────────────────────────────────
; обработка усложнений для 4-го этапа
; тут кометы летают и слева и справа
Proc4St$:       tst     @#NeedMkFrstAct ; действие сделать надо?
                beq     2$              ; нет
                mov     #30, CometStg4Delay ; да - зададим задержку появления комет
                clr     @#NeedMkFrstAct ; флаг сбрасываем

2$:             tst     (PC)+           ; кометы пора отображать?
CometStg4Delay: .word 0
                beq     3$              ; да
                dec     CometStg4Delay  ; нет - уменьшаем задержку
                jmp     ProcCommonDiffs$
; ───────────────────────────────────────────────────────────────────────────
                ; отображаем кометы
3$:             tst     (PC)+           ; новую комету пора отображать?
CometStg4Cnt:   .word 1                 ; счётчик до появления кометы
                bne     8$              ; нет
                mov     #7, CometStg4Cnt ; да, инициализируем счётчик
                mov     #CometBuffer, R0 ; ищем в буфере свободное место
                mov     #CometsNum4, R2

4$:             tst     (R0)
                bne     7$
                mov     @#177710, R4    ; нашли, добавляем
                add     #40000, R4      ; новую комету
                bic     #10076, R4
                bit     #1, R4          ; адрес нечётный?
                beq     5$              ; нет - правая комета
                bis     #73, R4
                mov     #SpriteCometL1, (R0)+ ; да - левая
                br      6$
; ───────────────────────────────────────────────────────────────────────────

5$:             mov     #SpriteCometR1, (R0)+
6$:             mov     R4, (R0)
                br      8$
; ───────────────────────────────────────────────────────────────────────────

7$:             add     #4, R0
                sob     R2, 4$

8$:             dec     CometStg4Cnt    ; уменьшаем счётчик
                ; обрабатываем кометы
                mov     #CometBuffer, R4
                mov     #CometsNum4, R2

9$:             mov     (R4), R0        ; элемент пуст?
                beq     11$             ; да
                cmp     R0, #SpriteCometLEnd ; нет, какая комета?
                blt     10$             ; левая
                                        ; правая
                trap    140             ; Прорисовка комет, летящих справа налево
                                        ; Вход: R4 - адрес текущего элемента массива

                br      11$
; ───────────────────────────────────────────────────────────────────────────

10$:            trap    134             ; Прорисовка комет, летящих слева направо
                                        ; Вход: R4 - адрес текущего элемента массива
11$:            add     #4, R4
                sob     R2, 9$

                mov     #CometBuffer + 2, R0
                trap    142             ; Просмотр массива на счёт врезавшихся друг в друга встречно летящих комет,
                                        ; если они врезались друг в друга - взаимоуничтожаются
                                        ; Вход: R0 - адрес буфера комет + 2
                jmp     ProcCommonDiffs$

; ───────────────────────────────────────────────────────────────────────────
; обработка усложнений для 5-го этапа
; тут летает какая-то бошка и взрывается
Proc5St$:       tst     (PC)+           ; бошку выводить?
HeadCnt:        .word 100               ; счётчик до появления бошки
                bne     2$              ; нет ещё
                ; генерируем параметры бошки
                mov     #60, HeadCnt    ; инициализируем счётчик
                mov     @#177710, R0    ; адрес
                bic     #177703, R0     ; корректируем адрес
                add     #40000, R0
                mov     R0, @#HeadAddr
                mov     @#177710, R0 ; время жизни
                bic     #177740, R0
                add     #6, R0
                mov     R0, @#HeadTimeLife

2$:             trap    146             ; Отображаем бошку, проверяем время её жизни и встречу с воздушным шаром
                trap    150             ; Прорисовка разлетающихся осколков от башки
                                        ; и проверка на попадание в воздушный шар
                dec     HeadCnt
                jmp     ProcCommonDiffs$
; ───────────────────────────────────────────────────────────────────────────


TrapTo4:        mov     #TopStack, SP
                trap    2               ; Инициализация некоторых переменных драйвера экрана
                trap    114             ; Вывод на экран строк об авторе, копирайт,
                                        ; и сделать остальной текст синим.
                mov     #Text13$, R4
                mov     #57000, R1
                trap    104             ; вывод строки на экран
                                        ; Вход: R1 - адрес экрана
                                        ;       R4 - адрес строки, конец строки - 0
                                        ; Выход: R4 - адрес за концом строки

                trap    16              ; Проверка на нажатие клавиши или кнопки джойстика, если нажата - выход
                cmp     #'1, @#Stage    ; текущий этап 1?
                beq     2$              ; да - переход,
                dec     @#Stage         ; иначе - уменьшаем этап в наказание

2$:             mov     #TrapTo4, @#4
                tst     @#177662
                jmp     StartOverTT4$
; ───────────────────────────────────────────────────────────────────────────

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

StoreRegs:      mov     R0, @#SR$Tmp
                mov     #SR$Tmp+2, R0
                mov     R1, (R0)+
                mov     R2, (R0)+
                mov     R3, (R0)+
                mov     R4, (R0)+
                mov     R5, (R0)+
                return
; End of function StoreRegs


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


RestoreRegs:    mov     #SR$Tmp+2, R0
                mov     (R0)+, R1
                mov     (R0)+, R2
                mov     (R0)+, R3
                mov     (R0)+, R4
                mov     (R0)+, R5
                mov     @#SR$Tmp, R0
                return
; End of function RestoreRegs


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

; Обработка падения пули, она просто падает без последствий
; Вход: R4 - адрес текущего элемента в массиве

FallDnBullet:   mov     #ShootSprite, R0
                mov     (R4), R1        ; адрес пули
                sub     #200, R1        ; чуть вверх
                clr     (R4)+           ; очищаем элемент массива
                clr     (R4)+
                mov     #7, R2          ; высота спрайта
                mov     #1, R3          ; ширина
                ; тут рисуем полностью пульку
                trap    6               ; Рисование методом наложения
                                        ; Вход: R0 - адрес спрайта в памяти
                                        ;       R1 - адрес экрана
                                        ;       R2 - высота спрайта
                                        ;       R3 - ширина спрайта в байтах
                mov     #Sound16$, R4
                trap    72              ; Вывод звука с повышением тона
                                        ; Вход: R4 - адрес блока параметров
                                        ;       .word длит.
                                        ;       .word тон,тон,..., 0 - конец цепочки
                trap    22              ; Стирание спрайта с экрана безусловное
                                        ; Вход: R1 - адрес экрана
                                        ;       R2 - высота спрайта
                                        ;       R3 - ширина спрайта в байтах
                return
; End of function FallDnBullet

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

; Проверка на попадание
; Вход: R1 - адрес экрана пули
;       R4 - адрес текущего элемента в массиве + 2


HitCheck:       mov     R4, @#HC$Tmp
                mov     @#BallonAddr, R2 ; Получим адрес воздушного шара
                sub     #600, R2
                mov     R1, R3
                mov     #77, R5
                mov     #177700, R4
                mov     R2, R0
                mov     R3, R1
                bic     R4, R0
                bic     R4, R1
                cmp     R0, R1
                bgt     0ret$

1$:             add     #3, R0
                cmp     R0, R1
                blt     0ret$

2$:             mov     R2, R0
                mov     R3, R1
                bic     R5, R0
                bic     R5, R1
                cmp     R0, R1
                bgt     0ret$

3$:             add     #3000, R0
                cmp     R0, R1
                bge     6$
                mov     R3, R1
                mov     R2, R0
                inc     R0
                bic     R4, R0
                bic     R4, R1
                cmp     R0, R1
                bgt     0ret$

4$:             inc     R0
                cmp     R0, R1
                blt     0ret$

5$:             mov     R3, R1
                mov     R2, R0
                add     #4200, R0
                bic     R5, R0
                bic     R5, R1
                cmp     R0, R1
                blt     0ret$

6$:             mov     R3, R0
                mov     #7, R1

7$:             clrb    (R0)
                add     #100, R0
                sob     R1, 7$
                mov     R3, R1
                mov     #ShootSprite, R0 ; рисуем попадание
                mov     #7, R2
                mov     #1, R3
                trap    6               ; Рисование методом наложения
                                        ; Вход: R0 - адрес спрайта в памяти
                                        ;       R1 - адрес экрана
                                        ;       R2 - высота спрайта
                                        ;       R3 - ширина спрайта в байтах
                mov     #Sound17$, R4
                trap    72              ; Вывод звука с повышением тона
                                        ; Вход: R4 - адрес блока параметров
                                        ;       .word длит.
                                        ;       .word тон,тон,..., 0 - конец цепочки
                trap    22              ; Стирание спрайта с экрана безусловное
                                        ; Вход: R1 - адрес экрана
                                        ;       R2 - высота спрайта
                                        ;       R3 - ширина спрайта в байтах
                ;tst     @#CannonHitCount ; попали!  ### это для бессмертия
                dec     @#CannonHitCount ; попали!  ### это для честной игры
                mov     #1, @#ShootCounter ; нужно немедленно снова стрелять
                mov     @#HC$Tmp, R4
                tst     -(R4)           ; очищаем элемент массива
                clr     (R4)+
                clr     (R4)+
0ret$:          return
; End of function HitCheck


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

; Анимация взрыва воздушного шара

BallonBlowAnim: mov     #4000, R5       ; задержка
                mov     #SpriteBlow1, R0
                mov     @#BallonAddr, R1
                add     #1100, R1
                mov     #BlowSprH, R2
                mov     #BlowSprW, R3
                trap    6               ; Рисование методом наложения
                                        ; Вход: R0 - адрес спрайта в памяти
                                        ;       R1 - адрес экрана
                                        ;       R2 - высота спрайта
                                        ;       R3 - ширина спрайта в байтах
                mov     R5, R4
                sob     R4, .
                mov     #Sound18$, R4
                trap    72              ; Вывод звука с повышением тона
                                        ; Вход: R4 - адрес блока параметров
                                        ;       .word длит.
                                        ;       .word тон,тон,..., 0 - конец цепочки
                trap    10              ; Стирание методом побитовой очистки
                                        ; Вход: R0 - адрес спрайта в памяти
                                        ;       R1 - адрес экрана
                                        ;       R2 - высота спрайта
                                        ;       R3 - ширина спрайта в байтах
                mov     R5, R4
                sob     R4, .
                add     #BlowSprLen, R0
                trap    6               ; Рисование методом наложения
                                        ; Вход: R0 - адрес спрайта в памяти
                                        ;       R1 - адрес экрана
                                        ;       R2 - высота спрайта
                                        ;       R3 - ширина спрайта в байтах
                mov     R5, R4
                sob     R4, .
                mov     #Sound19$, R4
                trap    72              ; Вывод звука с повышением тона
                                        ; Вход: R4 - адрес блока параметров
                                        ;       .word длит.
                                        ;       .word тон,тон,..., 0 - конец цепочки
                trap    10              ; Стирание методом побитовой очистки
                                        ; Вход: R0 - адрес спрайта в памяти
                                        ;       R1 - адрес экрана
                                        ;       R2 - высота спрайта
                                        ;       R3 - ширина спрайта в байтах
                mov     R5, R4
                sob     R4, .
                add     #BlowSprLen, R0
                trap    6               ; Рисование методом наложения
                                        ; Вход: R0 - адрес спрайта в памяти
                                        ;       R1 - адрес экрана
                                        ;       R2 - высота спрайта
                                        ;       R3 - ширина спрайта в байтах
                mov     R5, R4
                sob     R4, .
                mov     #Sound20$, R4
                trap    72              ; Вывод звука с повышением тона
                                        ; Вход: R4 - адрес блока параметров
                                        ;       .word длит.
                                        ;       .word тон,тон,..., 0 - конец цепочки
                trap    10              ; Стирание методом побитовой очистки
                                        ; Вход: R0 - адрес спрайта в памяти
                                        ;       R1 - адрес экрана
                                        ;       R2 - высота спрайта
                                        ;       R3 - ширина спрайта в байтах
                mov     R5, R4
                sob     R4, .
                return
; End of function BallonBlowAnim

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

StageTimeOut:   mov     #Text11$, R4
                mov     #datText11$, R3
                br      GoFail1$
; ───────────────────────────────────────────────────────────────────────────

GoFailS$:       mov     #TopStack, SP
GoFail$:        mov     #BallonSprMask, R0
                mov     @#BallonAddr, R1
                mov     #BallonSprH, R2
                mov     #BallonSprW, R3
                trap    10              ; Стирание методом побитовой очистки
                                        ; Вход: R0 - адрес спрайта в памяти
                                        ;       R1 - адрес экрана
                                        ;       R2 - высота спрайта
                                        ;       R3 - ширина спрайта в байтах
                call    BallonBlowAnim  ; Анимация взрыва воздушного шара
                mov     #strYouDied, R4
                mov     #datYouDied, R3
GoFail1$:       call    DrawText
                mov     #Sound21$, R4
                trap    72              ; Вывод звука с повышением тона
                                        ; Вход: R4 - адрес блока параметров
                                        ;       .word длит.
                                        ;       .word тон,тон,..., 0 - конец цепочки
                call    CheckKey$       ; проверка нажатия любой клавиши или джойстика
                                        ; если что-то нажато - выход
                                        ; иначе- ждём в цикле
                jmp     GoTryAgain
; ───────────────────────────────────────────────────────────────────────────

LoopGameFinishEnd$:
                trap    74              ; Прокрутка экрана с попутной очисткой внутри рамки
; Игра полностью пройдена
GameFinishEnd$: mov     #datCongrat, R3
                mov     #strCongratulations, R4
                call    DrawText
                trap    114             ; Вывод на экран строк об авторе, копирайт,
                                        ; и сделать остальной текст синим.
; ───────────────────────────────────────────────────────────────────────────
                mov     #TrapTo4Fin$, R0
                mov     R0, @#4
                mov     R0, @#60
                mov     R0, @#274
                mov     @#177662, R0
                mov     #FinalMelody, R4 ; это аргумент функции 152
                trap    152             ; Проигрыш музыки
                                        ; Вход: R4 - адрес массива мелодии

                mov     #Sound28$, R4
                trap    72              ; Вывод звука с повышением тона
                                        ; Вход: R4 - адрес блока параметров
                                        ;       .word длит.
                                        ;       .word тон,тон,..., 0 - конец цепочки
                jmp     LoopGameFinishEnd$
; ───────────────────────────────────────────────────────────────────────────

; Вывод текста на экран
; Вход: R3 - список параметров
;       R4 - адрес массива строк

DrawText:       mov     (R3)+, R1
1$:             trap    104             ; вывод строки на экран
                                        ; Вход: R1 - адрес экрана
                                        ;       R4 - адрес строки, конец строки - 0
                                        ; Выход: R4 - адрес за концом строки
                tst     (R3)
                beq     2$
                add     (R3)+, R1
                br      1$
2$:             return

GetFontData:    tstb    R0
                bpl     111$
                sub     #40, R0
111$:           asl     R0
                mov     R0, -(SP)
                asl     R0
                asl     R0
                add     (SP)+, R0
                add     #FONT - 500, R0
                return

TrapTo4Fin$:    mov     #TopStack, SP
                trap    2               ; Инициализация некоторых переменных драйвера экрана
                trap    102             ; Очистка экрана горизонтальными линиями сверху и снизу
                add     #204, @#177664
                ; вывод текста РЕКЛАМА, который потом прыгает вверх вниз с затуханием
                mov     #strReklama, R4
                mov     #36604, R1

1$:             clr     R0
                bisb    (R4)+, R0
                beq     7$
                call    GetFontData
                mov     R4, -(SP)
                mov     #10., R2

3$:             movb    (R0)+, R5
                mov     #8., R3

4$:             clr     R4
                ror     R5
                bcc     6$
                bit     #100, R1
                beq     5$
                movb    #167, R4
                br      6$
; ───────────────────────────────────────────────────────────────────────────

5$:             movb    #335, R4

6$:             movb    R4, (R1)+
                sob     R3, 4$
                add     #70, R1
                sob     R2, 3$
                sub     #1170, R1
                mov     (SP)+, R4
                br      1$
; ───────────────────────────────────────────────────────────────────────────

7$:             mov     #36700, R0
                mov     #56400, R1
                mov     #400, R2

8$:             mov     (R0)+, (R1)+
                sob     R2, 8$
                mov     #332, R5
                clr     0FinFlag$

9$:             mov     R5, R4
                com     0FinFlag$

10$:            tst     (PC)+
0FinFlag$:      .word 177777
                beq     11$
                inc     @#177664
                br      12$
; ───────────────────────────────────────────────────────────────────────────

11$:            dec     @#177664

12$:            bis     #1000, @#177664
                mov     #1000, R0
                sob     R0, .
                sob     R4, 10$
                mov     #Sound29$, R4
                trap    72              ; Вывод звука с повышением тона
                                        ; Вход: R4 - адрес блока параметров
                                        ;       .word длит.
                                        ;       .word тон,тон,..., 0 - конец цепочки
                clc
                ror     R5
                beq     13$
                mov     R5, R4
                asr     R4
                add     R4, R5
                br      9$
; ───────────────────────────────────────────────────────────────────────────
RekData = 300
RekColor1=302
RekColor2=304

13$:            mov     #ReklColorTbl, @#RekData
                ; строка увеличивается в высоту и отображается разными цветами
                ; из таблицы ReklColorTbl
LoopFinal1$:    mov     @#RekData, R0
                mov     (R0), @#RekColor1
                mov     (R0)+, @#RekColor2
                ror     @#RekColor2
                ror     @#RekColor2
                cmp     #ReklColorTblEnd, R0
                bne     1$
                mov     #ReklColorTbl, R0

1$:             mov     R0, @#RekData
                mov     #56700, R0
                mov     #37200, R1
                mov     #37300, R3
                mov     #57000, R2

2$:             mov     #24, R4

3$:             mov     #100, R5

4$:             clrb    (R0)
                clrb    (R2)
                tstb    (R1)+
                beq     6$
                bit     #100, R0
                beq     5$
                movb    @#RekColor1, (R0)
                br      6$
; ───────────────────────────────────────────────────────────────────────────

5$:             movb    @#RekColor2, (R0)

6$:             inc     R0
                tstb    (R3)+
                beq     8$
                bit     #100, R2
                beq     7$
                movb    @#RekColor1, (R2)
                br      8$
; ───────────────────────────────────────────────────────────────────────────

7$:             movb    @#RekColor2, (R2)

8$:             inc     R2
                sob     R5, 4$
                sub     #100, R1
                sub     #100, R3
                sub     #200, R0
                sob     R4, 3$
                sub     #100, R1
                add     #100, R3
                cmp     #40000, R3
                bne     2$
                mtps    #0
                mov     #VecKbdFin$, @#60
                mov     #VecKbdFin$, @#274
                mov     @#177662, R0
                jmp     LoopFinal1$
; ───────────────────────────────────────────────────────────────────────────

VecKbdFin$:     mov     #TopStack, SP
                mov     #F$DataBlock, R0
                mov     #-1, (R0)+      ; 40 цвет цифры 2
                mov     #42020, (R0)+   ; 42 адрес с которого выводить цифру 2
                mov     #40000, (R0)+   ; 44 начало экрана
                mov     #strGame, (R0)+ ; 46 адрес массива
                mov     #52525, (R0)+   ; 50 цвет
                mov     #14, (R0)+      ; 52 макс.масштаб
                mov     #2, (R0)+       ; 54 сама цифра 2
                mov     #44, (R0)+      ; 56
                mov     #61000, @#F$GameAddr ; адрес с которого начинать выводить слово GAME
                trap    154             ; выводит GAME 2
                mov     #Sound7$, R4
                trap    72              ; Вывод звука с повышением тона
                                        ; Вход: R4 - адрес блока параметров
                                        ;       .word длит.
                                        ;       .word тон,тон,..., 0 - конец цепочки
                trap    102             ; Очистка экрана горизонтальными линиями сверху и снизу

1$:             mov     #45430, @#F$ScrAddr ; начальный адрес
                mov     #SecondName, @#F$DataAddr2
                trap    162             ; Вывод названия SECOND
                mov     #Sound30$, R4
                trap    72              ; Вывод звука с повышением тона
                                        ; Вход: R4 - адрес блока параметров
                                        ;       .word длит.
                                        ;       .word тон,тон,..., 0 - конец цепочки
                mov     #F$DataBlock, R0
                mov     #77700, (R0)+   ; 40    адрес экрана вывода
                mov     #byte_34064, (R0)+ ; 42 адрес данных
                mov     #370, (R0)+     ; 44    маска цвета
                mov     #11000, (R0)+   ; 46    задержка
                trap    156             ; Вывод скроллом текста, описания к игре 2
                mov     #VecKbdFin1$, @#60
                mov     #VecKbdFin1$, @#274
                mtps    #0
                mov     @#177662, R0
                mov     #1330, @#177664
                br      1$
; ───────────────────────────────────────────────────────────────────────────
; тут рисуется поверхность
; и анимация взлетающей ракеты, поверхность скроллится по горизонтали,
; ракета постепенно взлетает

VecKbdFin1$:    mov     #TopStack, SP
                mov     #'5, @#Stage    ; ставим 5-й этап
                mov     #TrapTo4, @#4
                trap    02              ; Инициализация некоторых переменных драйвера экрана
                trap    00              ; Очистка экрана диагонально зубчатыми линиями

                mov     #72070, R4
                mov     #67, R5
                mov     #74000, @#320
                mov     @#320, R1
                mov     #40, R3
                mov     R3, R2

1$:             clr     (R1)+
                sob     R2, 1$
                add     #33, R2
                mov     #GroundSprite, R0
                trap    22              ; Стирание спрайта с экрана безусловное
                                        ; Вход: R1 - адрес экрана
                                        ;       R2 - высота спрайта
                                        ;       R3 - ширина спрайта в байтах
                trap    06              ; Рисование методом наложения
                                        ; Вход: R0 - адрес спрайта в памяти
                                        ;       R1 - адрес экрана
                                        ;       R2 - высота спрайта
                                        ;       R3 - ширина спрайта в байтах
                add     #40, R1
                trap    22              ; Стирание спрайта с экрана безусловное
                                        ; Вход: R1 - адрес экрана
                                        ;       R2 - высота спрайта
                                        ;       R3 - ширина спрайта в байтах
                trap    06              ; Рисование методом наложения
                                        ; Вход: R0 - адрес спрайта в памяти
                                        ;       R1 - адрес экрана
                                        ;       R2 - высота спрайта
                                        ;       R3 - ширина спрайта в байтах
                inc     @#320

2$:             mov     #SpriteRocket, R0
                mov     #RocketSprH, R2
                mov     #RocketSprW, R3
                mov     R4, R1
                trap    22              ; Стирание спрайта с экрана безусловное
                                        ; Вход: R1 - адрес экрана
                                        ;       R2 - высота спрайта
                                        ;       R3 - ширина спрайта в байтах
                sub     #301, R1
                trap    06              ; Рисование методом наложения
                                        ; Вход: R0 - адрес спрайта в памяти
                                        ;       R1 - адрес экрана
                                        ;       R2 - высота спрайта
                                        ;       R3 - ширина спрайта в байтах
                mov     R1, R4
                mov     #RocketFlame, R0
                com     #-1
                beq     3$
                add     #RocketFlame1-RocketFlame, R0

3$:             mov     #6, R2
                mov     #2, R3
                add     #1110, R1
                trap    22              ; Стирание спрайта с экрана безусловное
                                        ; Вход: R1 - адрес экрана
                                        ;       R2 - высота спрайта
                                        ;       R3 - ширина спрайта в байтах
                sub     #301, R1
                trap    06              ; Рисование методом наложения
                                        ; Вход: R0 - адрес спрайта в памяти
                                        ;       R1 - адрес экрана
                                        ;       R2 - высота спрайта
                                        ;       R3 - ширина спрайта в байтах
                mov     #GameStars, R2
                trap    04              ; Прорисовка мигающих звёздочек
                                        ; Вход: R2 - адрес блока параметров:
                                        ;            .word число элементов (пар адресов)
                                        ;            .word адрес спрайта в памяти
                                        ;            .word адрес экрана
                mov     #Sound31$, R3
                trap    14              ; Звучание тонального набора
                                        ; Вход: R3 - адрес тонального набора - цепочка пар слов
                                        ;            .word длительность (0 - конец цепочки),
                                        ;            .word тон.
                mov     #77777, R0
                mov     R0, R2
                inc     R2
                mov     #77777 - 73776, R3
4$:             movb    -(R0), -(R2)
                sob     R3, 4$
                sob     R5, 2$

                mov     #FinalMelody, R4
                mov     #TopStack, SP
                mov     #StartGameMenu, -(SP)
                jmp     Func152         ; Проигрыш музыки
                                        ; Вход: R4 - адрес массива мелодии

; ───────────────────────────────────────────────────────────────────────────
; Массив данных для функции 152
; параметры мелодии
FinalMelody:    .word 170004, 70010, 40552, 70003, 30552, 40440, 40362, 20265
                .word 20300, 20327, 20300, 50265, 30300, 30327, 20362, 20420
                .word 20440, 20420, 44362, 24362, 24362, 134362, 44420, 34440
                .word 44440, 134744, 24744, 134552, 34744, 134552, 34744, 70004
                .word 44552, 70003, 30552, 40440, 40362, 20220, 20241, 20265
                .word 20241, 50220, 30241, 30265, 20300, 20265, 20241, 20265
                .word 32300, 32241, 32300, 32241, 32327, 32265, 20300, 20265
                .word 20241, 20265, 32300, 32241, 32300, 32241, 32327, 32265
                .word 32362, 20362, 20420, 32440, 22440, 20502, 30440, 30362
                .word 54265, 70003, 34241, 44300, 32265, 50265, 70005, 70007
; ───────────────────────────────────────────────────────────────────────────
strCongratulations:
                .asciz "БОРТНИК БОРИС"
                .asciz "ПОЗДРАВЛЯЕТ ВАС"
                .asciz "С ЗАВЕРШЕНИЕМ"
                .asciz "ПЕРВОЙ ИГРЫ."
                .asciz "ЕСЛИ ВЫ УСПЕЛИ"
                .asciz "ПРИОБРЕСТИ"
                .asciz "ВТОРУЮ ИГРУ,"
                .asciz "ТО МОЖЕТЕ"
                .asciz "СПАТЬ СПОКОЙНО!"
                .even
datCongrat:     .word   47006 ; адрес
                .word   1374  ; смещения
                .word   1404
                .word   1402
                .word   2774
                .word   1410
                .word   1374
                .word   1404
                .word   1366
                .word   0     ; конец списка
; данные для функции 156
; формат такой:
; byte nScroll, nIndent, nLen
; ascii "string"
; конец данных - byte x,x,x,0
byte_34064:     .byte 100, 25, 6
                .ascii "GAME 2"
                .byte 55, 12, 13
                .ascii "В этой игре"
                .byte 6, 14, 12
                .ascii "перед вами"
                .byte 6, 2, 17
                .ascii "ставится задача"
                .byte 6, 6, 15
                .ascii "проникнуть на"
                .byte 6, 0, 20
                .ascii "базу противника,"
                .byte 6, 15, 11
                .ascii "преодолев"
                .byte 20, 15, 11
                .ascii "970000 км"
                .byte 20, 3, 17
                .ascii "запретной зоны."
                .byte 40, 12, 13
                .ascii "Космическое"
                .byte 6, 10, 14
                .ascii "пространство"
                .byte 6, 24, 6
                .ascii "усеяно"
                .byte 6, 12, 13
                .ascii "патрульными"
                .byte 6, 16, 11
                .ascii "кораблями"
                .byte 6, 12, 13
                .ascii "противника."
                .byte 40, 14, 12
                .ascii "Трудновато"
                .byte 6, 7, 15
                .ascii "вам придется."
                .byte 52, 0, 20
                .ascii "Управляемый вами"
                .byte 6, 2, 17
                .ascii "корабль, помимо"
                .byte 6, 10, 14
                .ascii "передвижения"
                .byte 6, 6, 15
                .ascii "вперед, может"
                .byte 6, 2, 17
                .ascii "перемещаться по"
                .byte 6, 4, 16
                .ascii "всему экрану и"
                .byte 6, 12, 13
                .ascii "стрелять по"
                .byte 6, 4, 17
                .ascii "3 направлениям."
                .byte 77, 10, 14
                .ascii "Приобретайте"
                .byte 6, 11, 14
                .ascii "вторую игру."
                .byte 377, 1, 1
                .ascii " "
                .byte 1, 0, 0, 0
                .even
; ───────────────────────────────────────────────────────────────────────────
; данные для функции 162
; формат:
; сперва идут два байта параметров: byte ScaleY, ColorMask
; затем данные, если 320 - то за ним снова два байта параметров
; если 377, то за ним байт - смещение по высоте в строках
; если 321..376 - то это смещение в строке + 320
; всё остальное - символы - 20
SecondName:     .byte  30,  167, 'C-20, 'O-20
                .byte  377,   34
                .byte  320,   20, 167
                .byte  340, 'E-20
                .byte  340, 'N-20
                .byte  377,   34
                .byte  320,   10,  167
                .byte  331, 'S-20
                .byte  356, 'D-20, 0
                .even

Sound28$:       .word 10
                .word 100, 400, 1000, 0

Sound30$:       .word 14
                .word 300, 500, 700, 1100
                .word 1300, 1500, 1300, 1100
                .word 700, 500, 300, 1000
                .word 0
; ───────────────────────────────────────────────────────────────────────────
; Ракета, ширина 10 высота 17
SpriteRocket:   .byte 0, 0, 0, 0, 0, 0, 360, 77
                .byte 0, 0, 0, 0, 300, 17, 334, 15
                .byte 0, 0, 0, 0, 277, 303, 167, 3
                .byte 0, 0, 0, 252, 252, 363, 335, 0
                .byte 0, 360, 377, 377, 377, 177, 67, 0
                .byte 0, 57, 36, 307, 161, 334, 35, 0
                .byte 360, 12, 170, 34, 307, 361, 77, 0
                .byte 274, 52, 70, 115, 323, 254, 352, 0
                .byte 257, 252, 372, 377, 377, 257, 352, 0
                .byte 274, 252, 72, 63, 63, 363, 77, 0
                .byte 300, 277, 256, 372, 377, 257, 3, 0
                .byte 0, 300, 377, 257, 252, 277, 77, 0
                .byte 0, 0, 0, 360, 377, 352, 372, 0
                .byte 0, 0, 0, 0, 0, 377, 257, 17
                .byte 0, 0, 0, 0, 0, 0, 374, 77
RocketSprW = 10
RocketSprH = 17
RocketSprPitch = 100 - RocketSprW

; это спрайты выхлопа ракеты
                .word ^B0000000000000010    ; 35570, ширина 2, высота 12
                .word ^B0000000000000110
RocketFlame:    .word ^B0000000011110000
                .word ^B0000111101010000
                .word ^B1111100100000000
                .word ^B1111101001000000
                .word ^B0000111110100000
                .word ^B0000000011110000
                .word ^B0000000000000110
                .word ^B0000000000000010
RocketFlame1:   .word ^B1111111100000000    ; 35614, ширина 2, высота 6
                .word ^B0000111011110000
                .word ^B0000001101000000
                .word ^B0000001101000000
                .word ^B0000111011110000
                .word ^B1111111100000000
; ───────────────────────────────────────────────────────────────────────────


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

; Воспроизведение фоновой музыки в игре

BackgrndMusic$: mov     #177716, R5
                mov     CurrMelNote$, R0 ; адрес текущей играемой ноты мелодии
                cmp     #EndMelody$, R0
                bne     1$
                sub     #<EndMelody$-Melody2$>, R0

1$:             movb    (R0)+, R1
                bpl     2$
                mov     #77770, R1

2$:             mov     #77770, R2
                mov     R2, R3
                mov     #5000, R4

3$:             dec     R1
                bgt     4$
                mov     #320, (R5)
                movb    -1(R0), R1
                dec     R2
                dec     R3
                mov     #220, (R5)

4$:             dec     R2
                dec     R3
                sob     R4, 3$
                mov     R0, (PC)+
CurrMelNote$:   .word Melody1$          ; адрес текущей играемой ноты мелодии
                return
; End of function BackgrndMusic$

; ───────────────────────────────────────────────────────────────────────────
Melody2$:       .byte 72, 101, 72, 116, 143, 116, 166, 200
                .byte 72, 101, 72, 116, 143, 116
Melody1$:       .byte 166, 200, 72, 63, 61, 63, 61, 72
                .byte 63, 72, 63, 101, 72, 101, 72, 101
                .byte 72, 200, 72, 101, 72, 116, 143, 116
                .byte 166, 200, 72, 101, 72, 116, 143, 116
                .byte 166, 200, 72, 63, 61, 63, 61, 72
                .byte 63, 72, 63, 101, 72, 101, 72, 63
                .byte 61, 200, 46, 53, 46, 61, 101, 61
                .byte 116, 200, 46, 53, 46, 61, 101, 61
                .byte 116, 200, 46, 42, 40, 42, 40, 46
                .byte 42, 46, 42, 53, 46, 53, 46, 53
                .byte 46, 200
EndMelody$:
; ───────────────────────────────────────────────────────────────────────────

; универсальный буфер для разных этапов
; для этапа 3,4
CometBuffer:
CometsNum = 20      ; количество комет на этапе 3
CometsNum4 = 10     ; для этапа 4 - в 2 раза меньше
CometBufferLen = 20*4 ; размер буфера в байтах
; для этапа 5
HeadBlowCenter:
HeadScratchBuffer = HeadBlowCenter + 2
HeadBulletNum = 10
                .blkw CometBufferLen
; ───────────────────────────────────────────────────────────────────────────

GMCEnd$:        .END
