; Target assembler: BK Turbo8 Cross Assembler

.include        "rm3_0_inc.asm"


; точка входа
Entry$:         jmp     @#HACK

; ███████████████ S U B R O U T I N E ███████████████████████████████████████
; Нарисовать окно с рамкой без тени
; Входные параметры:
; Слово - адрес экрана, бит 15 - флаг, не сохранять содержимое под окном
; Байт - высота в символах
; Байт - ширина в символах
; Байт - маска цвета фона
; Байт - инверсная маска цвета символов
DRWWIN:         mov     #5760, R5
                clr     R4
                br      35136$
; ───────────────────────────────────────────────────────────────────────────
; Нарисовать окно с рамкой с тенью
; Входные параметры:
; Слово - адрес экрана, бит 15 - флаг, не сохранять содержимое под окном
; Байт - высота в символах
; Байт - ширина в символах
; Байт - маска цвета фона
; Байт - инверсная маска цвета символов
DRWWNH:         mov     #5060, R5
                mov     #1, R4
35136$:         mov     R5, WCM1$
                mov     R5, WCM2$
                mov     (SP), R5
                mov     (R5)+, R0   ; Адрес экрана - верхний левый угол
                movb    (R5)+, R1   ; Высота в символах
                movb    (R5)+, R2   ; Ширина в символах
                clr     R3
                bisb    (R5), R3
                swab    R3
                bisb    (R5)+,R3
                mov     R3, BGCOLR  ; маска цвета фона
                clr     R3
                bisb    (R5), R3
                swab    R3
                bisb    (R5)+,R3
                mov     R3, COLMSK  ; инверсная маска цвета символов
                mov     R5, (SP)
                call    STRSCR  ; Сохранение области экрана под окном в буфер
                                ; Входные параметры:
                                ; R0 - адрес экрана, в.л.угол окна, если бит 15 установлен - не сохранять, бит снимается
                                ; R1 - высота окна в символах
                                ; R2 - ширина окна в словах
                                ; R4 - флаг 0 - без тени, 1 - с тенью
                ; рассчитаем центр экрана
                ; предполагается, что ширина и высота всегда чётные, если нет - алгоритм придётся серьёзно корректировать
                ; Ац = Авл + (шир - 2) + (выс / 2 - 1) * 1000
                ; поскольку ширина в словах просто вычитаем её, и - 2, т.к. начинаем рисовать квадрат 2 х 2
                ; а высоту надо поделить на 2 и - 1, т.к. начинаем рисовать квадрат 2 х 2
                add     R2, R0 ; шир
                tst     -(R0)
                mov     R1, R3
                asr     R3  ; выс /= 2
                dec     R3  ; выс -= 1
                swab    R3  ; выс *= 01000
                asl     R3
                add     R3, R0
                clrb    W$FLG
                clrb    H$FLG
                mov     #2, R3  ; начинаем рисовать с окна 2 х 2
                mov     R3, R4
DW5$:           call    DRWRKT  ; рисуем прямоугольник заданного размера
                mov     (PC)+, R5
OPT$WS:         .word   3000
                sob     R5, .
                tstb    W$FLG
                bne     1$
                cmp     R4, R2  ; текущая ширина достигла заданной?
                blo     2$      ; нет ещё
                mov     R2, R4  ; да - ограничим ширину заданной
                incb    W$FLG   ; отметим факт.
                br      1$
; ───────────────────────────────────────────────────────────────────────────

2$:             cmp     (R4)+, -(R0)    ; раз не достигли, то тек. ширина + 2, адрес экрана - 2
1$:             tstb    H$FLG   ; ограничения по высоте достигли?
                bne     3$      ; да - пропустим
                cmp     R3, R1  ; текущая высота достигла заданной?
                bhis    4$      ; да - переход
                sub     #1000, R0   ; нет ещё, тогда адрес экрана - 1000
                tst     (R3)+   ; тек. высота + 2
                br      DW5$    ; рисуем дальше
; ───────────────────────────────────────────────────────────────────────────

4$:             mov     R1, R3  ; да - ограничим высоту заданной
                incb    H$FLG   ; отметим факт.
3$:             tstb    W$FLG   ; если заданной ширины ещё не достигли
                beq     DW5$    ; то продолжим рисовать.
                ; наконец рисуем рамку окна и выходим.
                mov     #125, R1    ; рисуем значок ╔
                call    DRWCHW  ; Вход: R0 - адрес вывода
                                ; R1 - код
                bit     -(R3), -(R4)    ; конечные размеры уменьшаем на 2, чтобы вычесть углы
                inc     R1          ; значок ═
                mov     R3, -(SP)
                mov     R4, -(SP)
                beq     6$
7$:             tst     (R0)+
                call    DRWCHW  ; Вход: R0 - адрес вывода
                                ; R1 - код
                sob     R4, 7$

6$:             tst     (R0)+
                inc     R1      ; значок ╗
                call    DRWCHW  ; Вход: R0 - адрес вывода
                                ; R1 - код
                inc     R1      ; значок ║
                tst     R3
                beq     8$
9$:             add     #1000, R0
                call    DRWCHW  ; Вход: R0 - адрес вывода
                                ; R1 - код
                sob     R3, 9$

8$:             add     #1000, R0
                inc     R1      ; значок ╝
                call    DRWCHW  ; Вход: R0 - адрес вывода
                                ; R1 - код
                sub     #3, R1  ; значок ═
                mov     (SP)+, R4
                beq     10$
11$:            tst     -(R0)
                call    DRWCHW  ; Вход: R0 - адрес вывода
                                ; R1 - код
                sob     R4, 11$

10$:            bit     (R1)+, (R1)+ ; значок ╚
                tst     -(R0)
                call    DRWCHW  ; Вход: R0 - адрес вывода
                                ; R1 - код
                mov     (SP)+, R3
                beq     12$
                tst     -(R1)   ; значок ║
13$:            sub     #1000, R0
                call    DRWCHW  ; Вход: R0 - адрес вывода
                                ; R1 - код
                sob     R3, 13$
12$:            return
; End of function DRWWNH, DRWWIN

; ███████████████ S U B R O U T I N E ███████████████████████████████████████
; рисуем символ уже поверх нужного фона. часть оконной процедуры
; Вход: R0 - адрес вывода
;       R1 - код
; портит R2, R5
DRWCHW:         mov     R1, -(SP)
                mov     R0, -(SP)
                asl     R1
                asl     R1
                asl     R1
                asl     R1
                add     #RMFONT, R1
                mov     #10, R2
1$:             mov     (R1)+, R5
                bic     R5, (R0)
                bic     COLMSK, R5
                bis     R5, (R0)
                add     #100, R0
                sob     R2, 1$
                mov     (SP)+, R0
                mov     (SP)+, R1
                return
; End of function DRWCHW

; ███████████████ S U B R O U T I N E ███████████████████████████████████████
; прорисовка распахивающегося окна
; вход: R0 - адрес экрана (текущий верхний левый адрес окна)
; R3 - текущая высота, отсчёт начинается с 2
; R4 - текущая ширина, отсчёт начинается с 2
; портит R5
DRWRKT:         mov     R0, -(SP)
                mov     R3, -(SP)
                mov     R4, -(SP)
                dec     R4              ; рисуем на 1 символ меньше, т.к. он будет уже правой границей
2$:             mov     #10, R5         ; рисуем верхнюю границу
1$:             mov     BGCOLR, (R0)
                add     #100, R0
                sob     R5, 1$
                sub     #776, R0
                sob     R4, 2$          ; и так по всей текущей ширине
                dec     R3              ; рисуем на 1 символ меньше, т.к. он будет уже нижней границей
WL4$:           mov     #10, R5         ; рисуем правую границу
WL3$:           mov     BGCOLR, (R0)
WCM1$:          tst     1002(R0)        ; тут либо формируем тень, либо нет
                add     #100, R0
                sob     R5, WL3$
                sob     R3, WL4$        ; теперь вертикаль по всей текущей высоте
                mov     (SP), R4        ; снова достаём текущую ширину
WL6$:           mov     #10, R5         ; рисуем нижнюю границу
WL5$:           mov     BGCOLR, (R0)
WCM2$:          tst     1002(R0)        ; тут либо формируем тень, либо нет
                add     #100, R0
                sob     R5, WL5$
                sub     #1002, R0
                sob     R4, WL6$        ; и так по всей текущей ширине
                mov     2(SP), R3       ; снова достаём текущую высоту
                tst     (R0)+
                sub     #2,R3
                beq     9$
8$:             mov     #10, R5         ; рисуем левую границу
7$:             sub     #100, R0
                mov     BGCOLR, (R0)
                sob     R5, 7$
                sob     R3, 8$
9$:             mov     (SP)+, R4
                mov     (SP)+, R3
                mov     (SP)+, R0
                return
; End of function DRWRKT

; Сохранение области экрана под окном в буфер
; Входные параметры:
; R0 - адрес экрана, в.л.угол окна, если бит 15 установлен - не сохранять, бит снимается
; R1 - высота окна в символах
; R2 - ширина окна в словах
; R4 - флаг 0 - без тени, 1 - с тенью
STRSCR:         jsr     R5, @#PUSHA
                add     R4, R2          ; ширина в словах
                mov     R1, R3          ; высота в строка
                add     R4, R3
                asl     R3
                asl     R3
                asl     R3
                mov     R0, R1          ; адрес экрана
                bpl     1$              ; бит не сохранения есть?
                bic     #100000,2(SP)   ; сбросим бит 15 у адреса.
                return                  ; и не будем сохранять
1$:             mov     #17400, @#177716 ; стр.5->окно0, стр.6->окно1
                mov     STADDR, R0
                mov     R3, R4
3$:             mov     R2, R5
                mov     R1, -(SP)
2$:             mov     (R1)+, (R0)+    ; сохраняем содержимое
                sob     R5, 2$
                mov     (SP)+, R1
                add     #100, R1
                sob     R4, 3$
                mov     R3, (R0)+       ; сохраняем высоту
                mov     R2, (R0)+       ; сохраняем ширину
                mov     R1, (R0)+       ; сохраняем адрес
                br      07LR$
; ███████████████ S U B R O U T I N E ███████████████████████████████████████
; Восстановление области экрана из буфера
; Входные параметры: нет
RESWND:         jsr     R5, @#PUSHA
                mov     #17400, @#177716 ; стр.5->окно0, стр.6->окно1
                mov     STADDR, R0
; восстановление
                mov     -(R0), R1       ; достаём адрес
                mov     -(R0), R2       ; достаём ширину
                mov     -(R0), R3       ; достаём высоту
                add     R2, R1
                add     R2, R1
3$:             mov     R2, R4
                sub     #100, R1
                mov     R1, -(SP)
4$:             mov     -(R0), -(R1)    ; восстанавливаем содержимое
                sob     R4, 4$
                mov     (SP)+, R1
                sob     R3, 3$
07LR$:          mov     R0, STADDR
SETPGE:         mov     @#NPAGE, @#177716
                return
; End of function RESWND

; ███████████████ S U B R O U T I N E ███████████████████████████████████████
; Вывод строки.
; Вход: R0 - адрес строки, R1 - адрес экрана
OUTSTR:         jsr     R5, @#PUSHA
21$:            mov     R1, R5      ; Формат символов в строке:
                                    ; 0 - конец строки
                                    ; 1 - перевод строки относительно начальной позиции
                                    ; 2 - закрасить экран цветом фона с адреса 40000
                                    ; 3 - закрасить экран цветом фона с адреса 100000
                                    ; 4 - символы лат. заглавный регистр.
                                    ; 5 - символы лат. строчный регистр.
                                    ; 6..27 - нет
                                    ; 30..33 - задать цвет фона
                                    ; 34..37 - задать цвет символов
                                    ; 40..177 - знаки.
                                    ; если коды >=200:
                                    ; если установлен бит 6 - смещение от начала экрана, иначе - от текущей позиции
                                    ; если установлен бит 5 - закрашивать цветом фона, иначе - не закрашивать
                                    ; биты 4..0 - величина смещения.
                                    ; Если за концом строки слово 0 - то просто строка.
                                    ; Иначе - там может быть структура меню, которая начинает обрабатываться.

20$:            movb    (R0)+, R2   ; получим очередной символ
                bpl     1$          ; >= 0 ?
                bit     #100, R2    ; бит 6 есть?
                beq     2$          ; нет - перейдём
                add     #1000, R1   ; да - переход на новую строку
                bic     #77, R1
2$:             mov     R2, R3
                bic     #177740, R3 ; вычленим младшие 5 бит кода
                asl     R3
                beq     21$         ; если 0 - ничего более, только перевод строки
                bit     #40, R2     ; бит 5 есть?
                bne     3$          ; да, есть
                add     R3, R1      ; нет - значит мл.5 бит - смещение от начала строки
                br      20$
; ───────────────────────────────────────────────────────────────────────────

3$:             mov     R1, R5
5$:             mov     #10, R4
4$:             mov     BGCOLR, (R5) ; маска цвета фона
                add     #100, R5
                sob     R4, 4$      ; рисуем закрашенный цветом фона пробел
                tst     (R5)+
                sob     R3, 5$      ; и так по значению смещения
                br      21$
; ───────────────────────────────────────────────────────────────────────────

1$:             beq     22$         ; если 0, то строка кончилась
                cmpb    R2, #40
                blt     6$
                cmpb    R2, #100
                blo     7$
                cmpb    R2, #140
                bhis    7$
                add     OS$REG, R2  ; если код 100..137, то прибавим к нему флаг регистра
7$:             call    OUTCHR      ; Вход: R2 - код символа, R1 - адрес вывода
                br      20$
; ───────────────────────────────────────────────────────────────────────────

6$:             cmp     R2, #30     ; обработка кодов 1..37
                blt     8$
                cmp     R2, #33
                bhi     9$
                mov     #BGCOLR, R3 ; если коды 30..33, то адрес цвета фона
                br      10$
; ───────────────────────────────────────────────────────────────────────────

9$:             com     R2          ; если коды 34..37
                mov     #COLMSK, R3 ; то адрес маски цвета символов
10$:            bic     #177774, R2 ; получим номер цвета 0..3
                movb    COLTBL(R2),(R3) ; если 0 - то чёрный
                movb    (R3)+, (R3)     ; если 1 - то синий
                                        ; если 2 - то зелёный
                                        ; если 3 - то красный
                br      20$
; ───────────────────────────────────────────────────────────────────────────

8$:             dec     R2          ; обработка кодов 1..27
                bne     14$
                add     #1000, R1   ; код 1 - перевод строки относительно начальной позиции
                bic     #77, R1
                bic     #177700, R5
                bis     R5, R1
                br      21$
; ───────────────────────────────────────────────────────────────────────────

14$:            dec     R2
                bne     15$
                mov     #40000, R2  ; код 2 - закрасить экран цветом фона с адреса 40000
                br      16$
; ───────────────────────────────────────────────────────────────────────────

15$:            dec     R2
                bne     17$
                mov     #100000, R2 ; код 3 - закрасить экран цветом фона с адреса 100000
16$:            mov     #20000, R3
18$:            mov     BGCOLR, (R2)+
                sob     R3, 18$
                br      20$
; ───────────────────────────────────────────────────────────────────────────

17$:            dec     R2
                bne     19$
                clr     OS$REG      ; код 4 - лат.загл.буквы
19$:            dec     R2
                bne     20$
                mov     #100, OS$REG ; код 5 - лат.стр.буквы
                br      20$
; ───────────────────────────────────────────────────────────────────────────

22$:            inc     R0          ; всё, конец строки.
                bic     #1, R0      ; выравниваем
                tst     (R0)        ; что там дальше?
                beq     ENSTR$      ; 0 - всё, вывод только строки.
; End of function OUTSTR

                                    ; иначе - обработка структуры меню
; ███████████████ S U B R O U T I N E ███████████████████████████████████████
; Вход: R0 - адрес структуры меню.
; формат структуры меню:
; .word - адрес экрана, 0 - признак конца структуры меню
; .byte - ширина в словах
; .byte - маска выделения пункта меню
; .word - адрес подпрограммы пункта меню.
; .word - аргументы для п/п меню.
MNSUBR:         mov     R0, CurrMenuPt ; начало текущего обрабатываемого меню
39$:            call    SELMNU      ; Выделение пункта меню
                                    ; Вход: R0 - адрес структуры
38$:            call    INKEYM      ; получение кода нажатой клавиши с автоповтором.
                                    ; Выход: R5 - скан код.
                mov     CurrMenuPt, R4 ; начало текущего обрабатываемого меню
                mov     R0, R3      ; это текущий выделенный пункт меню
                cmp     R5, #10     ; стрелка влево?
                bne     31$         ; нет
                mov     #MNU$LT, MenuMovH ; будем двигаться влево
33$:            call    CheckMovH   ; найдём, куда можно подвинуться
                tst     R1          ; есть куда двигаться?
                beq     32$         ; нет.
                mov     (R0), R5    ; если есть, то это адрес экрана текущего выделенного пункта меню
                call    @MenuMovH
                add     #MenuItemLen, R4
                br      33$
; ───────────────────────────────────────────────────────────────────────────

32$:            cmp     R3, R0      ; если никуда не сдвинулись
                beq     38$         ; то ничего и не делаем
                mov     R3, -(SP)   ; это новый пункт
                call    SELMNU      ; Выделение пункта меню
                                    ; Вход: R0 - адрес структуры
                mov     (SP)+, R0   ; вот теперь новый пункт меню стал текущим
                br      39$
; ───────────────────────────────────────────────────────────────────────────

31$:            cmp     R5, #31     ; стрелка вправо?
                bne     34$         ; нет
                mov     #MNU$RT, MenuMovH ; будем двигаться вправо
                br      33$
; ───────────────────────────────────────────────────────────────────────────

34$:            cmp     R5, #32     ; стрелка вверх?
                bne     35$         ; нет
                mov     #MNU$UP, MenuMovV
36$:            call    CheckMovV
                tst     R1
                beq     32$
                mov     (R0), R5
                call    @MenuMovV
                add     #MenuItemLen, R4
                br      36$
; ───────────────────────────────────────────────────────────────────────────

35$:            cmp     R5, #33     ; стрелка вниз?
                bne     37$         ; нет
                mov     #MNU$DN, MenuMovV
                br      36$
; ───────────────────────────────────────────────────────────────────────────

37$:            cmpb    R5, #12     ; ввод?
                bne     38$         ; нет - остальные клавиши игнорируются
                mov     R0, -(SP)
                bit     (R0)+, (R0)+ ; переходим к адресу подпрограммы
                call    @(R0)+      ; выполняем
                mov     (SP)+, R0
                br      38$
MenuMovH:       .word   0           ; адрес функции перемещения по меню влево-вправо
MenuMovV:       .word   0           ; адрес функции перемещения по меню вверх-вниз

; ───────────────────────────────────────────────────────────────────────────
; на входе R5 - адрес экрана текущего меню
MNU$UP:         bic     #77, R5
                br      27634$
; ───────────────────────────────────────────────────────────────────────────
; на входе R5 - адрес экрана текущего меню
MNU$LT:         bic     #177700, R5 ; столбец выделенного пункта меню
27634$:         cmp     R5, R1      ; он левее цели?
                blos    1$          ; да - пропускаем
                cmp     R5, R2      ; равен самому себе?
                beq     2$          ; да - вроде бы должны пропустить
                cmp     R1, R2      ; цель левее текущего?
                blos    1$          ; да - пропускаем
2$:             mov     R4, R3      ; нет - вот, нашли, куда переместиться.
1$:                                 ; !!! чё-то хрень получилась, кажется комментарии тут неправильные
ENSTR$:         return

; ───────────────────────────────────────────────────────────────────────────
; на входе R5 - адрес экрана текущего меню
MNU$DN:         bic     #77, R5
                br      27660$
; ───────────────────────────────────────────────────────────────────────────
; на входе R5 - адрес экрана текущего меню
MNU$RT:         bic     #177700, R5
27660$:         cmp     R5, R1
                bhis    1$
                cmp     R5, R2
                beq     2$
                cmp     R1, R2
                bhis    1$
2$:             mov     R4, R3
1$:             return
; End of function MNSUBR

; ███████████████ S U B R O U T I N E ███████████████████████████████████████
; проверка, можно ли двигаться вертикально
; Вход: R4 - адрес начала структуры текущего обрабатываемого меню
;       R3 - адрес текущего элемента в структуре меню
; Выход: R1 - результат, 0 - некуда двигаться
;                       !0 - есть куда
CheckMovV:      mov     R5, -(SP)
                mov     R0, -(SP)
1$:             mov     (R4), R1    ; если структура меню закончилась
                beq     36616$      ; выход
                mov     (R3), R2    ; адрес экрана в текущем выделенном меню
                mov     R1, R0      ; адрес экрана текущего обрабатываемого пункта меню
                bic     #177700, R0 ; разбиваем на столбец
                bic     R0, R1      ; и строку
                mov     R2, R5      ; адрес экрана в текущем меню
                bic     #177700, R5 ; тоже разбиваем на столбец
                bic     R5, R2      ; и строку
                cmp     R5, R0      ; сравниваем столбцы
                beq     36616$      ; если равны - то выходим
                add     #MenuItemLen, R4 ; иначе - двигаемся к следующему элементу
                br      1$          ; и проверим его
; End of function CheckMovV

; ███████████████ S U B R O U T I N E ███████████████████████████████████████
; проверка, можно ли двигаться горизонтально
; Вход: R4 - адрес начала структуры текущего обрабатываемого меню
;       R3 - адрес текущего элемента в структуре меню
; Выход: R1 - результат, 0 - некуда двигаться
;                       !0 - есть куда - столбец экрана, куда.
;        R2 - столбец, откуда
CheckMovH:      mov     R5, -(SP)
                mov     R0, -(SP)
2$:             mov     (R4), R1    ; если структура меню закончилась
                beq     36616$      ; выход
                mov     (R3), R2    ; адрес экрана в текущем выделенном меню
                mov     R1, R0      ; адрес экрана текущего обрабатываемого пункта меню
                bic     #77, R0     ; разбиваем на строку
                bic     R0, R1      ; и столбец
                mov     R2, R5      ; адрес экрана в текущем меню
                bic     #77, R5     ; тоже разбиваем на строку
                bic     R5, R2      ; и столбец
                cmp     R0, R5      ; сравниваем строки
                beq     36616$      ; если равны - то выходим
                add     #MenuItemLen, R4 ; иначе - двигаемся к следующему элементу
                br      2$          ; и проверим его
; ───────────────────────────────────────────────────────────────────────────

36616$:         mov     (SP)+, R0
                mov     (SP)+, R5
                return
; End of function CheckMovH

; ███████████████ S U B R O U T I N E ███████████████████████████████████████
; Выделение пункта меню
; Вход: R0 - адрес структуры
SELMNU:         mov     R0, -(SP)
                mov     (R0)+, R1   ; адрес экрана
                movb    (R0)+, R2   ; ширина в словах
                clr     R3
                bisb    (R0), R3    ; маска выделения
                swab    R3
                bisb    (R0), R3    ; преобразуем байт в слово
1$:             mov     #11, R4     ; высота
2$:             xor     R3, (R1)
                add     #100, R1
                sob     R4, 2$
                sub     #1076, R1
                sob     R2, 1$
                mov     (SP)+, R0
                return
; End of function SELMNU

; ███████████████ S U B R O U T I N E ███████████████████████████████████████
; получение кода нажатой клавиши с автоповтором.
; Выход: R5 - скан код.
INKEYM:         mov     @#177662, R5
                mov     #10000, R4
3$:             bit     #100, @#177716
                bne     1$
                tstb    INKFL$
                bne     2$
                sob     R4, 3$
                incb    INKFL$
2$:             mov     #30000, R4
                sob     R4, .
                return
; ───────────────────────────────────────────────────────────────────────────

1$:             sob     R4, 3$
                clrb    INKFL$
4$:             tstb    @#177660
                bpl     4$
                mov     @#177662, R5
                return
; End of function INKEYM

; ███████████████ S U B R O U T I N E ███████████████████████████████████████
; вывод символа
; Вход: R2 - код символа, R1 - адрес вывода
OUTCHR:         mov     R0, -(SP)
                mov     R2, -(SP)
                mov     R3, -(SP)
                sub     #40, R2
                asl     R2
                asl     R2
                asl     R2
                asl     R2
                add     #RMFONT, R2
                mov     #10, R3
1$:             mov     BGCOLR, (R1)
                mov     (R2)+, R0
                bic     R0, (R1)
                bic     COLMSK, R0
                bis     R0, (R1)
                add     #100, R1
                sob     R3, 1$
                sub     #776, R1
                mov     (SP)+, R3
                mov     (SP)+, R2
                mov     (SP)+, R0
                return
; End of function OUTCHR

; затыкаем AY
IOTTRP:         mov     #362, @#177714 ; волпак
                clrb    @#177714
                mov     #370, @#177714 ; микшер
                clrb    @#177714
                rti
; ───────────────────────────────────────────────────────────────────────────
; прерывание по вектору 100 в меню и редакторе раздела
T100V:          call    @(PC)+
T100FN:         .word   0
                rti
; ───────────────────────────────────────────────────────────────────────────
; прерывание по вектору 100 в редакторе сэмплов
T100P:          tst     MUTEAY
                bne     1$
                call    PLYSMP
1$:             rti

; ███████████████ S U B R O U T I N E ███████████████████████████████████████
; выключаем звук AY
AYOFF:          mov     #TMRSPE, T100FN
AYOFF2:         movb    #377, AYREG1+Y.MIXR
                clrb    AYREG1+Y.VPCK
                iot
                return
; End of function AYOFF

; ───────────────────────────────────────────────────────────────────────────
; вход из хака
ENDHCK:         mov     #IOTTRP, @#20   ; обработчик IOT
; прерывание по вектору 4 и точка входа в программу.
TRP4:           mov     #RMPAL1 + 40000, @#177662 ; запрещаем прерывания от таймера
                mov     #100000, STADDR ; инициализируем оконный буфер
                mov     #STACKH, SP
                mov     #TRP4, @#4
                call    AYOFF           ; выключаем звук AY
                mov     #16000, @#NPAGE ; стр.5->окно0, стр.4->окно1
                call    SETPGE
                mov     #40000, R0
1$:             clr     (R0)+
                tst     R0
                bpl     1$
                mov     #0, @#102
                mov     #T100V, @#100
                mov     #RMPAL1, @#177662   ; разрешаем прерывания
                mov     #1330, @#177664
                call    DRWWIN  ; Нарисовать окно с рамкой без тени
                                ; Входные параметры:
                .word   40700+100000    ; Слово - адрес экрана, бит 15 - флаг, не сохранять содержимое под окном
                .byte   12      ; Байт - высота в символах
                .byte   40      ; Байт - ширина в символах
                .byte   0       ; Байт - маска цвета фона
                .byte   0       ; Байт - инверсная маска цвета символов
                mov     #T$MMNU, R0 ; Выводим на экран главное меню
                mov     #40700, R1
                call    OUTSTR  ; Вывод строки.
                                ; Вход: R0 - адрес строки, R1 - адрес экрана
                call    MIDWIN  ; выводим среднее окно - область редактора
                call    DRWWIN  ; Нарисовать окно с рамкой без тени
                                ; Входные параметры:
                .word   65000+100000    ; Слово - адрес экрана, бит 15 - флаг, не сохранять содержимое под окном
                .byte   12      ; Байт - высота в символах
                .byte   40      ; Байт - ширина в символах
                .byte   0       ; Байт - маска цвета фона
                .byte   0       ; Байт - инверсная маска цвета символов
                call    LOAOUT
J15700:         mov     #65016, R1
                mov     #T$SPAN, R0 ; выводим текст анализатора спектра, и затем приступаем к обработке главного меню.
                mtps    #0
                jmp     OUTSTR  ; Вывод строки.

; инициализация нотной страницы.
INITSN:         mov     #100000, R4
                mov     R4, R0
                mov     #17000, R1
1$:             clr     (R0)+
                sob     R1, 1$      ; очищаем всё, кроме сэмплов
                mov     R4, @#133000 ; адрес раздела
                mov     #40, R5
                mov     R5, @#133002 ; длина раздела
                call    S15240      ; помечаем конец раздела
                call    S15132      ; считаем количество разделов и что-то там ещё чистим
                mov     #134776, R1
                clr     (R1)        ; длина цепочки разделов мелодии = 0
                mov     #1, -(R1)   ; количество разделов в нотном тексте = 1
                mov     #2, -(R1)   ; темп исполнения = 2
                return
; инициализация сэмплов
INISAM:         mov     #136000,R0
                mov     #20,R1
2$:             mov     #7417,(R0)  ; зацикливание громкости
                mov     (R0)+,(R0)+ ; зацикливание тона
                clr     (R0)+       ; маска тона
                clr     (R0)+       ; маска шума
                mov     #7417,(R0)+ ; зацикливание шума
                mov     #33,R2
1$:             clr     (R0)+
                sob     R2, 1$
                sob     R1, 2$
                return


; ███████████████ S U B R O U T I N E ███████████████████████████████████████
; п/п куда делается переход из Load
LOAOUT:         call    S17556
; ███████████████ S U B R O U T I N E ███████████████████████████████████████
; выводим инфу о текущем разделе и ноты раздела
S11234:         call    S11110      ; выводим инфу
                mov     #7, R0
1$:             mov     R0, -(SP)
                call    S10334      ; заполняем нотами среднее окно
                mov     (SP)+, R0
                sob     R0, 1$
                return
; End of function S11234
; End of function LOAOUT
; ███████████████ S U B R O U T I N E ███████████████████████████████████████

S17556:         call    OUTFRE  ; выводим количество свободного места
                clr     R3
                call    S16020  ; вывод инфы о текущем разделе
                clr     CURPOS  ; Номер позиции в цепочке разделов
                call    OUTCPT  ; вывод инфы о позиции в цепочке разделов
; выводим количество разделов в музыке
SNDLEN:         mov     @#134776, R3    ; длина цепочки разделов мелодии
                inc     R3
                mov     #MMLENS, R0
                mov     #44724, R1
                jmp     OUT3NM  ; Вывод на экран трёхзначного числа.
                                ; Вход: R0 - адрес буфера, куда помещается строковое значение
                                ; R1 - адрес экрана
                                ; R3 - число
; ───────────────────────────────────────────────────────────────────────────
; End of function S17556

; вывод размера текущего раздела
OUTPLN:         mov     PLPTNR, R3
                call    S15504
                mov     133002(R0), R3
                br      006L$
; ███████████████ S U B R O U T I N E ███████████████████████████████████████
; вывод инфы о текущем разделе
S16020:         mov     R3, PLPTNR ; Номер паттерна, который будет проигрываться.
S16024:         mov     R3, CURPAT ; Номер текущего паттерна.
S16030:         call    S15504
                mov     133002(R0), R3
                mov     R3, -(SP)
                call    S11234  ; выводим инфу о текущем разделе и ноты раздела
                mov     (SP)+, R3
006L$:          asr     R3
                asr     R3
                dec     R3
S16056:         mov     #MMLEN, R0
                mov     #47724, R1
                call    OUT3NM  ; Вывод на экран трёхзначного числа.
                                ; Вход: R0 - адрес буфера, куда помещается строковое значение
                                ; R1 - адрес экрана
                                ; R3 - число
                mov     CURPAT, R3 ; Номер текущего паттерна.
                mov     #MMPTRN, R0 ; "000"
                mov     #46724, R1
                jmp     OUT3NM  ; Вывод на экран трёхзначного числа.
                                ; Вход: R0 - адрес буфера, куда помещается строковое значение
                                ; R1 - адрес экрана
                                ; R3 - число
; End of function

; ███████████████ S U B R O U T I N E ███████████████████████████████████████
; вывод инфы о позиции в цепочке разделов
OUTCPT:         mov     CURPOS, R3  ; Номер позиции в цепочке разделов
                inc     R3
                mov     R3, -(SP)
                mov     #41724, R1
                mov     #MMPOS, R0
                call    OUT3NM  ; Вывод на экран трёхзначного числа.
                                ; Вход: R0 - адрес буфера, куда помещается строковое значение
                                ; R1 - адрес экрана
                                ; R3 - число
                add     #772, R1
                mov     (SP)+, R4
                asl     R4
                movb    134776(R4), R3  ; раздел в цепочке разделов
                movb    134777(R4), R2  ; его высота
                mov     R2, -(SP)
                mov     #ACNPTN, R0
                call    OUT3NB
                add     #772, R1
                mov     (SP)+, R3
                mov     #ACNHGT, R0
                jmp     OUT3NB
; End of function OUTCPT

; ███████████████ S U B R O U T I N E ███████████████████████████████████████
; выводим количество свободного места
OUTFRE:         call    S15132
                mov     R5, R3
                mov     #D10BUF, R4
                call    S3164   ; преобразование числа в десятичную строку
                mov     #MMFREE, R0
                mov     #5, R3
                mov     #50724, R1
                add     #"00, (R4)
                inc     R4
                movb    (R4)+, (R0)+
                add     #"00, (R4)
                movb    (R4)+, (R0)+
                br      002J$
; End of function OUTFRE

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

OUT3NB:         bic     #177400, R3

; ███████████████ S U B R O U T I N E ███████████████████████████████████████
; Вывод на экран трёхзначного числа.
; Вход: R0 - адрес буфера, куда помещается строковое значение
; R1 - адрес экрана
; R3 - число
OUT3NM:         mov     #D10BUF, R4
                call    S3164   ; преобразование числа в десятичную строку
                mov     #3, R3
                add     R3, R4
                add     #"00, (R4)

002J$:          movb    (R4)+, (R0)+
                add     #"00, (R4)
                movb    (R4)+, (R0)+
                movb    (R4)+, (R0)+
                sub     R3, R0
                mov     TMPBGC, BGCOLR
                mov     TMPCLM, COLMSK
; вывод строки символов заданной длины.
; Вход R0 - адрес строки
;       R3 - длина строки
STROUT:         movb    (R0)+, R2
                call    OUTCHR  ; Вход: R2 - код символа, R1 - адрес вывода
                sob     R3, STROUT
                return
; End of function OUT3NM


; ███████████████ S U B R O U T I N E ███████████████████████████████████████
; подсчёт количества разделов в нотном тексте
S15132:         mov     #133000, R4
5$:             mov     (R4), R5
                bpl     1$
                cmp     R5, #132600
                blos    2$
1$:             mov     R4, -(SP)
                mov     -(R4), R5
                mov     -(R4), R4
                add     R5, R4
                add     R5, R4
                add     R5, R4
                mov     #132740, R5
                sub     R4, R5
3$:             clr     (R4)+
                cmp     R4, #133000
                blo     3$
                mov     (SP)+, R4
4$:             cmp     R4, #134770
                bhis    001LR$
                clr     (R4)+
                br      4$
; ───────────────────────────────────────────────────────────────────────────

2$:             cmp     R4, #134770
                bhis    1$
                cmp     (R4)+, (R4)+
                br      5$
; ───────────────────────────────────────────────────────────────────────────

S15230:         mov     PCPTBG, R4
                mov     PCPTLN, R5
S15240:         bic     #3, R5
                mov     R4, R0
                add     R5, R0
                mov     R0, R1
                add     R5, R1
                mov     R1, R2
                add     R5, R2
                mov     R2, R5
                sub     R4, R5
                mov     #-1, -(R2)
                mov     (R2), -(R2)
                mov     (R2), -(R1)
                mov     (R2), -(R1)
                mov     (R2), -(R0)
                mov     (R2), -(R0)
001LR$:         return
; End of function S15132

; ███████████████ S U B R O U T I N E ███████████████████████████████████████
; рисуем среднее окно
MIDWIN:         call    S15504
                call    MIDRKT      ; рисуем рамку среднего окна
                mov     #B37442, R0 ; выводим надписи каналов во втором окне
                mov     #53100, R1
                call    OUTSTR      ; Вывод строки.
                                    ; Вход: R0 - адрес строки, R1 - адрес экрана
                mov     #B37514, R0 ; выводим ещё что-то
                mov     #54100, R1
                jmp     OUTSTR      ; Вывод строки.
                                    ; Вход: R0 - адрес строки, R1 - адрес экрана
; End of function MIDWIN

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

S15504:         mov     #16000, @#NPAGE ; стр.5->окно0, стр.4->окно1
                call    SETPGE
                mov     PLPTNR, R0  ; Номер паттерна, который будет проигрываться.
S15522:         asl     R0
                asl     R0
                mov     133000(R0), TPTADR ; адрес начала раздела в массиве разделов
                return
; End of function S15522, S15504

; ███████████████ S U B R O U T I N E ███████████████████████████████████████
; рисуем рамку среднего окна
MIDRKT:         call    DRWWIN  ; Нарисовать окно с рамкой без тени
                                ; Входные параметры:
                .word   55100+100000    ; Слово - адрес экрана, бит 15 - флаг, не сохранять содержимое под окном
                .byte   11      ; Байт - высота в символах
                .byte   40      ; Байт - ширина в символах
                .byte   0       ; Байт - маска цвета фона
                .byte   252     ; Байт - инверсная маска цвета символов
                mov     #54110, R1
                mov     #B37314, R0
                call    OUTSTR  ; Вывод строки.
                                ; Вход: R0 - адрес строки, R1 - адрес экрана
                mov     #60000, R1  ; помечаем центр - указатель редактируемой ноты
                bis     #52000, 1000(R1)
                bis     #52000, (R1)+
                mov     #36, R0
1$:             mov     #52525, 1000(R1)
                mov     #52525, (R1)+
                sob     R0, 1$
                bis     #125, 1000(R1)
                bis     #125, (R1)+
                return
; End of function MIDRKT


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

S11110:         mov     TPTADR, R0
                mov     R0, PCPTBG
                clr     W37404
                clrb    W37404+2
                mov     R0, R1
1$:             cmpb    #377, (R0)
                beq     2$
                cmp     (R0)+, (R0)+
                br      1$
; ───────────────────────────────────────────────────────────────────────────

2$:             mov     R0, R3
                sub     R1, R3
                cmp     (R3)+, (R3)+
                mov     R3, PCPTLN
                sub     #14, R0
                sub     #14, R3
                mov     R0, PCPTAD
                asr     R3
                asr     R3
                tst     -(R3)

S11200:         mov     #D10BUF, R4
                call    S3164
                add     #3, R4
                mov     #W37404, R3
                movb    (R4)+, (R3)+
                movb    (R4)+, (R3)+
                movb    (R4)+, (R3)+
                return
; End of function S11110

; ███████████████ S U B R O U T I N E ███████████████████████████████████████
; преобразование числа в десятичную строку
; вход: R4 - адрес буфера вывода, R3 - число
S3164:          jsr     R5, @#PUSHA
                clr     R1
                clr     R2
                clr     R0
                mov     #15., R5
2$:             asl     R3
                bcs     1$
                sob     R5, 2$
                asl     R3
                br      3$
; ───────────────────────────────────────────────────────────────────────────

1$:             adc     R0
                asl     R0
                asl     R2
                asl     R1
                cmpb    #10., R0
                bhi     4$
                add     #366, R0
4$:             cmp     #5000, R0
                bhi     5$
                sub     #5000, R0
                inc     R2
5$:             cmpb    #10., R2
                bhi     6$
                add     #366, R2
6$:             cmp     #5000, R2
                bhi     7$
                sub     #5000, R2
                inc     R1
7$:             rol     R3
                sob     R5, 1$
3$:             adc     R0
                swab    R1
                swab    R2
                swab    R0
                mov     R1, (R4)+
                mov     R2, (R4)+
                mov     R0, (R4)+
                return
; End of function S3164

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

S11436:         call    SCRLDN
                call    S11420
                mov     CURNLN, R0
                sub     #4, R0
                bpl     1$
                add     R1, R0
1$:             dec     CURNLN
                bpl     2$
                add     R1, CURNLN
2$:             mov     R0, R3
                asl     R0
                asl     R0
                call    S11200
                add     PCPTBG, R0
                mov     #B37410, R1
                call    S10476
                mov     #55202, R1
                br      S10350
; End of function S11436


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

S11532:         call    SCRLUP
                call    S11420
                mov     CURNLN, R0
                add     #4, R0
                cmp     R1, R0
                bhi     1$
                sub     R1, R0
1$:             inc     CURNLN
                cmp     R1, CURNLN
                bhi     2$
                sub     R1, CURNLN
2$:             mov     R0, R3
                asl     R0
                asl     R0
                call    S11200
                add     PCPTBG, R0
                mov     #B37410, R1
                call    S10476
                br      10344$
; End of function S11532

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

S10334:         call    SCRLUP
                call    S10436
10344$:         mov     #63202, R1
S10350:         mov     #36, R5
                mov     #100, R4
                mov     #W37404, R2
1$:             movb    (R2)+, R0
                bmi     2$
                mov     R1, R3
                asl     R0
                asl     R0
                asl     R0
                asl     R0
                add     #RMPLFN+2, R0   ; фонт для быстрой генерации нотных символов
                mov     (R0)+, (R3)
                add     R4, R3
                mov     (R0)+, (R3)
                add     R4, R3
                mov     (R0)+, (R3)
                add     R4, R3
                mov     (R0)+, (R3)
                add     R4, R3
                mov     (R0)+, (R3)
2$:             tst     (R1)+
                sob     R5, 1$
                return
; End of function S10334

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

SCRLUP:         mov     #56200, R0
                mov     #55200, R1
                mov     #300, R4
                mov     #6, R3
1$:             mov     #5, R2
2$:             mov     (R0)+, (R1)+
                mov     (R0)+, (R1)+
                mov     (R0)+, (R1)+
                mov     (R0)+, (R1)+
                mov     (R0)+, (R1)+
                mov     (R0)+, (R1)+
                mov     (R0)+, (R1)+
                mov     (R0)+, (R1)+
                mov     (R0)+, (R1)+
                mov     (R0)+, (R1)+
                mov     (R0)+, (R1)+
                mov     (R0)+, (R1)+
                mov     (R0)+, (R1)+
                mov     (R0)+, (R1)+
                mov     (R0)+, (R1)+
                mov     (R0)+, (R1)+
                mov     (R0)+, (R1)+
                mov     (R0)+, (R1)+
                mov     (R0)+, (R1)+
                mov     (R0)+, (R1)+
                mov     (R0)+, (R1)+
                mov     (R0)+, (R1)+
                mov     (R0)+, (R1)+
                mov     (R0)+, (R1)+
                mov     (R0)+, (R1)+
                mov     (R0)+, (R1)+
                mov     (R0)+, (R1)+
                mov     (R0)+, (R1)+
                mov     (R0)+, (R1)+
                mov     (R0)+, (R1)+
                mov     (R0)+, (R1)+
                mov     (R0)+, (R1)+
                sob     R2, 2$
                add     R4, R0
                add     R4, R1
                sob     R3, 1$
                return
; End of function SCRLUP

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

SCRLDN:         mov     #63676, R1
                mov     #62676, R0
                mov     #300, R4
                mov     #6, R3
1$:             mov     #5, R2
2$:             mov     -(R0), -(R1)
                mov     -(R0), -(R1)
                mov     -(R0), -(R1)
                mov     -(R0), -(R1)
                mov     -(R0), -(R1)
                mov     -(R0), -(R1)
                mov     -(R0), -(R1)
                mov     -(R0), -(R1)
                mov     -(R0), -(R1)
                mov     -(R0), -(R1)
                mov     -(R0), -(R1)
                mov     -(R0), -(R1)
                mov     -(R0), -(R1)
                mov     -(R0), -(R1)
                mov     -(R0), -(R1)
                mov     -(R0), -(R1)
                mov     -(R0), -(R1)
                mov     -(R0), -(R1)
                mov     -(R0), -(R1)
                mov     -(R0), -(R1)
                mov     -(R0), -(R1)
                mov     -(R0), -(R1)
                mov     -(R0), -(R1)
                mov     -(R0), -(R1)
                mov     -(R0), -(R1)
                mov     -(R0), -(R1)
                mov     -(R0), -(R1)
                mov     -(R0), -(R1)
                mov     -(R0), -(R1)
                mov     -(R0), -(R1)
                mov     -(R0), -(R1)
                mov     -(R0), -(R1)
                sob     R2, 2$
                sub     R4, R0
                sub     R4, R1
                sob     R3, 1$
                return
; End of function SCRLDN

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

S11420:         mov     PCPTLN, R1
                sub     #4, R1
                asr     R1
                asr     R1
                return
; End of function S11420


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

S10436:         mov     #B37410, R1
                mov     R1, R2
                inc     -(R2)
                cmpb    (R2), #10.
                blo     1$
                clrb    (R2)
                incb    -(R2)
                cmpb    (R2), #10.
                blo     1$
                clrb    (R2)
                incb    -(R2)
1$:             mov     PCPTAD, R0
S10476:         mov     R0, R5
                call    S10554  ; выводим текстовое представление ноты в канал A
                call    S10554  ; выводим текстовое представление ноты в канал B
                call    S10554  ; выводим текстовое представление ноты в канал C
                add     #4, PCPTAD ; адрес следующей ноты
                return
; End of function S10436

; ███████████████ S U B R O U T I N E ███████████████████████████████████████
; выводим текстовое представление ноты в канал
; вход:  R0 - адрес текущей ноты в текущем канале
;       R1 - адрес буфера
; 012345670
; nnn_sv.._
;       R5 - адрес в разделе начала ноты канала A
S10554:         movb    (R0), R3    ; берём номер ноты
                bmi     1$          ; переход - если у V отсутствует параметр
                movb    3(R0), R4   ; нет, параметр есть - берём период огибающей или длительность ноты
                mov     R4, R2      ; разобьём параметр
                bic     #360, R4    ; мл. 4 бита
                bic     R4, R2      ; ст. 4 бита
                asr     R2
                asr     R2
                asr     R2
                asr     R2
                br      2$
; ───────────────────────────────────────────────────────────────────────────
; внезапный конец раздела?
7$:             cmp     R0, R5      ; это мы в канале A такое встретили?
                bne     14$         ; нет - просто посчитаем это паузой
                mov     PCPTBG, R0  ; адрес начала текущего раздела
                mov     R0, PCPTAD  ; указатель адреса в текущем разделе
                clr     W37404      ; а если в канале A, то
                clrb    W37404+2    ; переместимся к началу раздела
                br      S10554      ; и отобразим первую ноту.
                ; потому что это какая-то нештатная ситуация
; ───────────────────────────────────────────────────────────────────────────

1$:             movb    #23, R2     ; символ точки
                mov     R2, R4      ; тоже точка
2$:             bic     #177600, R3 ; у ноты сбрасываем бит 7
                bne     3$          ; если не пауза - переход
14$:            movb    #26, (R1)+  ; знак паузы 'R'
                br      4$
; ───────────────────────────────────────────────────────────────────────────

3$:             cmpb    #176, R3    ; нота отсутствует?
                bne     5$          ; нет - переход
                movb    #21, (R1)+  ; да - знак '-'
4$:             movb    #21, (R1)+  ; ставим ещё два прочерка
                movb    #21, (R1)+
                inc     R1
                movb    #23, (R1)+  ; и затем 4 точки
                movb    #23, (R1)+
                movb    #23, (R1)+
                movb    #23, (R1)+
                br      6$          ; всё
; ───────────────────────────────────────────────────────────────────────────

5$:             cmpb    #177, R3    ; нота есть, а не конец ли раздела?
                beq     7$          ; да - конец
                movb    R2, 6(R1)   ; v или ст.4 бит периода
                movb    R4, 7(R1)   ; длит.ноты или мл.4 бит периода
                clr     R2
                dec     R3          ; из номера ноты сделаем
8$:             inc     R2          ; ноту и октаву
                sub     #12., R3
                bpl     8$
                add     #12., R3
                asl     R3
                add     #B10524, R3 ; формируем ноту
                movb    (R3)+, (R1)+
                movb    (R3)+, (R1)+
                movb    R2, (R1)+   ; и октаву
                inc     R1          ; пропустим разделитель
                movb    1(R0), R3   ; байт атрибутов
                bpl     9$          ; volume есть?
                movb    #24, 2(R1)  ; да есть - ставим знак V
9$:             movb    2(R0), R4   ; байт параметров
                mov     R4, R2
                bic     #360, R4    ; громкость
                bic     R4, R2      ; номер сэмпла
                asr     R2
                asr     R2
                asr     R2
                asr     R2
                bit     #40, R3     ; номер сэмпла присутствует?
                beq     10$         ; да - переход
                movb    #23, (R1)+  ; нет - ставим прочерк
                br      11$
; ───────────────────────────────────────────────────────────────────────────

10$:            movb    R2, (R1)+   ; ставим номер сэмпла
11$:            bit     #100, R3    ; громкость присутствует?
                beq     12$         ; да - переход
                movb    #23, (R1)+  ; нет - ставим прочерк
                br      13$
; ───────────────────────────────────────────────────────────────────────────

12$:            movb    R4, (R1)+   ; ставим громкость
13$:            tst     (R1)+       ; пропускаем вторые два параметра - их задали ранее
6$:             inc     R1          ; промежуток между каналами
                add     PCPTLN, R0  ; переходим к следующей ноте канала
                return
; End of function S10554

; ███████████████████████████████████████████████████████████████████████████
; ███████████████ ФУНКЦИИ ГЛАВНОГО МЕНЮ █████████████████████████████████████
; ███████████████████████████████████████████████████████████████████████████

; Меню PATTERN Down. Выбор номера редактируемого паттерна
M$PTDN:         mov     CURPAT, R3
                dec     R3
                bpl     16020$
                mov     @#134774, R3    ; количество разделов в нотном тексте
L16110:         mov     R3, CURPAT  ; Номер текущего паттерна.
                clr     R3
                jmp     S16056
; ───────────────────────────────────────────────────────────────────────────
; Меню PATTERN Up. Выбор номера редактируемого паттерна
M$PTUP:         mov     CURPAT, R3
                inc     R3

S16006:         cmp     R3, @#134774    ; количество разделов в нотном тексте
                beq     L16110
                blo     16020$
                clr     R3
16020$:         jmp     S16020

RETG$:          return
; ───────────────────────────────────────────────────────────────────────────
; Меню  "PATTERN". Редактировать выбранный паттерн
M$PTRN:         mov     CURPAT, R3
                cmp     R3, @#134774    ; Сравниваем номер паттерна с макс.количеством
                blo     4$          ; если меньше - то идём редактировать
                cmp     R3, #377    ; резервируем место под новый паттерн
                bhis    RETG$       ; если места нету
                call    S15132
                cmp     R5, #200
                blo     RETG$       ; то выходим
                mov     R3, R4      ; иначе резервируем
                mov     R3, @#134774    ; количество разделов в нотном тексте
                inc     @#134774
                asl     R4
                asl     R4
                add     #133000, R4
                cmp     -(R4), -(R4)
                mov     (R4)+, R1
                mov     (R4)+, R2
                add     R2, R1
                asl     R2
                add     R2, R1
                mov     R1, (R4)+
                mov     #40, (R4)+
                mov     #60, R2
5$:             clr     (R1)+
                sob     R2, 5$
                ; редактирование
4$:             mov     R3, PLPTNR ; Номер паттерна, который будет проигрываться.
                sub     #6, R0
                call    SELMNU  ; Выделение пункта меню
                                ; Вход: R0 - адрес структуры
                call    OUTFRE  ; обновляем информацию о свободном месте
                call    OUTPLN  ; обновляем информацию о размере раздела
                mov     #15000, @#NPAGE ; стр.5->окно0, стр.2->окно1
                mov     #16000, @#177716    ; стр.5->окно0, стр.4->окно1
                mov     #100000, TPTADR
                mov     PLPTNR, R0
                asl     R0
                asl     R0
                add     #133000, R0
                mov     (R0)+, R4
                mov     (R0)+, R5
                call    S15240      ; помечаем конец раздела
                mov     R5, -(SP)
                asr     R5
                mov     #40000, R3
                mtps    #340
                mov     #26000, @#177716    ; стр.2->окно0, стр.4->окно1
1$:             mov     (R4)+, (R3)+
                sob     R5, 1$              ; переносим текущий раздел в стр.2
                mov     #76000, R4
2$:             mov     40000(R4), (R4)+    ; и сэмплы тоже
                tst     R4
                bpl     2$
                mov     @#134772,@#74772    ; копируем темп. Или нужно обнулять?
                call    S15132
                call    SETPGE              ; раздел редактировать будем во второй странице.
                mtps    #0
                add     (SP)+, R5
                mov     R5, R1
                mov     #3, R2
                call    DIVIDE
                dec     R1
                bic     #3, R1
                cmp     R1, #7600   ; константа, максимальная длина раздела
                blos    3$
                mov     #7600, R1
3$:             mov     R1, W14034
                mov     #STACKH, SP
; ───────────────────────────────────────────────────────────────────────────
; функция обработки клавиатуры в редакторе разделов
; ───────────────────────────────────────────────────────────────────────────
PKEYPR:         call    S11234  ; выводим инфу о текущем разделе и ноты раздела
                iot
                clr     CURNLN
3$:             call    KURSOR
                call    GETCHR  ; получение кода нажатой клавиши с автоповтором.
                                ; синхронизация с таймером 50Гц
                                ; Выход: R0 - код
5$:             mov     #KEYCDS,R1
                mov     #KEYFUN,R5
2$:             tstb    (R1)
                bmi     7$
                cmpb    (R1)+, R0
                beq     1$
                TST     (R5)+
                br      2$

7$:             call    KURSOR
                call    KNOTES  ; проверка нотных клавиш и ввод нот
                br      3$

1$:             call    KURSOR
                call    @(R5)+
                br      3$  ; обычный выход из подпрограммы
                br      5$  ; выход из подпрограммы для ТАБ
; ───────────────────────────────────────────────────────────────────────────
KEYCDS:         .byte   32      ; стрелка вверх
                .byte   33      ; стрелка вниз
                .byte   10      ; стрелка влево
                .byte   31      ; стрелка вправо
                .byte   11      ; Таб - проигрывание текущей ноты по трем каналам
                .byte   16      ; Рус - назад на 7 нот
                .byte   17      ; Лат - вперёд на 7 нот
                .byte   0       ; Шаг - переход на нулевую ноту
                .byte   14      ; Сбр - очистка всех нот в одном канале
                .byte   13      ; -|-> - очистка от текущей ноты до конца в одном канале
                .byte   26      ; Сдвижка в строке - сдвижка по всем каналам, изменяет размер раздела
                .byte   2       ; Инд.Су - сдвижка в одном канале, размер раздела не изменяется
                .byte   27      ; раздвижка в строке - раздвижка по всем каналам, изменяет размер раздела
                .byte   4       ; Блок.Ред - раздвижка в одном канале,  размер раздела не изменяется
                .byte   1       ; Повт - копирование текущей ноты на следующую в одном голосе
                .byte   3       ; КТ - конец редактирования
                .byte   377     ; конец списка кодов клавиш
                .even

KEYFUN:         .word   S11436  ; стрелка вверх
                .word   S11532  ; стрелка вниз
                .word   KKEYLT  ; стрелка влево
                .word   KKEYRT  ; стрелка вправо
                .word   KKEYTB  ; Таб - проигрывание текущей ноты по трём каналам
                .word   KKEYRU  ; Рус - назад на 7 нот
                .word   KKEYEN  ; Лат - вперёд на 7 нот
                .word   KKEYST  ; Шаг - переход на нулевую ноту
                .word   KKESBR  ; Сбр - очистка всех нот в одном канале
                .word   KKERRT  ; -|-> - очистка от текущей ноты до конца в одном канале
                .word   KKEDEL  ; Сдвижка в строке - сдвижка по всем каналам, изменяет размер раздела
                .word   KKEISU  ; Инд.Су - сдвижка в одном канале, размер раздела не изменяется
                .word   KKEINS  ; раздвижка в строке - раздвижка по всем каналам, изменяет размер раздела
                .word   KKEBLR  ; Блок.Ред - раздвижка в одном канале,  размер раздела не изменяется
                .word   KKEREP  ; Повт - копирование текущей ноты на следующую в одном голосе
                .word   KKEYKT  ; КТ - конец редактирования
; ───────────────────────────────────────────────────────────────────────────
; стрелка влево
KKEYLT:         mov     #B11752, R5
                mov     #6, R4
                mov     KURSAD, R1
                cmp     R1, #60212
                beq     0$
3$:             sub     #2, R1
4$:             cmpb    R1, (R5)+
                beq     3$
                sob     R4, 4$
                mov     R1, KURSAD
0$:             return
; стрелка вправо
KKEYRT:         mov     #B11752, R5
                mov     #6, R4
                mov     KURSAD, R1
                cmp     R1, #60274
                beq     0$
7$:             add     #2, R1
8$:             cmpb    R1, (R5)+
                beq     7$
                sob     R4, 8$
                mov     R1, KURSAD
0$:             return
; ───────────────────────────────────────────────────────────────────────────
B11752:         .byte   210 ; участки для передвижения влево-вправо
                .byte   220
                .byte   232
                .byte   242
                .byte   254
                .byte   264
; ───────────────────────────────────────────────────────────────────────────
; проверка нотных клавиш и ввод нот
KNOTES:         call    KSUB1
                dec     R1  ; ноту вводить можно?
                bgt     14$ ; нет
                mov     #NOTKEY, R4 ; Нотные клавиши
                mov     #12., R2
20$:            cmpb    R0, (R4)+   ; проверяем, ввели ли ноту
                beq     19$     ; да - обработает
                sob     R2, 20$
                ; нет, но ещё можно и другие вещи
                cmpb    R0, #12     ; ввод
                bne     13$
                bic     #177, (R3)
                br      12$
; ───────────────────────────────────────────────────────────────────────────

13$:            cmpb    R0, #40     ; пробел
                bne     02LR$
                bisb    #177, (R3)
                decb    (R3)
                br      12$
; ───────────────────────────────────────────────────────────────────────────
                ; вводим ноту
19$:            dec     R2
                movb    (R3), R1
                bic     #177600, R1
                beq     21$
                bicb    R1, (R3)
                cmpb    R1, #176
                bne     22$
21$:            mov     #1, R1
22$:            mov     R3, -(SP)
                mov     R2, -(SP)
                mov     R1, -(SP)
                dec     R1
                mov     #14, R2
                call    DIVIDE
                mov     (SP)+, R1
                sub     R3, R1
                mov     (SP)+, R2
                add     R2, R1
                mov     (SP)+, R3
                bisb    R1, (R3)

12$:            mov     #-1, W37404
                movb    #377, W37404+2
                mov     R5, R0
                mov     #B37410, R1
                call    S10476
                mov     #60202, R1
                call    S10350
02LR$:          return
; ───────────────────────────────────────────────────────────────────────────
                ; ноту вводить нельзя, но можно другое
14$:            dec     R1
                bne     17$
                cmpb    R0, #'1     ; выбор октавы
                blo     02LR$
                cmpb    R0, #'8
                bhi     02LR$
                sub     #'1, R0
                movb    (R3), R1
                bic     #177600, R1
                beq     02LR$
                cmpb    R1, #176
                beq     02LR$
                bicb    R1, (R3)
                mov     R0, R4
                mov     R3, -(SP)
                mov     #14, R2
                dec     R1
                call    DIVIDE
                tst     R4
                beq     15$
16$:            add     #14, R3
                sob     R4, 16$
15$:            inc     R3
                bisb    R3, @(SP)+
                br      12$

17$:            tst     (R3)+
                dec     R1
                dec     R1
                bne     2$
                cmpb    R0, #40
                bne     1$
                bisb    #40, -1(R3)
                br      12$
; ───────────────────────────────────────────────────────────────────────────

1$:             bicb    #40, -1(R3)
11$:            call    S12440  ; из 16ричной цифры получим значение.
                                ; Вход: R0 - цифра 0..9, A..F
                                ; Выход: если все правильно, то R0 - значение 0..15.
                                ; иначе - R0 без изменений
                                ; и делается выход из п/п в которой используется вызов
                asl     R0
                asl     R0
                asl     R0
                asl     R0
                bicb    #360, (R3)
                bisb    R0, (R3)
                br      12$
; ───────────────────────────────────────────────────────────────────────────

2$:             dec     R1
                bne     4$
                cmpb    R0, #40
                bne     3$
                bisb    #100, -1(R3)
                br      12$
; ───────────────────────────────────────────────────────────────────────────

3$:             bicb    #100, -1(R3)
10$:            call    S12440  ; из 16ричной цифры получим значение.
                                ; Вход: R0 - цифра 0..9, A..F
                                ; Выход: если все правильно, то R0 - значение 0..15.
                                ; иначе - R0 без изменений
                                ; и делается выход из п/п в которой используется вызов
                bicb    #17, (R3)
                bisb    R0, (R3)
9$:             br      12$
; ───────────────────────────────────────────────────────────────────────────

4$:             inc     R3
                dec     R1
                bne     5$
                cmpb    R0, #40
                bne     6$
                bicb    #200, -2(R3)
8$:             bisb    #200, -3(R3)
                br      9$
; ───────────────────────────────────────────────────────────────────────────

6$:             cmpb    R0, #126
                bne     7$
                bisb    #200, -2(R3)
                br      9$
; ───────────────────────────────────────────────────────────────────────────

7$:             bicb    #200, -2(R3)
                bicb    #200, -3(R3)
                br      11$
; ───────────────────────────────────────────────────────────────────────────

5$:             cmpb    R0, #40
                beq     8$
                bicb    #200, -3(R3)
                br      10$

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

; из 16ричной цифры получим значение.
; Вход: R0 - цифра 0..9, A..F
; Выход: если все правильно, то R0 - значение 0..15.
; иначе - R0 без изменений
; и делается выход из п/п в которой используется вызов
S12440:         cmpb    R0, #'0
                blo     1$
                cmpb    R0, #'9
                blos    2$
                cmpb    R0, #'A
                blo     1$
                cmpb    R0, #'F
                blos    3$
1$:             tst     (SP)+
                return
; ───────────────────────────────────────────────────────────────────────────

2$:             sub     #'0, R0
                return

3$:             sub     #67, R0
                return
; End of function S12440

; Таб - проигрывание текущей ноты по трем каналам
KKEYTB:         call    KSUB1
                mov     R5, W22614
                call    KURSOR
13$:            clr     NEWCH$
                mov     #L26364, T100FN
                call    S22604
12$:            call    GETCHR  ; получение кода нажатой клавиши с автоповтором.
                                ; синхронизация с таймером 50Гц
                                ; Выход: R0 - код
                tst     NEWCH$
                beq     12$
                cmpb    #11, R0     ; Таб
                beq     13$
                call    AYOFF   ; выключаем звук AY
                ADD     #2,(SP)
                return

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

S22604:         mov     #VARPR1, R5
                mov     W22614, R0
                mtps    #340
                mov     R0, L.ACHN(R5)
                add     PCPTLN, R0
                mov     R0, CHPLN+L.ACHN(R5)
                add     PCPTLN, R0
                mov     R0, CHPLN+CHPLN+L.ACHN(R5)
                mov     #L22706, F21002
                call    GETNT1      ; чтение очередной ноты в канале, там с темпом непонятка. он в странице 2 обнуляется или это ошибка?
                add     #CHPLN, R5
                call    GETNT1      ; чтение очередной ноты в канале
                add     #CHPLN, R5
                call    GETNT1      ; чтение очередной ноты в канале
                mtps    #0
                return
; End of function S22604

; Рус - назад на 7 нот
KKEYRU:         mov     #7, R0
2$:             mov     R0, -(SP)
                call    S11436
                mov     (SP)+, R0
                sob     R0, 2$
                return
; Лат - вперёд на 7 нот
KKEYEN:         mov     #7, R0
3$:             mov     R0, -(SP)
                call    S11532
                mov     (SP)+, R0
                sob     R0, 3$
                return

KSUB1:          mov     KURSAD, R1
                mov     PCPTBG, R3
                mov     R3, R5
                sub     #60212, R1
                asr     R1
                cmp     R1, #11
                blo     9$
                add     PCPTLN, R3
                sub     #11, R1
                cmp     R1, #11
                blo     9$
                add     PCPTLN, R3
                sub     #11, R1
9$:             mov     CURNLN, R2
                asl     R2
                asl     R2
                add     R2, R3
                add     R2, R5
                return

; Сбр - очистка всех нот в одном канале
KKESBR:         mov     SP, BF$SPC
                call    KSUB1
                mov     KURSAD, R0
                movb    #'A, R4
                cmpb    R0, #232
                blo     2$
                cmpb    R0, #254
                blo     1$
                inc     R4
1$:             inc     R4
2$:             sub     R2, R3
                movb    R4, V$CRCH
                mov     R3, W13210
                call    DRWWNH  ; Нарисовать окно с рамкой с тенью
                                ; Входные параметры:
                .word   62020   ; Слово - адрес экрана, бит 15 - флаг, не сохранять содержимое под окном
                .byte   6       ; Байт - высота в символах
                .byte   20      ; Байт - ширина в символах
                .byte   125     ; Байт - маска цвета фона
                .byte   0       ; Байт - инверсная маска цвета символов
                mov     #63432, R1
                mov     #T$RESE, R0
                jmp     OUTSTR  ; Вывод строки.
                                ; Вход: R0 - адрес строки, R1 - адрес экрана
; ───────────────────────────────────────────────────────────────────────────
; подтверждение Reset Channel
YERSCH:         call    RESWND  ; Восстановление области экрана из буфера
                mov     W13210, R1
                mov     PCPTLN, R2
1$:             clrb    (R1)+
                sob     R2, 1$
                mov     #-1, -(R1)
                mov     (R1), -(R1)
                mov     BF$SPC, SP  ; выходим из обработчика меню
; Шаг - переход на нулевую ноту
KKEYST:         clr     CURNLN
                jmp     S11234  ; выводим инфу о текущем разделе и ноты раздела

; ───────────────────────────────────────────────────────────────────────────
; -|-> - очистка от текущей ноты до конца в одном канале
KKERRT:         mov     SP, BF$SPC
                call    KSUB1
                mov     KURSAD, R0
                movb    #'A, R4
                cmpb    R0, #232
                blo     2$
                cmpb    R0, #254
                blo     1$
                inc     R4
1$:             inc     R4
2$:             movb    R4, V$ERCH
                mov     R3, W13360
                sub     R2, R3
                add     PCPTLN, R3
                mov     R3, W13372
                call    DRWWNH  ; Нарисовать окно с рамкой с тенью
                                ; Входные параметры:
                .word   62020   ; Слово - адрес экрана, бит 15 - флаг, не сохранять содержимое под окном
                .byte   6       ; Байт - высота в символах
                .byte   20      ; Байт - ширина в символах
                .byte   125     ; Байт - маска цвета фона
                .byte   0       ; Байт - инверсная маска цвета символов
                mov     #63424, R1
                mov     #T$ERTN, R0
                jmp     OUTSTR  ; Вывод строки.
                                ; Вход: R0 - адрес строки, R1 - адрес экрана
; ───────────────────────────────────────────────────────────────────────────
; Подтверждение очистки до конца канала
YEERTE:         call    RESWND  ; Восстановление области экрана из буфера
                mov     W13372, R1
                mov     W13360, R2
                mov     #-1, -(R1)
                mov     (R1), -(R1)
1$:             clrb    -(R1)
                cmp     R1, R2
                bhi     1$
                mov     #7, R0
2$:             mov     R0, -(SP)
                call    S11436
                wait
                mov     (SP)+, R0
                sob     R0, 2$
                mov     #7, R0
3$:             mov     R0, -(SP)
                call    S11532
                wait
                mov     (SP)+, R0
                sob     R0, 3$
                mov     BF$SPC, SP  ; выходим из обработчика меню
                return
; ───────────────────────────────────────────────────────────────────────────
; отказ делать Reset Channel
; отказ делать очистку до конца канала
NORSCH:         call    RESWND  ; Восстановление области экрана из буфера
                mov     BF$SPC, SP  ; выходим из обработчика меню
                return

; ───────────────────────────────────────────────────────────────────────────
; КТ - конец редактирования
KKEYKT:         mov     #STACKH, SP
                mtps    #340
                call    S15230
                mov     #26000, @#177716    ; стр.2->окно0, стр.4->окно1
                mov     PLPTNR, R0 ; Номер паттерна, который будет проигрываться.
                asl     R0
                asl     R0
                add     #133000, R0
                mov     (R0)+, R1
                mov     (R0)+, R2
                mov     PCPTLN, -(R0)
                bic     #3, (R0)
                bic     #3, R2
                mov     R1, R3
                mov     R2, -(SP)
                asl     R2
                add     (SP)+, R2
                add     R2, R1
                mov     R5, R4
                sub     R2, R4
                bhi     5$
                mov     #40000, R4
                asr     R5
1$:             mov     (R4)+, (R3)+
                sob     R5, 1$
2$:             mov     (R1)+, (R3)+
                cmp     R1, #133000
                blo     2$
8$:             mov     #133000, R0
3$:             mov     (R0)+, R1
                mov     (R0)+, R2
                add     R2, R1
                asl     R2
                add     R2, R1
                tst     (R0)
                beq     4$
                mov     R1, (R0)
                cmp     R0, #134776 ; длина цепочки разделов мелодии
                blo     3$
4$:             call    S16030
                call    OUTFRE
                jmp     J15700
; ───────────────────────────────────────────────────────────────────────────

5$:             mov     #133000, R0
                neg     R4
                add     R0, R4
6$:             mov     -(R4), -(R0)
                cmp     R4, R1
                bhi     6$
                mov     #40000, R4
                asr     R5
7$:             mov     (R4)+, (R3)+
                sob     R5, 7$
                br      8$
; ───────────────────────────────────────────────────────────────────────────

; Инд.Су - сдвижка в одном канале, размер раздела не изменяется
KKEISU:         call    KSUB1
                call    S14366
                beq     LR01$
                sub     R2, R3
                mov     R3, R0
                call    S13552
                clr     -(R0)
                clr     -(R0)
                br      14232$
; ───────────────────────────────────────────────────────────────────────────
; Сдвижка в строке - сдвижка по всем каналам, изменяет размер раздела
KKEDEL:         call    KSUB1
                cmp     PCPTLN, #40
                blos    LR01$
                call    S14366
                beq     LR01$
                mov     PCPTBG, R5
                call    S13550
                mov     R5, -(SP)
                call    S13550
                mov     R5, -(SP)
                call    S13550
                mov     PCPTLN, R1
                cmp     -(R1), -(R1)
                asr     R1
                mov     (SP)+, R4
                mov     (SP)+, R3
                mov     R3, R2
                mov     R1, R0
                cmp     -(R2), -(R2)
1$:             mov     (R3)+, (R2)+
                sob     R1, 1$
2$:             mov     (R4)+, (R2)+
                sob     R0, 2$
                call    S16406
                br      14232$
; ───────────────────────────────────────────────────────────────────────────
; Блок.Ред - раздвижка в одном канале,  размер раздела не изменяется
KKEBLR:         call    KSUB1
                sub     R2, R3
                mov     R3, R0
                call    S13762
                br      14232$
; ───────────────────────────────────────────────────────────────────────────
; раздвижка в строке - раздвижка по всем каналам, изменяет размер раздела
KKEINS:         call    KSUB1
                mov     PCPTLN, R1
                cmp     R1, W14034
                bhis    LR01$
                mov     PCPTBG, R4
                add     R1, R4
                asl     R1
                add     R1, R4
                mov     R4, R3
                add     #10, R4
                asr     R1
                asr     R1
                mov     R1, R0
1$:             mov     -(R3), -(R4)
                sob     R1, 1$
                cmp     -(R4), -(R4)
2$:             mov     -(R3), -(R4)
                sob     R0, 2$
                call    S16416
                mov     PCPTBG, R5
                call    S13760
                call    S13760
                call    S13760
                br      14232$
LR01$:          return

; ───────────────────────────────────────────────────────────────────────────
; Повт - копирование текущей ноты на следующую в одном голосе
KKEREP:         call    KSUB1
                call    S14366
                beq     LR01$
                mov     (R3)+, 2(R3)
                mov     (R3)+, 2(R3)
                inc     CURNLN

14232$:         call    S11420
                mov     CURNLN, R0
                sub     #3, R0
                bpl     1$
                add     R1, R0
1$:             mov     #55202, R2
                mov     #7, R5
2$:             mov     R2, -(SP)
                mov     R5, -(SP)
                mov     R1, -(SP)
                mov     R0, -(SP)
                mov     R0, R3
                asl     R0
                asl     R0
                call    S11200
                add     PCPTBG, R0
                mov     #B37410, R1
                call    S10476
                mov     6(SP), R1
                call    S10350
                mov     (SP)+, R0
                mov     (SP)+, R1
                mov     (SP)+, R5
                inc     R0
                cmp     R1, R0
                bhi     3$
                sub     R1, R0
3$:             mov     (SP)+, R2
                add     #1000, R2
                sob     R5, 2$
                return


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

S14366:         cmpb    4(R3), #377
                return
; End of function S14366

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

S13550:         mov     R5, R0
S13552:         mov     R0, R4
                add     R2, R0
                add     PCPTLN, R4
                mov     R4, R5
                sub     #10, R4
1$:             mov     4(R0), (R0)+
                cmp     R0, R4
                blo     1$
                mov     #-1, (R0)
                mov     (R0)+, (R0)+
                return
; End of function S13552

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

S13760:         mov     R5, R0
S13762:         mov     R0, R4
                add     R2, R0
                cmp     (R0)+, (R0)+
                add     PCPTLN, R4
                mov     R4, R5
                mov     #-1, -(R4)
                mov     (R4), -(R4)
1$:             mov     -6(R4), -(R4)
                cmp     R4, R0
                bhi     1$
                return
; End of function S13762


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

S16416:         mov     R2, -(SP)
                add     #4, PCPTLN
                call    S16272
                mov     (SP)+, R2
                return
; End of function S16416

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

S16406:         sub     #4, PCPTLN
S16272:         mov     PCPTLN, R3
                asr     R3
                asr     R3
                dec     R3
                mov     #47724, R1
                mov     #D10BUF, R0
                jmp     OUT3NM  ; Вывод на экран трёхзначного числа.
                                ; Вход: R0 - адрес буфера, куда помещается строковое значение
                                ; R1 - адрес экрана
                                ; R3 - число
; End of function S16272

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

KURSOR:         mov     KURSAD, R2
                mov     #25252, R1
                xor     R1, -100(R2)
                mov     #5, R3
                mov     #27776, R1
1$:             xor     R1, (R2)
                add     #100, R2
                sob     R3, 1$
                mov     #25252, R1
                xor     R1, (R2)
                return
; End of function KURSOR
; ███████████████ S U B R O U T I N E ███████████████████████████████████████

GETKEY:         movb    @#177662, R0
                cmpb    R0, #100
                blo     1$
                bic     #177640, R0
1$:             return
; End of function GETKEY

; ███████████████ S U B R O U T I N E ███████████████████████████████████████
; получение кода нажатой клавиши с автоповтором.
; синхронизация с таймером 50Гц
; Выход: R0 - код
GETCHR:         call    GETKEY
                mov     #14000, R1
2$:             bit     #100, @#177716
                bne     INPCHR      ; получение кода нажатой клавиши с ожиданием.
                                    ; Выход: R0 - код
                tstb    FLGCH$
                bne     1$
                sob     R1, 2$
                incb    FLGCH$
1$:             wait
                return
; End of function GETCHR

; ███████████████ S U B R O U T I N E ███████████████████████████████████████
; получение кода нажатой клавиши с ожиданием.
; Выход: R0 - код
INPCHR:         tstb    @#177660
                bpl     INPCHR      ; получение кода нажатой клавиши с ожиданием.
                                    ; Выход: R0 - код
                mov     PC, NEWCH$
                mov     #3000, R0
                sob     R0, .
                call    GETKEY
                clrb    FLGCH$
                return
; End of function INPCHR

; ███████████████ S U B R O U T I N E ███████████████████████████████████████
; деление
; вход: R1 - делимое
;       R2 - делитель
; выход: R1 - целая часть
;       R3 - остаток
DIVIDE:         clr     R3
                mov     #20, R0
1$:             asl     R1
                rol     R3
                cmp     R3, R2
                blo     2$
                sub     R2, R3
                inc     R1
2$:             sob     R0, 1$
                bic     #140000, R1
                return
; End of function DIVIDE

; ───────────────────────────────────────────────────────────────────────────
; Меню LENGTH Down. Задать длину цепочки разделов
M$LNDN:         decb    @#134776    ; длина цепочки разделов мелодии
                br      17004$
; Меню LENGTH Up. Задать длину цепочки разделов
M$LNUP:         incb    @#134776    ; длина цепочки разделов мелодии
17004$:         jmp     SNDLEN  ; выводим количество разделов в музыке

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

S16654:         movb    (R0)+, R2   ; байт - параметр 1 - смещение до строкового значения величины
                movb    (R0)+, R4   ; байт - параметр 2 - смещение в структуре цепочки разделов
                sub     #10, R0     ; на начало структуры меню
                mov     (R0), R1        ; адрес экрана
                add     #T$MMNU, R2
                mov     R2, R0
                mov     CURPOS, R5 ; Номер позиции в цепочке разделов
                asl     R5
                add     #135000, R5 ; указатель на текущую позицию в цепочке разделов
                add     R4, R5      ; определяем, что получить, номер раздела или его высоту
                clr     R3
                bisb    (R5), R3    ; получаем значение
                return
; End of function S16654

; ───────────────────────────────────────────────────────────────────────────
; Меню HEIGHT Down, PATTERN Down
; Задать высоту тона заданного паттерна
; Задать номер паттерна в цепочке в заданной позиции
M$HGDN:         call    S16654
                add     #70, R1
                tst     R4
                bne     1$
                dec     R3
                bpl     16744$
                mov     @#134774, R3    ; количество разделов в нотном тексте
1$:             dec     R3
                br      16744$
; ───────────────────────────────────────────────────────────────────────────
; Меню HEIGHT Up, PATTERN Up
; Задать высоту тона заданного паттерна
; Задать номер паттерна в цепочке в заданной позиции
M$HGUP:         call    S16654
                add     #72, R1
                inc     R3
                tst     R4
                bne     16744$
                cmp     R3, @#134774    ; количество разделов в нотном тексте
                blo     16744$
                clr     R3
16744$:         movb    R3, (R5)
                jmp     OUT3NB
; ───────────────────────────────────────────────────────────────────────────
; Меню POSITION Up. Выбрать позицию в цепочке паттернов
M$PSUP:         incb    CURPOS
                br      007L$
; ───────────────────────────────────────────────────────────────────────────
; Меню POSITION Down. Выбрать позицию в цепочке паттернов
M$PSDN:         decb    CURPOS
007L$:          jmp     OUTCPT
; ───────────────────────────────────────────────────────────────────────────
; Меню SAVE, LOAD, COMPILE
M$SVLD:         mov     CurrMenuPt, -(SP)
                mov     SP, BF$SPD
                mov     #14000, @#NPAGE ; стр.5->окно0, стр.1->окно1
                call    SETPGE
                call    @(R0)+
                mov     #16000, @#NPAGE ; стр.5->окно0, стр.4->окно1
                mov     BF$SPD, SP
                mov     (SP)+, CurrMenuPt   ; начало текущего обрабатываемого меню
                jmp     SETPGE
; ───────────────────────────────────────────────────────────────────────────
; Меню COPY
M$COPY:         mov     CurrMenuPt, -(SP)
                mov     SP, BF$SPD
                clr     BFCPTR+B.CLNS
                mov     #V$CLN1, R1
                movb    #'0, (R1)
                movb    (R1)+, (R1)
                movb    (R1)+, (R1)
                call    DRWWNH  ; Нарисовать окно с рамкой с тенью
                                ; Входные параметры:
                .word   44732   ; Слово - адрес экрана, бит 15 - флаг, не сохранять содержимое под окном
                .byte   14      ; Байт - высота в символах
                .byte   22      ; Байт - ширина в символах
                .byte   252     ; Байт - маска цвета фона
                .byte   377     ; Байт - инверсная маска цвета символов
                mov     #T$COPY, R0
                mov     #45742, R1
                br      010LL$
; ───────────────────────────────────────────────────────────────────────────
; Меню TRANSPOSITION
M$TRAN:         mov     CurrMenuPt, -(SP)
                mov     SP, BF$SPD
                clr     BFCPTR+B.TRLN
                mov     #V$TRLN, R1
                movb    #'0, (R1)
                movb    (R1)+, (R1)
                movb    (R1)+, (R1)
                call    DRWWNH  ; Нарисовать окно с рамкой с тенью
                                ; Входные параметры:
                .word   44732   ; Слово - адрес экрана, бит 15 - флаг, не сохранять содержимое под окном
                .byte   10      ; Байт - высота в символах
                .byte   22      ; Байт - ширина в символах
                .byte   252     ; Байт - маска цвета фона
                .byte   377     ; Байт - инверсная маска цвета символов
                mov     #T$TRAN, R0
                mov     #45764, R1
010LL$:         mov     R0, F25654
                jmp     OUTSTR  ; Вывод строки.
                                ; Вход: R0 - адрес строки, R1 - адрес экрана
; ───────────────────────────────────────────────────────────────────────────
; Выполнение копирования
M$CSET:         cmp     BFCPTR+B.CLNS, BFCPTR+B.CFNS
                blos    L33536
                mov     #BFCPTR+B.CPTS, R5
                mov     #STACKH, R0
                call    L33632
                mov     BFCPTR+B.CCHS, R1
                mov     BFCPTR+B.CCHD, R2
                cmp     R1, #3
                bhis    2$
4$:             dec     R1
                bmi     3$
                add     -16(R0), -20(R0)
                br      4$
; ───────────────────────────────────────────────────────────────────────────

3$:             cmp     R2, #3
                bhis    L33536
6$:             dec     R2
                bmi     5$
                add     -6(R0), -10(R0)
                br      6$
; ───────────────────────────────────────────────────────────────────────────

2$:             cmp     R2, #3
                blo     L33536
                call    S33726
5$:             call    S33730
L33536:         jmp     D$CANC  ; Отмена действия

L33632:         mov     PC, -(SP)
                mov     (R5)+, R4
                cmp     R4, @#134774    ; количество разделов в нотном тексте
                bhis    L33536
                asl     R4
                asl     R4
                mov     133000(R4), R2
                mov     133002(R4), R1
                mov     R2, (R0)+
                mov     R1, (R0)+
                dec     R1
                asr     R1
                asr     R1
                cmp     R1, (R5)
                blos    L33536
                mov     (R5)+, (R0)+
                mov     (R5)+, (R0)+
                tst     (R5)+
                return

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

S33726:         mov     PC, -(SP)
S33730:         mov     R0, -(SP)
                tst     -(R0)
                mov     -(R0), R5
                asl     R5
                asl     R5
                tst     -(R0)
                add     -(R0), R5
                mov     -(R0), R4
                asl     R4
                asl     R4
                call    S26130
                mov     (SP)+, R0
                add     -6(R0), -10(R0)
                add     -16(R0), -20(R0)
                return
; End of function S33730

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

S26130:         mov     -(R0), R3
                tst     -(R0)
                asl     R3
                asl     R3
                add     -(R0), R4
                add     (R0), R3
2$:             cmpb    (R3), #377
                beq     1$
                cmpb    (R5), #377
                beq     1$
                mov     (R3)+, (R5)+
                mov     (R3)+, (R5)+
                cmp     R3, R4
                blos    2$
1$:             return
; End of function S26130

; ───────────────────────────────────────────────────────────────────────────
; Выполнение действия меню транспонирования
M$TSET:         cmp     BFCPTR+B.TRLN, BFCPTR+B.TRFN
                blos    2$
                mov     BFCPTR+B.TRPT, R5
                cmp     R5, @#134774    ; количество разделов в нотном тексте
                bhis    2$
                asl     R5
                asl     R5
                add     #133000, R5
                mov     (R5)+, R1
                mov     BFCPTR+B.TRFN, R2
                mov     BFCPTR+B.TRLN, R3
                asl     R2
                asl     R2
                asl     R3
                asl     R3
                mov     (R5), R5
                mov     R5, R4
                cmp     -(R4), -(R4)
                cmp     R4, R2
                blos    2$
                movb    BFCPTR+B.TRST, R4
                mov     BFCPTR+B.TRCH, R0
                cmp     R0, #3
                bhis    3$
5$:             dec     R0
                bmi     4$
                add     R5, R1
                br      5$
; ───────────────────────────────────────────────────────────────────────────

3$:             call    S26026
4$:             call    S26030
2$:             jmp     D$CANC  ; Отмена действия

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

S26026:         mov     PC, -(SP)
S26030:         mov     R2, -(SP)
                mov     R3, -(SP)
                add     R1, R3
                add     R1, R2
5$:             movb    (R2), R0
                cmpb    R0, #377
                beq     1$
                bic     #177600, R0
                beq     2$
                cmpb    R0, #176
                beq     2$
                bicb    R0, (R2)
                add     R4, R0
                bmi     3$
                cmpb    R0, #140
                blo     4$
                movb    #140, R0
                br      4$
; ───────────────────────────────────────────────────────────────────────────

3$:             clr     R0
4$:             bisb    R0, (R2)
2$:             cmp     (R2)+, (R2)+
                cmp     R2, R3
                blos    5$
1$:             mov     (SP)+, R3
                mov     (SP)+, R2
                add     R5, R1
                return
; End of function S26030

; ───────────────────────────────────────────────────────────────────────────
; изменение канала в меню копирование, транспонирование
M$CCCH:         movb    (R0)+, R2
                movb    (R0)+, R3
                mov     -10(R0), R1
                add     #100, R1
                add     F25654, R2
                add     #BFCPTR, R3
                mov     (R3), R5
                inc     R5
                bic     #177774, R5
                mov     R5, (R3)
                mov     R5, R0
                asl     R5
                add     R5, R0
                asl     R0
                add     #CH.A, R0
                mov     R0, R5
1$:             movb    (R5)+, (R2)+
                tstb    (R5)
                bne     1$
                mov     #5, R3
                mov     #177777, BGCOLR
                mov     #125252, COLMSK
                jmp     STROUT
; ───────────────────────────────────────────────────────────────────────────
; Уменьшение значения в меню транспонирование, копирование
M$TVDN:         mov     #-1, R4
                mov     #72, R5
                br      25572$
; ───────────────────────────────────────────────────────────────────────────
; Увеличение значения в меню транспонирование, копирование
M$TVUP:         mov     #1, R4
                mov     #102, R5
25572$:         movb    (R0)+, R2   ; берём аргументы из пункта меню.
                movb    (R0)+, R1
                add     #BFCPTR, R1
                mov     (R1), R3
                add     R4, R3
                bit     #4, R1
                beq     1$
                bic     #177400, R3
                br      3$
; ───────────────────────────────────────────────────────────────────────────

1$:             tst     R3
                bpl     2$
                mov     #999., R3
2$:             cmp     R3, #999.
                blos    3$
                clr     R3
3$:             mov     R3, (R1)
                mov     -10(R0), R1
                add     R5, R1
                add     F25654, R2
                mov     R2, R0
                mov     #125252, TMPBGC
                mov     #177777, TMPCLM
                call    OUT3NM  ; Вывод на экран трёхзначного числа.
                                ; Вход: R0 - адрес буфера, куда помещается строковое значение
                                ; R1 - адрес экрана
                                ; R3 - число
                mov     #0, TMPBGC
                mov     #0, TMPCLM
                return
; ───────────────────────────────────────────────────────────────────────────
; Меню выключения/включения каналов
M$CHTG:         movb    (R0)+, R2
                movb    (R0)+, R3   ; получим биты маски канала в регистре-смесителе
                mov     -10(R0), R1 ; адрес экрана
                add     #106, R1
                add     #T$MMNU+200, R2
                swab    R3
                xor     R3, MIXSWC
                bit     R3, MIXSWC  ; что канал?
                bne     1$  ; выключен
                movb    #'N, (R2)+  ; отметим - включен
                movb    #' , (R2)+
                br      2$
; ───────────────────────────────────────────────────────────────────────────

1$:             movb    #'F, (R2)   ; отметим - выключен
                movb    (R2)+, (R2)+
2$:             mov     R2, R0
                mov     #3, R3
                sub     R3, R0
                mov     #-1, BGCOLR
                mov     #-1, COLMSK
                jmp     STROUT
; ───────────────────────────────────────────────────────────────────────────
; Меню SAMPLE
M$SAMP:         call    DRWWNH  ; Нарисовать окно с рамкой с тенью
                                ; Входные параметры:
                .word   52724+100000    ; Слово - адрес экрана, бит 15 - флаг, не сохранять содержимое под окном
                .byte   6       ; Байт - высота в символах
                .byte   14      ; Байт - ширина в символах
                .byte   125     ; Байт - маска цвета фона
                .byte   0       ; Байт - инверсная маска цвета символов
                movb    EDSAMN, R0
                add     #133, R0
                movb    R0, V$SLNS
                mov     #53732, R1
                mov     #T$SELE, R0
                jmp     OUTSTR  ; Вывод строки.
                                ; Вход: R0 - адрес строки, R1 - адрес экрана
; ───────────────────────────────────────────────────────────────────────────
; выбор номера сэмпла в меню SAMPLE
CHNGSN:         mov     #0, BGCOLR
                mov     #52525, COLMSK
                incb    EDSAMN
                bicb    #177760, EDSAMN
                movb    EDSAMN, R2
                mov     #56744, R1
                add     #133, R2
                movb    R2, V$SMSM
                jmp     OUTCHR  ; Вход: R2 - код символа, R1 - адрес вывода
; ───────────────────────────────────────────────────────────────────────────
 ; подтверждение выбранного номера сэмпла в меню SAMPLE
SELCSN:         movb    EDSAMN, R0
                swab    R0
                asr     R0
                asr     R0
                add     #136000, R0
                mov     R0, CURSAM
                mov     #16000, @#NPAGE ; стр.5->окно0, стр.4->окно1
                call    SETPGE
                mov     PC, MUTEAY
                mov     #T100P, @#100
                mov     #340, @#102
                mov     #SEPAL1, @#177662
                jmp     SMPLED  ; редактор сэмплов
; ───────────────────────────────────────────────────────────────────────────
; Меню TEMP
M$TEMP:         mov     CurrMenuPt, -(SP)
                mov     SP, BF$SPD
                mov     @#134772, R2
                add     #133, R2
                movb    R2, V$TEMP
                call    DRWWNH  ; Нарисовать окно с рамкой с тенью
                                ; Входные параметры:
                .word   47752   ; Слово - адрес экрана, бит 15 - флаг, не сохранять содержимое под окном
                .byte   6       ; Байт - высота в символах
                .byte   12      ; Байт - ширина в символах
                .byte   125     ; Байт - маска цвета фона
                .byte   0       ; Байт - инверсная маска цвета символов
                mov     #50756, R1
                mov     #T$TEMP, R0
                jmp     OUTSTR  ; Вывод строки.
                                ; Вход: R0 - адрес строки, R1 - адрес экрана
; ───────────────────────────────────────────────────────────────────────────
; задание нового темпа
CHNGTM:         mov     @#134772, R2
                inc     R2
                cmp     R2, #20
                blo     1$
                mov     #2, R2
1$:             mov     R2, @#134772
                add     #133, R2
                movb    R2, V$TEMP
                mov     #53770, R1
                jmp     OUTCHR  ; Вход: R2 - код символа, R1 - адрес вывода
; ───────────────────────────────────────────────────────────────────────────
; Меню PLAY
M$PLAY:         tst     -(SP)
                mov     CurrMenuPt, -(SP)   ; начало текущего обрабатываемого меню
                mov     SP, BF$SPD
                call    DRWWNH  ; Нарисовать окно с рамкой с тенью
                                ; Входные параметры:
                .word   46750   ; Слово - адрес экрана, бит 15 - флаг, не сохранять содержимое под окном
                .byte   4       ; Байт - высота в символах
                .byte   12      ; Байт - ширина в символах
                .byte   125     ; Байт - маска цвета фона
                .byte   0       ; Байт - инверсная маска цвета символов
                mov     #47752, R1
                mov     #T$PLAY, R0
                jmp     OUTSTR  ; Вывод строки.
                                ; Вход: R0 - адрес строки, R1 - адрес экрана
; ───────────────────────────────────────────────────────────────────────────
; выполнение функции меню PLAY
M1PLAY:         mov     BF$SPD, R1
                mov     (R0), 2(R1)
                jmp     D$CANC  ; Отмена действия
; ───────────────────────────────────────────────────────────────────────────
; Меню DELETE
M$DELT:         mov     CurrMenuPt, -(SP)
                mov     SP, BF$SPD
                call    DRWWNH  ; Нарисовать окно с рамкой с тенью
                                ; Входные параметры:
                .word   51746   ; Слово - адрес экрана, бит 15 - флаг, не сохранять содержимое под окном
                .byte   6       ; Байт - высота в символах
                .byte   14      ; Байт - ширина в символах
                .byte   252     ; Байт - маска цвета фона
                .byte   377     ; Байт - инверсная маска цвета символов
                mov     #T$DELT, R0
                mov     #52754, R1
                jmp     OUTSTR  ; Вывод строки.
                                ; Вход: R0 - адрес строки, R1 - адрес экрана
; ───────────────────────────────────────────────────────────────────────────
; Вывод меню подтверждения удаления
CNFIRM:         mov     SP, BF$SPC
                call    DRWWNH  ; Нарисовать окно с рамкой с тенью
                                ; Входные параметры:
                .word   54712   ; Слово - адрес экрана, бит 15 - флаг, не сохранять содержимое под окном
                .byte   6       ; Байт - высота в символах
                .byte   20      ; Байт - ширина в символах
                .byte   377     ; Байт - маска цвета фона
                .byte   125     ; Байт - инверсная маска цвета символов
                mov     #56414, R1
                mov     #T$SURE, R0
                jmp     OUTSTR  ; Вывод строки.
                                ; Вход: R0 - адрес строки, R1 - адрес экрана
; ───────────────────────────────────────────────────────────────────────────
YESCNF:         call    RESWND  ; Восстановление области экрана из буфера
                mov     BF$SPC, SP
                return          ; окошко закрывается, и продолжается выполнение после вызова call CNFIRM
; ───────────────────────────────────────────────────────────────────────────
NOTCNF:         call    RESWND  ; Восстановление области экрана из буфера
; Отмена действия
D$CANC:         mov     BF$SPD, SP  ; переход к главному меню.
                mov     (SP)+, CurrMenuPt   ; начало текущего обрабатываемого меню
                jmp     RESWND  ; Восстановление области экрана из буфера
; ───────────────────────────────────────────────────────────────────────────
; Удаление позиции в списке разделов
D$POSI:         call    CNFIRM
                mov     CURPOS, R3 ; Номер позиции в цепочке разделов
                asl     R3
                add     #135000, R3
1$:             cmp     R3, #135776
                bhis    2$
                mov     2(R3), (R3)+
                br      1$
; ───────────────────────────────────────────────────────────────────────────

2$:             call    OUTCPT
                br      D$CANC      ; Отмена действия
; ───────────────────────────────────────────────────────────────────────────
; Удаление всей мелодии
D$SONG:         call    CNFIRM
LOAERR:         call    RESWND  ; Восстановление области экрана из буфера
                mov     BF$SPD, SP
                mov     (SP)+, CurrMenuPt   ; начало текущего обрабатываемого меню
                call    INITSN
                jmp     S17556
; ───────────────────────────────────────────────────────────────────────────
; Удаление раздела
D$PATR:         cmp     CURPAT, @#134774    ; количество разделов в нотном тексте
1$:             bhis    D$CANC          ; Отмена действия
                cmp     @#134774, #1    ; если количество разделов в нотном тексте всего 1
                beq     1$              ; то удалять нечего
                call    CNFIRM          ; Вывод меню подтверждения действия
                mov     CURPAT, R0      ; Номер текущего паттерна.
                asl     R0
                asl     R0
                add     #133004, R0
                mov     -(R0), R2
                mov     -(R0), R1
                mov     R1, R3
                add     R2, R3
                asl     R2
                add     R2, R3
2$:             mov     (R3)+, (R1)+
                cmp     R3, #133000
                blo     2$
3$:             mov     4(R0), (R0)+
                cmp     R0, #134774
                blo     3$
                mov     #133000, R0
                mov     #100000, (R0)
4$:             mov     (R0)+, R1
                mov     (R0)+, R2
                add     R2, R1
                asl     R2
                add     R2, R1
                tst     (R0)
                beq     5$
                mov     R1, (R0)
                cmp     R0, #134776 ; длина цепочки разделов мелодии
                blo     4$
5$:             mov     BF$SPD, SP
                mov     (SP)+, CurrMenuPt   ; начало текущего обрабатываемого меню
                call    RESWND      ; Восстановление области экрана из буфера
                dec     @#134774    ; количество разделов в нотном тексте
                mov     CURPAT, R3  ; Номер текущего паттерна.
                mov     #135000, R0
13$:            cmpb    (R0), R3
                blo     11$
                bne     12$
                clrb    (R0)
                br      11$
; ───────────────────────────────────────────────────────────────────────────

12$:            decb    (R0)
11$:            tst     (R0)+
                cmp     R0, #136000
                blo     13$
                call    S16006
                call    OUTFRE
                jmp     OUTCPT
; ───────────────────────────────────────────────────────────────────────────


; ███████████████████████████████████████████████████████████████████████████
; ████████████████████ ПРОИГРЫВАТЕЛЬ ████████████████████████████████████████
; ███████████████████████████████████████████████████████████████████████████
; Пункт меню - играть раздел
PLYPTR:         mtps    #340
                clrb    PLY$FP      ; флаг - играем текущий раздел
                mov     #PLAY1, T100FN
                mov     #340, @#102 ; чтобы не могли прервать сами себя
                call    INIPL1
                mov     PLPTNR, R3  ; Номер паттерна, который будет проигрываться.
                clrb    HEIGH1
                call    S16024      ; вывод инфы о текущем разделе
                mtps    #0
1$:             wait
                call    SPECAN      ; анализатор спектра
2$:             cmpb    VARPR1, #2  ; счётчик тиков == 2
                bne     1$          ; пока нет - вызываем эквалайзер
                wait
                call    S10334      ; прокрутка нотного текста
                bit     #100, @#177716
                bne     2$
                jmp     AYOFF       ; выключаем звук AY

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

; Пункт меню - играть всю мелодию
PLYSNG:         mtps    #341        ; бит С ставим, чтобы во флаг попало
                rolb    PLY$FP      ; флаг - играем всю мелодию
                mov     #PLAY1, T100FN
                mov     #340, @#102 ; чтобы не могли прервать сами себя
                call    INIPL1
                call    OUTCPT      ; вывод инфы о позиции в цепочке разделов
                mov     CURPOS, R1  ; Номер позиции в цепочке разделов
                asl     R1
                clr     R0
                bisb    135000(R1), R0  ; раздел текущей позиции в цепочке
                call    S15522
                call    S11234      ; выводим инфу о текущем разделе и ноты раздела
                movb    CURPOS, PLYPOS  ; Номер текущей позиции в цепочке разделов
                mtps    #0
4$:             wait                ; выводить эквалайзер синхронизированно с музыкой
                call    SPECAN      ; анализатор спектра
3$:             cmpb    VARPR1, #2  ; счётчик тиков == 2
                bne     4$          ; пока нет - вызываем эквалайзер
                cmpb    @PCPTAD, #377   ; раздел кончился?
                bne     2$              ; нет
                movb    PLYPOS, R0      ; берём текущую позицию
                incb    R0              ; увеличиваем
                cmpb    @#134776, R0    ; дошли до конца цепочки?
                bhis    1$              ; нет ещё
                clr     R0              ; да - начнём сначала
1$:             movb    R0, PLYPOS      ; текущая позиция играния
                clr     W37404          ; номер ноты инициализируем
                mov     #177377, W37404+2
                asl     R0
                clr     R1
                bisb    135000(R0), R1  ; раздел текущей позиции в цепочке
                asl     R1
                asl     R1
                mov     133000(R1), PCPTAD  ; текущий адрес в разделе
                mov     133002(R1), PCPTLN  ; длина текущего раздела
2$:             call    S10334          ; прокрутка нотного текста
                wait                    ; нужно для синхронизации, когда ничего не звучит, а ноты прокручивать надо
                bit     #100, @#177716
                bne     3$
                jmp     AYOFF           ; выключаем звук AY
; ███████████████ S U B R O U T I N E ███████████████████████████████████████

PLAY1:          jsr     R5, @#PUSHA
                call    EXPNT1      ; формируем квант данных для передачи в AY
                add     #15, R3
                mov     #363, R2    ; начинаем с регистра 14, т.е. форму волпака не тут обрабатываем
                mov     #177714, R5 ; и заполняем регистры AY
1$:             mov     R2, (R5)
                movb    -(R3), R0
                com     R0
                movb    R0, (R5)
                incb    R2
                bmi     1$
                return
; End of function PLAY1


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

INIPL1:         call    AYOFF2      ; глушим всё
                mov     #GETNT1, F21002 ; зададим рабочую функцию
                mov     CURPOS, R0 ; Номер позиции в цепочке разделов
                mov     #VARPR1, R5
                tstb    PLY$FP      ; что играем, раздел или всю мелодию?
                bne     1$          ; всю мелодию
                mov     PLPTNR, R1  ; только раздел, берём его номер
                call    S20410      ; обработка перехода к началу текущего раздела, который будем играть
                br      2$
1$:             call    S20366      ; обработка перехода к началу раздела, с которого начнём играть всю мелодию.
2$:             call    2(PC)
                mov     PC, -(SP)
                clr     (R5)
                mov     #136000, L.ASMP(R5) ; начало сэмплов
                mov     L.BCHN(R5), L.ACHN(R5)  ; адрес в голосе текущего раздела
                movb    #20, L.VVAL(R5)
                add     #CHPLN, R5
                return
; End of function INIPL1

; ███████████████ S U B R O U T I N E ███████████████████████████████████████
; чтение очередной ноты в канале
GETNT1:         movb    @#134772, (R5)  ; темп на место
L20310:         mov     L.ACHN(R5), R4  ; текущий адрес ноты в канале
                cmpb    (R4), #377      ; конец раздела?
                bne     10$             ; нет
                tstb    PLY$FP          ; что играем, раздел или всю мелодию?
                bne     1$              ; всю мелодию
L20330:         mov     L.BCHN(R5), L.ACHN(R5) ; только раздел. Снова берём адрес начала текущего раздела
                br      L20310          ; и начинаем сначала
; ───────────────────────────────────────────────────────────────────────────
; 
1$:             cmpb    L.CNMT(R5), #1  ; обрабатываем канал A?
                bne     L20330          ; нет - пропустим переход к новому разделу
                movb    CURPOS, R0      ; берём номер текущей позиции в цепочке разделов
                incb    R0          ; увеличиваем
                cmpb    @#134776, R0    ; дошли до конца?
                bhis    S20366          ; нет
                clr     R0          ; да - начинаем сначала

S20366:         movb    R0, CURPOS      ; сохраним новый номер позиции в цепочке разделов
                call    OUTCPT      ; вывод инфы о позиции в цепочке разделов
                mov     CURPOS, R0  ; Номер позиции в цепочке разделов
                asl     R0
                add     #135000, R0 ; смещение в цепочке разделов
                clr     R1
                bisb    (R0)+, R1   ; номер раздела, который нужно играть
                movb    (R0), HEIGH1    ; высота проигрыша раздела

S20410:         asl     R1
                asl     R1
                mov     R1, R0
                add     #133000, R0 ; смещение в списке разделов нотного текста
                mov     (R0)+, R1
                mov     R1, L.BCHN(R5)      ; адрес канала A текущего раздела
                add     (R0), R1
                mov     R1, CHPLN+L.BCHN(R5) ; адрес канала B текущего раздела
                add     (R0), R1
                mov     R1, CHPLN+CHPLN+L.BCHN(R5) ; адрес канала C текущего раздела
                br      L20330      ; и пойдём нужный адрес в нужное место скопируем.
; ───────────────────────────────────────────────────────────────────────────

10$:            add     #4, L.ACHN(R5)  ; заранее двигаем указатель на новую ноту
                movb    HEIGH1, R2      ; высота раздела
                movb    (R4)+, R0       ; берём текущую ноту
                movb    R0, R1
                bic     #177600, R1     ; что за нота?
                beq     12$             ; пауза - пойдём обрабатывать
                cmpb    #176, R1        ; пусто?
                beq     8$              ; да - ничего не делаем
                dec     R1              ; получим номер ноты
                add     R2, R1          ; прибавим высоту
                movb    R1, L.NOTN(R5)  ; запомним номер текущей ноты
                movb    (R4)+, R1       ; атрибуты ноты
                movb    (R4)+, R3       ; параметры ноты: громкость и номер сэмпла
                movb    (R4)+, R2       ; ещё параметры: период огибающей или длительность
                bit     #40, R1         ; номер сэмпла есть
                bne     2$              ; нету
                mov     R3, R4          ; есть
                bic     #360, R3        ; это громкость
                bic     R3, R4          ; это номер сэмпла * 16.
                asl     R4
                asl     R4              ; умножаем ещё на 4
                add     #136000, R4     ; и получим адрес сэмпла
                mov     R4, L.ASMP(R5)  ; запомним его
                mov     (R4)+, L.BCYV(R5)   ; начало и конец зацикливания громкости
                mov     6(R4), L.BCYN(R5)   ; начало и конец зацикливания шума
                mov     (R4), R4        ; начало и конец зацикливания тона
                bic     #100000, R4     ; сбрасываем признак плавного изменения
                mov     R4, L.BCYT(R5)
2$:             movb    R1, L.ATTR(R5)  ; сохраним атрибут
                bpl     3$              ; переход, если нет volume
                aslb    R1              ; проверим форму пакета
                bmi     4$              ; отсутствует - переход
                mov     #17, R4         ; присутствует
                sub     R3, R4          ; громкость = 17 - value
                movb    R4, L.VVAL(R5)  ; запомним
4$:             tstb    R0              ; у V параметр есть?
                bmi     5$              ; нету
                bic     #360, R2        ; есть - это длительность первого фрагмента ноты
                asl     R2
                movb    R2, L.NDLT(R5)  ; запомним
5$:             movb    L.NDLT(R5), L.L1FR(R5) ; обновляем длительность звучания первого фрагмента
                br      7$
; ───────────────────────────────────────────────────────────────────────────
                ; обработка отсутствия volume
3$:             aslb    R1              ; проверим форму пакета
                bmi     6$              ; отсутствует - переход
                movb    R3, L.VPFM(R5)  ; форму пакета сохраним
6$:             tstb    R0              ; у V параметр есть?
                bmi     11$             ; нету
                movb    R2, L.VPER(R5)  ; период сохраним
11$:            mov     #362, @#177714  ; устанавливаем форму
                movb    L.VPFM(R5), R2
                movb    R2, AYREG1+Y.VPCK   ; флаг для эквалайзера, что работает чистый волпак.
                                            ; иначе вообще никак не отлавливается.
                com     R2
                movb    R2, @#177714    ; волнового пакета
7$:             clrb    L.PAUS(R5)      ; сбрасываем флаг паузы
                movb    #377, L.TPSV(R5)    ; инициализируем текущие фрагменты громкости
                mov     #-1, L.TPSN(R5)     ; шума и тона в сэмпле
                br      9$
; ───────────────────────────────────────────────────────────────────────────
; часть другой функции
L22706:         bit     #100, @#177716
                bne     12$
                incb    (R5)
                return
; ───────────────────────────────────────────────────────────────────────────
; обработка паузы
12$:            tstb    L.PAUS(R5)  ; пауза есть?
                bne     8$          ; да
                decb    L.PAUS(R5)  ; нет - установим признак паузы
                mov     R5, R4
                inc     R4
                movb    L.ECYV(R5), (R4)+   ; L.ECYV(R5) -> L.TPSV(R5)
                movb    L.ECYN(R5), (R4)+   ; L.ECYN(R5) -> L.TPSN(R5)
                movb    L.ECYT(R5), (R4)    ; L.ECYT(R5) -> L.TPST(R5)
9$:             clrb    L.TSLV(R5)
                clrb    L.TSLN(R5)
                clrb    L.TSLT(R5)
8$:             return
; End of function GETNT1

; ███████████████ S U B R O U T I N E ███████████████████████████████████████
; формируем квант данных для передачи в AY
EXPNT1:         mov     #VARPR1, R5
                call    2(PC)
                mov     PC, -(SP)
                decb    (R5)        ; тики кончились?
                bgt     21004$      ; нет ещё - звучим текущую ноту
                call    @(PC)+      ; чтение очередной ноты в канале
F21002:         .word   GETNT1      ; или другой функции какой-нибудь
21004$:         decb    L.TSLV(R5)  ; текущий фрагмент громкости отзвучал?
                bpl     10$         ; нет ещё - продолжаем
                ; достаём из сэмпла новую громкость и её длительность
                incb    L.TPSV(R5)
                movb    L.TPSV(R5), R0 ; текущий фрагмент громкости в сэмпле
                tstb    L.PAUS(R5)  ; пауза?
                bne     1$          ; да
                cmpb    L.ECYV(R5), R0  ; нет - дошли до конца зацикливания?
                bhis    1$          ; нет ещё
                movb    L.BCYV(R5), R0  ; да - начнём сначала
                movb    R0, L.TPSV(R5)  ; обновим текущий фрагмент
1$:             clr     L.DVLV(R5)  ; приращение при плавном изменении громкости
                cmpb    #13., R0    ; фрагмент за границы не вышел?
                bhi     2$          ; нет, нормально всё
                decb    L.TPSV(R5)  ; вышел - корректируем
                clr     L.CVLV(R5)  ; и глушим резко - громкость 0
                bisb    L.CNMT(R5), AYREG1+Y.MIXR   ; и вырубаем в миксере тон
                bisb    L.CNMN(R5), AYREG1+Y.MIXR   ; и шум
                br      10$         ; и продолжаем
; ───────────────────────────────────────────────────────────────────────────

2$:             mov     #1, R2
                mov     R0, R3
                beq     4$
3$:             asl     R2          ; делаем маску фрагмента
                sob     R3, 3$
4$:             mov     L.ASMP(R5), R3 ; адрес сэмпла
                add     R3, R0  ; смещение до параметров фрагмента
                clr     R1
                bisb    46(R0), R1  ; берём параметры фрагмента огибающей громкости
                bit     4(R3), R2   ; проверяем маску в огибающей тона
                bne     5$          ; тон есть - переход
                bisb    L.CNMT(R5), AYREG1+Y.MIXR ; иначе - выключаем тон
                br      51$
5$:             bicb    L.CNMT(R5), AYREG1+Y.MIXR ; включаем тон
51$:            mov     R1, R2
                bic     #360, R1    ; значение
                bic     R1, R2      ; длительность * 16
                asr     R2
                asr     R2          ; делим на 4
                beq     6$
                sub     #3, R2
6$:             add     L.L1FR(R5), R2  ; формируем длительность
                movb    R1, L.RVLV+1(R5)    ; громкость текущего фрагмента -> в конечное значение
                movb    R2, L.TSLV(R5)
                tst     4(R3)       ; тон менять плавно?
                bmi     7$          ; да
                movb    R1, L.CVLV+1(R5)    ; нет - сразу сделаем конечный результат
                br      10$
; ───────────────────────────────────────────────────────────────────────────

7$:             clr     R4
                movb    L.CVLV+1(R5), R0    ; текущее значение
                sub     R0, R1  ; дельта = конечное значение - текущее значение
                bpl     8$      ; если отрицательное
                neg     R1      ; знак поменяем
                inc     R4      ; и отметим флагом
8$:             swab    R1      ; d*256.
                call    DIVIDE  ; деление
                                ; вход: R1 - делимое
                                ;       R2 - делитель
                                ; выход: R1 - целая часть
                                ;       R3 - остаток
                tst     R4
                beq     9$
                neg     R1
9$:             mov     R1, L.DVLV(R5)  ; приращение при плавном изменении громкости
                ; с громкостью разобрались, теперь - с шумом.
10$:            decb    L.TSLN(R5)  ; текущий фрагмент шума отзвучал?
                bpl     21$         ; нет ещё, продолжим
                ; достаём из сэмпла новый шум и его длительность
                incb    L.TPSN(R5)
                movb    L.TPSN(R5), R0 ; текущий фрагмент шума в сэмпле
                tstb    L.PAUS(R5)  ; пауза?
                bne     11$         ; да
                cmpb    L.ECYN(R5), R0 ; нет - дошли до конца зацикливания?
                bhis    11$         ; нет ещё
                movb    L.BCYN(R5), R0  ; да - начнём сначала
                movb    R0, L.TPSN(R5)  ; обновим текущий фрагмент
11$:            clr     L.DVLN(R5)  ; приращение при плавном изменении шума
                cmpb    #13., R0    ; фрагмент за границы не вышел?
                bhi     12$         ; нет, нормально всё
                decb    L.TPSN(R5)  ; вышел - корректируем
                br      21$         ; и просто продолжаем, без формирования новых данных
; ───────────────────────────────────────────────────────────────────────────

12$:            mov     #1, R4
                mov     R0, R3
                beq     13$
14$:            asl     R4          ; делаем маску фрагмента
                sob     R3, 14$
13$:            mov     L.ASMP(R5), R3 ; адрес сэмпла
                add     R3, R0      ; смещение до параметров фрагмента
                clr     R1
                bisb    63(R0), R1  ; берём параметры фрагмента огибающей шума
                bit     6(R3), R4   ; проверяем маску в огибающей шума
                bne     15$         ; шум есть - переход
                bisb    L.CNMN(R5), AYREG1+Y.MIXR   ; выключаем шум
                br      151$
15$:            bicb    L.CNMN(R5), AYREG1+Y.MIXR   ; включаем шум
151$:           mov     R1, R2
                bic     #340, R1    ; это уровень
                bic     R1, R2      ; это длительность
                bit     12(R3), R4  ; и не поместившийся мл.бит
                beq     16$
                add     #20, R2     ; помещаем на место
16$:            asr     R2
                asr     R2          ; длит * 16 / 4
                beq     17$
                sub     #3, R2
17$:            add     L.L1FR(R5), R2 ; формируем длительность
                movb    R1, L.RVLN+1(R5) ; уровень текущего фрагмента -> в конечное значение
                movb    R2, L.TSLN(R5)
                tst     6(R3)       ; шум менять плавно?
                bmi     18$         ; да
                movb    R1, L.CVLN+1(R5)    ; нет - сразу сделаем конечный результат
                br      21$
; ───────────────────────────────────────────────────────────────────────────

18$:            clr     R4
                movb    L.CVLN+1(R5), R0    ; текущее значение
                sub     R0, R1  ; дельта = конечное значение - текущее значение
                bpl     19$     ; если отрицательное
                inc     R4      ; знак поменяем
                neg     R1      ; и отметим флагом
19$:            swab    R1      ; d*256.
                call    DIVIDE  ; деление
                                ; вход: R1 - делимое
                                ;       R2 - делитель
                                ; выход: R1 - целая часть
                                ;       R3 - остаток
                tst     R4
                beq     20$
                neg     R1
20$:            mov     R1, L.DVLN(R5)  ; приращение при плавном изменении шума
                ; с шумом разобрались, теперь - с тоном.
21$:            decb    L.TSLT(R5)  ; текущий фрагмент тона отзвучал?
                bpl     36$         ; нет ещё, продолжим
                incb    L.TPST(R5)
                movb    L.TPST(R5), R0  ; текущий фрагмент тона в сэмпле
                tstb    L.PAUS(R5)  ; пауза?
                bne     22$         ; да
                cmpb    L.ECYT(R5), R0  ; нет - дошли до конца зацикливания?
                bhis    22$         ; нет ещё
                movb    L.BCYT(R5), R0  ; да - начнём сначала
                movb    R0, L.TPST(R5)  ; обновим текущий фрагмент
22$:            cmpb    #13., R0        ; фрагмент за границы не вышел?
                bhi     23$             ; нет, нормально всё
                decb    L.TPST(R5)      ; вышел - корректируем
                br      36$             ; и просто продолжаем, без формирования новых данных
; ───────────────────────────────────────────────────────────────────────────

23$:            mov     L.ASMP(R5), R3  ; адрес текущего сэмпла
                asl     R0
                add     R3, R0          ; смещение до параметров фрагмента
                mov     14(R0), R0      ; берём параметры фрагмента огибающей тона
                mov     R0, R1
                bit     #2000, R0       ; признак минуса?
                beq     24$             ; нет
                neg     R1              ; да - меняем знак
24$:            bic     #176000, R1     ; оставляем только значение
                movb    L.NOTN(R5), R4  ; берём номер текущей ноты
                bit     #4000, R0       ; значения в полутонах?
                beq     25$             ; нет - переход
                bit     #2000, R0       ; да, снова проверим на минус
                bne     26$             ; перейдём обрабатывать минус
                add     R1, R4          ; прибавим полутона к ноте
                cmp     R4, #140        ; проверим, вышли ли за границу?
                blo     27$             ; нет
                mov     #137, R4        ; да - скорректируем
                br      27$
; ───────────────────────────────────────────────────────────────────────────

26$:            sub     R1, R4          ; отнимем полутона от ноты
                bpl     27$             ; проверим, вышли ли за границу?
                clr     R4              ; да - скорректируем
27$:            asl     R4
                mov     NOTCLK(R4), R4  ; получим частоту ноты
                br      28$
; ───────────────────────────────────────────────────────────────────────────

25$:            asl     R4
                mov     NOTCLK(R4), R4  ; возьмём частоту ноты
                bit     #2000, R0       ; снова проверим на минус
                beq     29$             ; перейдём обрабатывать минус
                add     R1, R4          ; прибавим частоту к частоте ноты
                br      28$
; ───────────────────────────────────────────────────────────────────────────

29$:            sub     R1, R4          ; отнимем частоту от частоты ноты
                bpl     28$             ; проверим, вышли ли за границу?
                clr     R4              ; да - скорректируем
28$:            mov     R4, R1          ; вот результирующая частота
                clrb    L.FLCT(R5)
                mov     R0, R2
                swab    R2
                bic     #177417, R2     ; длительность фрагмента * 16
                asr     R2
                asr     R2              ; делим на 4
                beq     30$
                sub     #3, R2
30$:            add     L.L1FR(R5), R2  ; формируем длительность
                movb    R2, L.TSLT(R5)
                tst     2(R3)           ; тон менять плавно?
                bmi     31$             ; да
                mov     R1, L.CVLT+2(R5) ; нет - результат в конечное значение
                comb    L.FLCT(R5)
                br      36$
; ───────────────────────────────────────────────────────────────────────────

31$:            mov     L.CVLT+2(R5), R4 ; текущее значение
                mov     R1, L.RVLT(R5)  ; конечное значение
                sub     R4, R1      ; дельта = конечное значение - текущее значение
                bpl     32$         ; если отрицательное
                neg     R1          ; знак поменяем
                incb    L.FLCT(R5)  ; и отметим флагом
32$:            call    DIVIDE  ; деление
                                ; вход: R1 - делимое
                                ;       R2 - делитель
                                ; выход: R1 - целая часть
                                ;       R3 - остаток
                mov     #10, R0 ; ещё раз делим
                clr     R4
34$:            asl     R4
                asl     R3
                cmp     R3, R2
                blo     33$
                sub     R2, R3
                inc     R4
33$:            sob     R0, 34$
                tstb    L.FLCT(R5)
                beq     35$
                neg     R4
                neg     R1
                dec     R1
35$:            movb    R4, L.DVLT+1(R5)    ; формируем
                mov     R1, L.DVLT+2(R5)    ; приращение при плавном изменении тона
                ; всё, формируем значения для регистров AY
36$:            mov     #AYREG1, R3
                mov     R3, R0
                add     #Y.MIXR, R0
                bisb    MIXSWC+1, (R0)  ; применяем биты селектора каналов
                add     L.DVLV(R5), L.CVLV(R5)  ; прибавляем приращение громкости к текущему значению
                tstb    L.TSLV(R5)  ; фрагмент ещё не отзвучал?
                bne     37$         ; нет ещё
                mov     L.RVLV(R5), L.CVLV(R5) ; да - формируем конечное значение
37$:            movb    L.CNOA(R5), R4  ; смещение до адреса регистра амплитуды
                add     R3, R4  ; адрес регистра амплитуды
                bitb    L.CNMN(R5), (R0)    ; шум есть?
                beq     44$         ; есть - переход
                bitb    L.CNMT(R5), (R0) ; нету, а тон есть?
                bne     45$         ; нету - переход
44$:            tstb    L.ATTR(R5)  ; у ноты Volume есть?
                bmi     38$         ; есть - переход
                movb    #20, (R4)   ; нету - делаем признак волпака
                bisb    L.CNMN(R5), (R0) ; запрещаем шум
                movb    L.VPER(R5), Y.PERD(R3) ; задаём период
                br      39$
; ───────────────────────────────────────────────────────────────────────────

38$:            movb    L.CVLV+1(R5), R1 ; берём громкость
                movb    L.VVAL(R5), R2  ; берём приращение громкости
                sub     R2, R1  ; вычисляем
                bpl     40$
45$:            clr     R1
40$:            movb    R1, (R4)    ; задаём громкость

39$:            add     L.DVLN(R5), L.CVLN(R5)  ; прибавляем приращение шума к текущему значению
                tstb    L.TSLN(R5)  ; фрагмент ещё не отзвучал?
                bne     41$         ; нет ещё
                mov     L.RVLN(R5), L.CVLN(R5)  ; да - формируем конечное значение
41$:            bitb    L.CNMN(R5), (R0)    ; шум есть?
                bne     42$         ; нету - переход
                tstb    (R4)        ; есть, а громкость есть?
                beq     42$         ; нету
                movb    L.CVLN+1(R5), Y.NOIS(R3) ; есть - уровень шума в регистр

42$:            tstb    L.FLCT(R5)  ; что с тоном?
                bmi     43$         ; меняется резко - переход
                add     L.DVLT(R5), L.CVLT(R5) ; меняется плавно, прибавим приращение
                adc     L.CVLT+2(R5)
                add     L.DVLT+2(R5), L.CVLT+2(R5)
                tstb    L.TSLT(R5)  ; фрагмент ещё не отзвучал?
                bne     43$         ; нет ещё
                mov     L.RVLT(R5), L.CVLT+2(R5)    ; да - формируем конечное значение
                comb    L.FLCT(R5)
43$:            movb    L.CNMT(R5), R4  ; маска тона в миксере, используется вместо адреса регистра тона, потому что ячеек не хватило
                add     R3, R4      ; адрес регистра тона
                mov     L.CVLT+2(R5), (R4)  ; задаём тон
                clr     L.L1FR(R5)
                add     #CHPLN, R5
                return

; звучание ноты в редакторе раздела по клавише ТАБ
L26364:         call    PLAY1
; ███████████████████████████████████████████████████████████████████████████
; ███████████████ Э К В А Л А Й З Е Р ███████████████████████████████████████
; ███████████████████████████████████████████████████████████████████████████

; вызов по таймеру
TMRSPE:         jsr     R5, @#PUSHA
; непосредственный вызов
SPECAN:         mov     #EQUMAX, R0
                mov     #17, R1
1$:             clr     (R0)+       ; чистим буфер максимальных значений
                sob     R1, 1$  ; далее R1 должен быть == 0
                movb    AYREG1+Y.MIXR, R2   ; берём миксер
                clr     R3      ; детектор волпака

                movb    AYREG1+Y.AMPA, R4   ; амплитуда канала A
                beq     2$      ; если 0 - переход
                bis     R4, R3  ; есть - может там волпак?
                bitb    #1, R2  ; тон есть?
                bne     3$      ; нету
                mov     AYREG1+Y.CLKA, R0 ; иначе - берём частоту
                call    S24426  ; установим максимальную амплитуду для полосы заданной частоты
3$:             bitb    #10, R2 ; шум есть?
                bne     2$      ; нету
                add     R4, R1  ; есть - значение в накопитель уровня шума

2$:             movb    AYREG1+Y.AMPB, R4   ; амплитуда канала B
                beq     5$      ; если 0 - переход
                bisb    R4, R3  ; есть - может там волпак?
                bitb    #2, R2  ; тон есть?
                bne     4$      ; нету
                mov     AYREG1+Y.CLKB, R0   ; берём частоту
                call    S24426  ; установим максимальную амплитуду для полосы заданной частоты
4$:             bitb    #20, R2 ; шум есть?
                bne     5$      ; нету
                add     R4, R1  ; есть - значение в накопитель уровня шума

5$:             movb    AYREG1+Y.AMPC, R4   ; амплитуда канала C
                beq     7$      ; если 0 - переход
                bisb    R4, R3  ; есть - может там волпак?
                bitb    #4, R2  ; тон есть?
                bne     6$      ; нету
                mov     AYREG1+Y.CLKC, R0   ; берём частоту
                call    S24426  ; установим максимальную амплитуду для полосы заданной частоты
6$:             bitb    #40, R2 ; шум есть?
                bne     7$      ; нету
                add     R4, R1  ; есть - значение в накопитель уровня шума

7$:             bic     #177757, R3 ; проверим, может хоть где-то волпак
                beq     8$          ; нигде нету - переходим
                tstb    AYREG1+Y.VPCK
                beq     8$
                mov     R3, R4      ; R4 == #20
                clr     R0
                bisb    AYREG1+Y.PERD, R0 ; младший байт периода
                asr     R0
                asr     R0
                asr     R0      ; его ещё и на 8 поделим, чтобы в число полос попадал.
                call    S24366

8$:             movb    R1, R4  ; уровень шума > 0?
                beq     9$      ; нет, 0 - переход
                movb    AYREG1+Y.NOIS, R1   ; частота шума
                sub     #2, R1
                mov     #W24460, R2
                mov     #5, R3
12$:            mov     R1, R0
                bpl     10$
                clr     R0
10$:            mov     R4, -(SP)
                sub     (R2)+, R4
                bmi     11$
                call    S24366  ; делаем из шума горб из 5ти полос
11$:            inc     R1
                mov     (SP)+, R4
                sob     R3, 12$

9$:             tst     (PC)+
OPT$EQ:         .word   1       ; опция 0 - старый 1 - новый вид
                beq     OLDEQ
; новый рабочий код - с пиками
                mov     #EQUMAX, R0 ; тут у нас текущие максимальные значения
                mov     #EQUWRK, R1 ; тут рабочий массив
                mov     #36, R2
; цикл обработки колонок эквалайзера
19$:            movb    (R1), R3    ; берём рабочее значение
                movb    (R0)+, R4   ; берём текущий максимум
                cmpb    R4, R3      ; что текущее значение?
                beq     15$         ; если равно рабочему  - ничего не делаем
                blo     13$         ; меньше - уменьшаем шкалу

22$:            incb    R3          ; увеличиваем рабочее значение
                cmpb    #17, R3     ; за пределы максимума вышли?
                bhis    14$         ; нет
                movb    #17, R3     ; да - корректируем
14$:            movb    R3, (R1)    ; сохраняем
                call    EQDRWS
                movb    (R1), R3    ; снова берём значение
                cmpb    R3, R4      ; до текущего доросло?
                blo     22$
                inc     R1
                movb    #3, (R1)+   ; счётчик инициализируем
                cmpb    R3, (R1)    ; если оно меньше ткущего максимума
                blo     17$         ; то пропускаем
                movb    R3, (R1)    ; иначе обновляем максимум
                movb    #100, 1(R1) ; длительность свечения пика
                br      17$
; ───────────────────────────────────────────────────────────────────────────

13$:            inc     R1
                decb    (R1)+       ; иначе  уменьшаем счётчик свечения элемента шкалы
                bgt     17$         ; если ещё не 0 - ничего не делаем
                movb    #3, -(R1)   ; счётчик инициализируем
                decb    -(R1)       ; уменьшаем значение в массиве
                bpl     18$         ; если >=0 идём стирать
                clrb    (R1)        ; иначе - корректируем, и не стираем
                br      15$

18$:            cmpb    2(R1), R3   ; если это максимум
                beq     15$         ; то его стирать не надо, он в другом месте стирается
                clr     R5          ; иначе - будем уменьшать шкалу
                call    EQDRWC
15$:            tst     (R1)+
17$:            movb    (R1)+, R3
                ble     21$
                decb    (R1)
                bne     21$
                clrb    -(R1)
                clr     R5
                call    EQDRWC
                inc     R1
21$:            inc     R1
                sob     R2, 19$
                return

; старый рабочий код
OLDEQ:          mov     PC, -(SP)   ; далее - выполнять два раза
                mov     #EQUMAX, R0 ; тут у нас текущие максимальные значения
                mov     #EQUWRK, R1 ; тут рабочий массив
                mov     #36, R2
; цикл обработки колонок эквалайзера
19$:            movb    (R1), R3    ; берём рабочее значение
                cmpb    (R0)+, R3   ; что текущее значение?
                beq     15$         ; если равно рабочему  - ничего не делаем
                blo     13$         ; меньше - уменьшаем шкалу
                incb    R3          ; увеличиваем рабочее значение
                cmpb    #17, R3     ; за пределы максимума вышли?
                bhis    14$         ; нет
                movb    #17, R3     ; да - корректируем
14$:            movb    R3, (R1)+   ; сохраняем
                call    EQDRWS
                movb    #10, (R1)+  ; счётчик инициализируем, верхний сегмент светится чуточку дольше
                br      17$
; ───────────────────────────────────────────────────────────────────────────

13$:            inc     R1
                decb    (R1)+       ; иначе  уменьшаем счётчик свечения элемента шкалы
                bgt     17$         ; если ещё не 0 - ничего не делаем
                movb    #6, -(R1)   ; счётчик инициализируем
                decb    -(R1)       ; уменьшаем значение в массиве
                bpl     18$         ; если >=0 - сотрём элемент шкалы
                clrb    (R1)        ; иначе - корректируем, и не стираем
                br      15$

18$:            clr     R5          ; иначе - будем уменьшать шкалу
                call    EQDRWC
15$:            tst     (R1)+
17$:            sob     R2, 19$
                return
; End of function SPECAN

EQDRWS:         mov     #25252, R5  ; это цвет сегмента
                cmpb    #16, R3     ; два верхних сегмента
                bhi     EQDRWC
                mov     #37777, R5  ; будут красными
EQDRWC:         swab    R3
                neg     R3
                add     #76100, R3  ; делаем из него адрес
                add     R2, R3
                add     R2, R3      ; находим колонку
                mov     R5, (R3)    ; и в ней дорисовываем шкалу
                mov     R5, -100(R3)
                mov     R5, -200(R3)
                return


; ███████████████ S U B R O U T I N E ███████████████████████████████████████
; вход:  R0 - частота волпака
;       R4 - амплитуда
S24366:         mov     R1, -(SP)
                mov     R0, R1
                bic     #177740, R1 ; берём младшие 5 бит
                dec     R1
                bpl     1$
                clr     R1
1$:             cmp     #36, R1     ; умещаем их в [0..35]
                bhi     24412$
                mov     #35, R1
                br      24412$
; End of function S24366

; ███████████████ S U B R O U T I N E ███████████████████████████████████████
; вход:  R0 - частота тона
;       R4 - амплитуда
S24426:         mov     R1, -(SP)
                mov     #F24624+74, R1
4$:             cmp     @-(R1), R0  ; массив частот полос анализатора спектра
                bhi     4$
3$:             sub     #F24624, R1
                asr     R1              ; нашли, получим номер от начала массива
24412$:         cmpb    #17, R4     ; за пределы максимума вышли?
                bhis    23$         ; нет
                movb    #17, R4     ; да - корректируем
23$:            cmpb    EQUMAX(R1), R4
                bgt     2$
                movb    R4, EQUMAX(R1)  ; запомним в массиве максимальное значение
2$:             mov     (SP)+, R1
                return
; End of function S24426


; ──────Фонт─────────────────────────────────────────────────────────────────

                .word 0, 314, 176314, 30374, 6314, 176314, 0, 0     ; 034 Hz
                .word 0, 0, 1714, 6074, 6014, 6014, 0, 0            ; 035 n
                .word 0, 176000, 7400, 1700, 360, 77, 0, 0          ; 036 _/~
                .word 0, 177700, 1700, 1700, 1700, 1777, 0, 0       ; 037 _|~
RMFONT:         .word 0, 0, 0, 0, 0, 0, 0, 0                        ; 040 пробел
                .word 0, 6000, 1400, 300, 0, 14, 0, 0               ; 041 !
                .word 0, 1460, 314, 0, 0, 0, 0, 0                   ; 042 "
                .word 0, 1460, 7774, 1460, 7774, 1460, 0, 0         ; 043 #
                .word 0, 6014, 1760, 1460, 1760, 6014, 0, 0         ; 044 $
                .word 0, 6014, 1400, 300, 60, 6014, 0, 0            ; 045 %
                .word 0, 1700, 60, 6300, 1460, 6360, 0, 0           ; 046 &
                .word 0, 1400, 300, 60, 0, 0, 0, 0                  ; 047 '
                .word 0, 1400, 300, 300, 300, 1400, 0, 0            ; 050 (
                .word 0, 300, 1400, 1400, 1400, 300, 0, 0           ; 051 )
                .word 0, 300, 6314, 1760, 6314, 300, 0, 0           ; 052 *
                .word 0, 300, 300, 7774, 300, 300, 0, 0             ; 053 +
                .word 0, 0, 0, 0, 0, 300, 60, 0                     ; 054 ,
                .word 0, 0, 0, 7760, 0, 0, 0, 0                     ; 055 -
                .word 0, 0, 0, 0, 0, 300, 0, 0                      ; 056 .
                .word 0, 6000, 1400, 300, 60, 14, 0, 0              ; 057 /
                .word 0, 1760, 6014, 6014, 6014, 1760, 0, 0         ; 060 0
                .word 0, 1400, 1700, 1400, 1400, 1400, 0, 0         ; 061 1
                .word 0, 1760, 6014, 1700, 60, 7774, 0, 0           ; 062 2
                .word 0, 7774, 6000, 1700, 6014, 1760, 0, 0         ; 063 3
                .word 0, 1400, 1700, 1460, 7774, 1400, 0, 0         ; 064 4
                .word 0, 7774, 14, 1774, 6000, 1774, 0, 0           ; 065 5
                .word 0, 1760, 14, 1774, 6014, 1760, 0, 0           ; 066 6
                .word 0, 7774, 6000, 1400, 300, 300, 0, 0           ; 067 7
                .word 0, 1760, 6014, 1760, 6014, 1760, 0, 0         ; 070 8
                .word 0, 1760, 6014, 7760, 6000, 1760, 0, 0         ; 071 9
                .word 0, 0, 300, 0, 300, 0, 0, 0                    ; 072 :
                .word 0, 0, 300, 0, 0, 300, 60, 0                   ; 073 ; 
W30700:         .word 0, 1400, 1700, 1760, 1700, 1400, 0, 0         ; 074 <
                .word 0, 0, 7760, 0, 7760, 0, 0, 0                  ; 075 =
                .word 0, 300, 1700, 7700, 1700, 300, 0, 0           ; 076 >
                .word 0, 1760, 6014, 1700, 0, 300, 0, 0             ; 077 ?
                .word 7760, 30014, 31714, 30314, 31714, 30014, 7760, 0  ; 100 @
                .word 0, 1760, 6014, 7774, 6014, 6014, 0, 0         ; 101 A
                .word 0, 1774, 6014, 1774, 6014, 1774, 0, 0         ; 102 B
                .word 0, 1760, 6014, 14, 6014, 1760, 0, 0           ; 103 C
                .word 0, 374, 1414, 6014, 1414, 374, 0, 0           ; 104 D
                .word 0, 7774, 14, 1774, 14, 7774, 0, 0             ; 105 E
                .word 0, 7774, 14, 1774, 14, 14, 0, 0               ; 106 F
                .word 0, 7760, 14, 7414, 6014, 7760, 0, 0           ; 107 G
                .word 0, 6014, 6014, 7774, 6014, 6014, 0, 0         ; 110 H
                .word 0, 1760, 300, 300, 300, 1760, 0, 0            ; 111 I
                .word 0, 6000, 6000, 6000, 6014, 1760, 0, 0         ; 112 J
                .word 0, 6014, 1414, 374, 1414, 6014, 0, 0          ; 113 K
                .word 0, 14, 14, 14, 14, 7774, 0, 0                 ; 114 L
                .word 0, 6014, 7474, 6314, 6014, 6014, 0, 0         ; 115 M
                .word 0, 6014, 6074, 6314, 7414, 6014, 0, 0         ; 116 N
                .word 0, 1760, 6014, 6014, 6014, 1760, 0, 0         ; 117 O
                .word 0, 1774, 6014, 1774, 14, 14, 0, 0             ; 120 P
                .word 0, 1760, 6014, 6014, 6014, 1760, 7400, 0      ; 121 Q
                .word 0, 1774, 6014, 1774, 1414, 6014, 0, 0         ; 122 R
                .word 0, 7760, 14, 1760, 6000, 1774, 0, 0           ; 123 S
                .word 0, 7774, 300, 300, 300, 300, 0, 0             ; 124 T
                .word 0, 6014, 6014, 6014, 6014, 1760, 0, 0         ; 125 U
                .word 0, 6014, 6014, 6014, 1460, 300, 0, 0          ; 126 V
                .word 0, 6014, 6314, 6314, 6314, 1460, 0, 0         ; 127 W
                .word 0, 6014, 1460, 300, 1460, 6014, 0, 0          ; 130 X
                .word 0, 6014, 1460, 300, 300, 300, 0, 0            ; 131 Y
                .word 0, 7774, 1400, 300, 60, 7774, 0, 0            ; 132 Z
RMPLFN:         .word 0, 1760, 6014, 6014, 6014, 1760, 0, 0         ; 133/0 0
                .word 0, 1400, 1700, 1400, 1400, 1400, 0, 0         ; 134/1 1
                .word 0, 1760, 6014, 1700, 60, 7774, 0, 0           ; 135/2 2
                .word 0, 7774, 6000, 1700, 6014, 1760, 0, 0         ; 136/3 3
                .word 0, 1400, 1700, 1460, 7774, 1400, 0, 0         ; 137/4 4
                .word 0, 7774, 14, 1774, 6000, 1774, 0, 0           ; 140/5 5
                .word 0, 1760, 14, 1774, 6014, 1760, 0, 0           ; 141/6 6
                .word 0, 7774, 6000, 1400, 300, 300, 0, 0           ; 142/7 7
                .word 0, 1760, 6014, 1760, 6014, 1760, 0, 0         ; 143/10 8
                .word 0, 1760, 6014, 7760, 6000, 1760, 0, 0         ; 144/11 9
                .word 0, 1760, 6014, 7774, 6014, 6014, 0, 0         ; 145/12 A
                .word 0, 1774, 6014, 1774, 6014, 1774, 0, 0         ; 146/13 B
                .word 0, 1760, 6014, 14, 6014, 1760, 0, 0           ; 147/14 C
                .word 0, 374, 1414, 6014, 1414, 374, 0, 0           ; 150/15 D
                .word 0, 7774, 14, 1774, 14, 7774, 0, 0             ; 151/16 E
                .word 0, 7774, 14, 1774, 14, 14, 0, 0               ; 152/17 F
                .word 0, 7760, 14, 7414, 6014, 7760, 0, 0           ; 153/20 G
                .word 0, 0, 0, 7774, 0, 0, 0, 0                     ; 154/21 - (длинный дефис)
                .word 0, 1460, 7774, 1460, 7774, 1460, 0, 0         ; 155/22 #
                .word 0, 0, 0, 300, 0, 0, 0, 0                      ; 156/23  (точка по центру)
                .word 0, 6014, 6014, 6014, 1460, 300, 0, 0          ; 157/24 v
                .word 0, 0, 0, 0, 0, 0, 360, 0                      ; 160/25 _ (половинка подчёркивания)
                .word 0, 1774, 6014, 1774, 1414, 6014, 0, 0         ; 161/26 R
                .word 170377, 146377, 176377, 176377, 176377, 176017, 0, 177417 ; 162/27 инверсный знак ноты
                .word 0, 300, 1760, 7774, 7474, 6014, 0, 0          ; 163/30 ^ (стрелка вверх)
                .word 0, 6014, 7474, 7774, 1760, 300, 0, 0          ; 164/31 v (стрелка вниз)
                .word 0, 0, 177700, 300, 176300, 6300, 6300, 6300   ; 165/32 ╔ (левый верхний угол)
                .word 0, 0, 177777, 0, 177777, 0, 0, 0              ; 166/33 ═ (двойная горизонталь)
                .word 0, 0, 7777, 6000, 6377, 6300, 6300, 6300      ; 167/34 ╗ (правый верхний угол)
                .word 6300, 6300, 6300, 6300, 6300, 6300, 6300, 6300 ; 170/35 ║ (двойная вертикаль)
                .word 6300, 6300, 6377, 6000, 7777, 0, 0, 0         ; 171/36 ╝ (правый нижний угол)
                .word 6300, 6300, 176300, 300, 177700, 0, 0, 0      ; 172/37 ╚ (левый нижний угол)
                .word 6300, 6300, 176300, 300, 176300, 6300, 6300, 6300 ; 173/40 │- (левый двойной стык)
                .word 0, 0, 177777, 0, 176377, 6300, 6300, 6300     ; 174/41 Т (верхний двойной стык)
                .word 6300, 6300, 6377, 6000, 6377, 6300, 6300, 6300 ; 175/42 -|(правый двойной стык)
                .word 6300, 6300, 176377, 0, 177777, 0, 0, 0        ; 176/43 (нижний двойной стык)
                .word 6300, 6300, 176377, 0, 176377, 6300, 6300, 6300 ; 177/44 (двойное пересечение)

; ───────────────────────────────────────────────────────────────────────────
; Массив переменных
CurrMenuPt:     .word   0   ; начало текущего обрабатываемого меню
INKFL$:         .byte   0   ; флаг автоповтора
FLGCH$:         .byte   0
NEWCH$:         .word   0
OS$REG:         .word   0   ; флаг регистра символов
; ───────────────────────────────────────────────────────────────────────────
COLTBL:         .byte   0, 125, 252, 377    ; таблица цветов
BGCOLR:         .word   0   ; цвет фона
COLMSK:         .word   0   ; инверсная маска цвета символов.
W$FLG:          .byte   0   ; флаг, что окно распахнулось до заданной ширины
H$FLG:          .byte   0   ; флаг, что окно распахнулось до заданной высоты
STADDR:         .word   0   ; начальный адрес буфера
; ───────────────────────────────────────────────────────────────────────────
TMPBGC:         .word   0   ; временный цвет фона
TMPCLM:         .word   0   ; временная инверсная маска цвета символов.
CURPOS:         .word   0   ; Номер позиции в цепочке разделов
CURPAT:         .word   0   ; Номер текущего раздела.
PLPTNR:         .word   0   ; Номер раздела, который будет проигрываться.
PLYPOS:         .byte   0   ; Позиция в цепочке разделов при проигрывании всей мелодии
PLY$FP:         .byte   0   ; флаг, что играем - 0 текущий раздел, !0 - всю мелодию
TPTADR:         .word   0   ; временный адрес раздела
PCPTBG:         .word   0   ; адрес начала текущего раздела
PCPTLN:         .word   0   ; длина текущего раздела
PCPTAD:         .word   0   ; указатель адреса в текущем разделе
KURSAD:         .word   60212 ; проинициализированное значение, текущий адрес курсора
CURNLN:         .word   0   ; текущий номер строки в нотном тексте редактора разделов
W13210:         .word   0   ; адрес начала раздела, который очищается по кнопке СБР
W13360:         .word   0   ; адрес начала канала, который очищается по кнопке -|->
W13372:         .word   0   ; адрес конца канала, который очищается по кнопке -|->
W14034:         .word   0   ; длина текущего раздела
W22614:         .word   0   ; адрес текущей ноты в канале, которая звучит по клавише ТАБ
MIXSWC:         .word   0   ; селектор каналов в редакторе
HEIGH1:         .byte   0   ; высота проигрыша текущего раздела
EDSAMN:         .byte   0   ; номер редактируемого сэмпла
MUTEAY:         .word   0   ; флаг глушения AY в прерывании по вектору 100 в редакторе сэмплов.
BF$SPD:         .word   0   ; буфер стека для главного меню
BF$SPC:         .word   0   ; буфер стека меню подтверждения удаления
F25654:         .word   0   ; база меню копирования, транспонирования
BFCPTR:         .blkb   24  ; буфер параметров меню копирование и транспонирование, длиной 13 слов
; ───────────────────────────────────────────────────────────────────────────
; блок параметров проигрывателя
; три блока по 70 байтов на канал
VARPR1:         .word   177400,177777,0,7417,7417,7417 ; проинициализированные значения циклов
                .blkb   47
                .byte   1,10,10,0,0 ; константы
                .word   177400,177777,0,7417,7417,7417
                .blkb   47
                .byte   2,20,11,0,0
                .word   177400,177777,0,7417,7417,7417
                .blkb   47
                .byte   4,40,12,0,0
AYREG1:         .blkb   20  ; Ещё массив звучания, общий для всех каналов,
                            ; здесь формируется то, что выводится в регистры AY
; ───────────────────────────────────────────────────────────────────────────
; тут формируется текстовое представление текущей ноты. массив 36 байтов
W37404:         .word 0     ; номер ноты в разделе
                .byte 3     ; три байта
                .byte 377   ; эти 4 байта от B37410 вверх
B37410:         .byte 21
                .byte 21
                .byte 21
                .byte 377   ; байты <0 - разделители
                .byte 23
                .byte 23
                .byte 23
                .byte 23
                .byte 377
                .byte 21
                .byte 21
                .byte 21
                .byte 377
                .byte 23
                .byte 23
                .byte 23
                .byte 23
                .byte 377
                .byte 21
                .byte 21
                .byte 21
                .byte 377
                .byte 23
                .byte 23
                .byte 23
                .byte 23
; ───────────────────────────────────────────────────────────────────────────
; массив текстовых представлений нот. 2 байта на ноту
B10524:         .byte   14, 21  ; C-
                .byte   14, 22  ; C#
                .byte   15, 21  ; D-
                .byte   15, 22  ; D#
                .byte   16, 21  ; E-
                .byte   17, 21  ; F-
                .byte   17, 22  ; F#
                .byte   20, 21  ; G-
                .byte   20, 22  ; G#
                .byte   12, 21  ; A-
                .byte   12, 22  ; A#
                .byte   13, 21  ; B-
; ───────────────────────────────────────────────────────────────────────────
EQUMAX:         .blkb 36    ; массив текущих мгновенных уровней эквалайзера длиной 36 байтов
EQUWRK:         .blkw 74    ; массив рабочих значений эквалайзера длиной 36*4 байта
; ───────────────────────────────────────────────────────────────────────────
F24624:         ; массив указателей на граничные частоты из таблицы частот для эквалайзера
                .word W24464    ; а это 0
                .word W5672
                .word W5664
                .word W5654
                .word W5644
                .word W5640
                .word W5632
                .word W5624
                .word W5614
                .word W5604
                .word W5600
                .word W5572
                .word W5564
                .word W5554
                .word W5544
                .word W5540
                .word W5532
                .word W5524
                .word W5514
                .word W5504
                .word W5500
                .word W5472
                .word W5464
                .word W5454
                .word W5444
                .word W5440
                .word W5432
                .word W5424
                .word W5414
                .word W5404
; ───────────────────────────────────────────────────────────────────────────
W24460:         .word 6     ; массив амплитуд для рисования горба шума в анализаторе
                .word 3
W24464:         .word 0
                .word 3
                .word 6
; ───────────────────────────────────────────────────────────────────────────
NOTKEY:         .byte   'X      ; B
                .byte   'O      ; A#
                .byte   'T      ; A
                .byte   'R      ; G#
                .byte   'I      ; G
                .byte   'P      ; F#
                .byte   'M      ; F
                .byte   'S      ; E
                .byte   'W      ; D#
                .byte   '^      ; D
                .byte   'Y      ; C#
                .byte   'Q      ; C
                .even
; ───────────────────────────────────────────────────────────────────────────
; массив нот
; октава 1
NOTCLK:         .word 7370
W5404:          .word 7020
                .word 6540
                .word 6200
                .word 5730
W5414:          .word 5450
                .word 5210
                .word 4760
                .word 4540
W5424:          .word 4340
                .word 4130
                .word 3740
; октава 2
W5432:          .word 3574
                .word 3410
                .word 3260
W5440:          .word 3100
                .word 2754
W5444:          .word 2624
                .word 2504
                .word 2370
                .word 2260
W5454:          .word 2160
                .word 2054
                .word 1760
; октава 3
                .word 1676
W5464:          .word 1604
                .word 1530
                .word 1440
W5472:          .word 1366
                .word 1312
                .word 1242
W5500:          .word 1174
                .word 1130
W5504:          .word 1070
                .word 1026
                .word 770
; октава 4
                .word 737
W5514:          .word 702
                .word 654
                .word 620
                .word 573
W5524:          .word 545
                .word 521
                .word 476
W5532:          .word 454
                .word 434
                .word 413
W5540:          .word 374
; октава 5
                .word 357
W5544:          .word 341
                .word 326
                .word 310
                .word 275
W5554:          .word 262
                .word 250
                .word 237
                .word 226
W5564:          .word 216
                .word 205
                .word 176
; октава 6
W5572:          .word 167
                .word 160
                .word 153
W5600:          .word 144
                .word 136
W5604:          .word 131
                .word 124
                .word 117
                .word 113
W5614:          .word 107
                .word 102
                .word 77
; октава 7
                .word 73
W5624:          .word 70
                .word 65
                .word 62
W5632:          .word 57
                .word 54
                .word 52
W5640:          .word 47
                .word 45
W5644:          .word 43
                .word 41
                .word 37
; октава 8
                .word 35
W5654:          .word 34
                .word 32
                .word 31
                .word 27
W5664:          .word 26
                .word 25
                .word 23
W5672:          .word 22
                .word 21
                .word 20
                .word 17
; ───────────────────────────────────────────────────────────────────────────

; массивы меню.
; текст главного меню
T$MMNU:         .byte 217
                .byte 174
                .byte 206
                .byte 174
                .byte 301
                .ascii "POSITION "
MMPOS:          .ascii "000"
                .byte 163
                .byte 164
                .byte 170
                .ascii " SAVE "
                .byte 170
                .ascii " SAMPLE"
                .byte 301
                .ascii "PATTERN"
                .byte 202
ACNPTN:         .ascii "000"
                .byte 163
                .byte 164
                .byte 170
                .ascii " LOAD "
                .byte 170
                .ascii " COMPIL"
                .byte 301
                .ascii "HEIGHT"
                .byte 203
ACNHGT:         .ascii "000"
                .byte 163
                .byte 164
                .byte 170
                .ascii " COPY "
                .byte 170
                .ascii " TRANSP"
                .byte 301
                .ascii "LENGTH"
                .byte 203
MMLENS:         .ascii "000"
                .byte 163
                .byte 164
                .byte 170
                .ascii "OPTION"
                .byte 170
                .ascii " DELETE"
                .byte 300
                .byte 173
                .byte 166
                .byte 166
                .byte 166
                .byte 166
                .byte 166
                .byte 166
                .byte 166
                .byte 166
                .byte 166
                .byte 166
                .byte 166
                .byte 166
                .byte 166
                .byte 166
                .byte 177
                .byte 166
                .byte 166
                .byte 166
                .byte 166
                .byte 166
                .byte 166
                .byte 175
                .byte 202
                .ascii "PLAY"
                .byte 301
                .ascii "PATTERN"
                .byte 202
MMPTRN:         .ascii "000"
                .byte 163
                .byte 164
                .byte 170
ACASTA:         .ascii " A>ON "
                .byte 170
                .byte 202
                .ascii "TEMP"
                .byte 301
                .ascii "LENGTH"
                .byte 203
MMLEN:          .ascii "000"
                .byte 202
                .byte 170
ACBSTA:         .ascii " B>ON "
                .byte 170
                .ascii " ''''''"
                .byte 301
                .ascii "FREE"
                .byte 205
MMFREE:         .ascii "00000"
                .byte 170
ACCSTA:         .ascii " C>ON "
                .byte 170
                .byte 202
                .ascii "EXIT"
                .byte 317
                .byte 176
                .byte 206
                .byte 176
                .byte 0
                .even
                .word 0 ; конец строки, нет меню.

T$SPAN:         .byte 30
                .byte 36
                .ascii "SPECTRUM"<202>"ANALYSER"
                .byte 300
                .byte 300
                .byte 300
                .byte 300
                .byte 300
                .byte 300
                .byte 300
                .byte 300
                .byte 300
                .byte 301
                .asciz "@ 1993 CAROLINE SOFTWARE  V3.2"
                .even
; ───────────────────────────────────────────────────────────────────────────
MenuItemLen = M$Itm$ - M$MMNU   ; размер элемента меню в байтах
; главное меню рокмонитора
M$MMNU:         .word 46602     ; структура элемента меню: адрес экрана
                .byte 7         ; ширина пункта меню
                .byte 377       ; маска выделения пункта меню
                .word M$PTRN    ; исполняемая подпрограмма
                .word 0         ; возможные параметры подпрограммы
M$Itm$:         .word 46632
                .byte 1
                .byte 377
                .word M$PTUP        ; Меню PATTERN Up. Выбор номера редактируемого паттерна
                .word 0
                .word 46634
                .byte 1
                .byte 377
                .word M$PTDN        ; Меню PATTERN Down. Выбор номера редактируемого паттерна
                .word 0
                .word 44632
                .byte 1
                .byte 377
                .word M$LNUP        ; Меню LENGTH Up. Задать длину цепочки разделов
                .word 0
                .word 44634
                .byte 1
                .byte 377
                .word M$LNDN        ; Меню LENGTH Down. Задать длину цепочки разделов
                .word 0
                .word 43632
                .byte 1
                .byte 377
                .word M$HGUP        ; Меню HEIGHT Up, PATTERN Up
                                    ; Задать высоту тона заданного паттерна
                                    ; Задать номер паттерна в цепочке в заданной позиции
                .byte ACNHGT-T$MMNU ; смещение до ACNHGT от начала меню
                .byte 1             ; смещение в цепочке разделов: 1 - высота
                .word 43634
                .byte 1
                .byte 377
                .word M$HGDN        ; Меню HEIGHT Down, PATTERN Down
                                    ; Задать высоту тона заданного паттерна
                                    ; Задать номер паттерна в цепочке в заданной позиции
                .byte ACNHGT-T$MMNU
                .byte 1             ; смещение в цепочке разделов: 1 - высота
                .word 42632
                .byte 1
                .byte 377
                .word M$HGUP        ; Меню HEIGHT Up, PATTERN Up
                                    ; Задать высоту тона заданного паттерна
                                    ; Задать номер паттерна в цепочке в заданной позиции
                .byte ACNPTN-T$MMNU ; смещение до ACNPTN от начала меню
                .byte 0             ; смещение в цепочке разделов: 0 - номер раздела
                .word 42634
                .byte 1
                .byte 377
                .word M$HGDN        ; Меню HEIGHT Down, PATTERN Down
                                    ; Задать высоту тона заданного паттерна
                                    ; Задать номер паттерна в цепочке в заданной позиции
                .byte ACNPTN-T$MMNU
                .byte 0             ; смещение в цепочке разделов: 0 - номер раздела
                .word 41632
                .byte 1
                .byte 377
                .word M$PSUP        ; Меню POSITION Up. Выбрать позицию в цепочке паттернов
                .word 0
                .word 41634
                .byte 1
                .byte 377
                .word M$PSDN        ; Меню POSITION Down. Выбрать позицию в цепочке паттернов
                .word 0
                .word 41640
                .byte 6
                .byte 377
                .word M$SVLD        ; Меню SAVE, LOAD, COMPILE
                .word SAVTSN
                .word 42640
                .byte 6
                .byte 377
                .word M$SVLD        ; Меню SAVE, LOAD, COMPILE
                .word LOATSN
                .word 43640
                .byte 6
                .byte 377
                .word M$COPY        ; Меню COPY
                .word 0
                .word 44640
                .byte 6
                .byte 377
                .word M$OPTS        ; меню опции
                .word 0
                .word 46640
                .byte 6
                .byte 377
                .word M$CHTG        ; Меню выключения/включения каналов
                .byte ACASTA+4-T$MMNU-200   ; смещение до ACASTA+4 от начала меню и смещение, чтобы в байт влезало
                .byte 11            ; биты маски канала в регистре-смесителе
                .word 47640
                .byte 6
                .byte 377
                .word M$CHTG        ; Меню выключения/включения каналов
                .byte ACBSTA+4-T$MMNU-200   ; смещение до ACBSTA+4 от начала меню и смещение, чтобы в байт влезало
                .byte 22            ; биты маски канала в регистре-смесителе
                .word 50640
                .byte 6
                .byte 377
                .word M$CHTG        ; Меню выключения/включения каналов
                .byte ACCSTA+4-T$MMNU-200   ; смещение до ACCSTA+4 от начала меню и смещение, чтобы в байт влезало
                .byte 44            ; биты маски канала в регистре-смесителе
                .word 41656
                .byte 10
                .byte 377
                .word M$SAMP        ; Меню SAMPLE
                .word 0
                .word 42656
                .byte 10
                .byte 377
                .word M$SVLD        ; Меню SAVE, LOAD, COMPILE
                .word COMPIL
                .word 43656
                .byte 10
                .byte 377
                .word M$TRAN        ; Меню TRANSPOSITION
                .word 0
                .word 44656
                .byte 10
                .byte 377
                .word M$DELT        ; Меню DELETE
                .word 0
                .word 45656
                .byte 10
                .byte 377
                .word M$PLAY        ; Меню PLAY
                .word 0
                .word 46656
                .byte 10
                .byte 377
                .word M$TEMP        ; Меню TEMP
                .word 0
                .word 47760
                .byte 10
                .byte 377
                .word RETG$         ; заглушка
                .word 0
                .word 50656
                .byte 10
                .byte 377
                .word M$EXIT        ; Меню EXIT
                .word 0
                .word 0 ; конец меню
; ───────────────────────────────────────────────────────────────────────────
; меню функции копирования
T$COPY:         .ascii "FROM:"
                .byte 204
                .ascii "SET"
                .byte 316
                .ascii "VOICES"
                .byte 205
V$CCH1:         .ascii "  A  "
                .byte 316
                .ascii "PATTERN"
                .byte 204
                .byte 163
V$CPT1:         .ascii "000"
                .byte 164
                .byte 316
                .ascii "FIRST NOTE "
                .byte 163
V$CFN1:         .ascii "000"
                .byte 164
                .byte 316
                .ascii "LAST"<202>"NOTE "
                .byte 163
V$CLN1:         .ascii "000"
                .byte 164
                .byte 321
                .ascii "TO:"
                .byte 316
                .ascii "VOICES"
                .byte 205
V$CCH2:         .ascii "  A  "
                .byte 316
                .ascii "PATTERN"
                .byte 204
                .byte 163
V$CPT2:         .ascii "000"
                .byte 164
                .byte 316
                .ascii "FIRST NOTE "
                .byte 163
V$CFN2:         .ascii "000"
                .byte 164
                .byte 0
                .even
                .word 45662
                .byte 5
                .byte 125
                .word M$CSET
                .word 0
                .word 46662
                .byte 5
                .byte 125
                .word M$CCCH
                .byte V$CCH1-T$COPY
                .byte B.CCHS
                .word 47662
                .byte 1
                .byte 125
                .word M$TVUP
                .byte V$CPT1-T$COPY
                .byte B.CPTS
                .word 47672
                .byte 1
                .byte 125
                .word M$TVDN
                .byte V$CPT1-T$COPY
                .byte B.CPTS
                .word 50662
                .byte 1
                .byte 125
                .word M$TVUP
                .byte V$CFN1-T$COPY
                .byte B.CFNS
                .word 50672
                .byte 1
                .byte 125
                .word M$TVDN
                .byte V$CFN1-T$COPY
                .byte B.CFNS
                .word 51662
                .byte 1
                .byte 125
                .word M$TVUP
                .byte V$CLN1-T$COPY
                .byte B.CLNS
                .word 51672
                .byte 1
                .byte 125
                .word M$TVDN
                .byte V$CLN1-T$COPY
                .byte B.CLNS
                .word 53662
                .byte 5
                .byte 125
                .word M$CCCH
                .byte V$CCH2-T$COPY
                .byte B.CCHD
                .word 54662
                .byte 1
                .byte 125
                .word M$TVUP
                .byte V$CPT2-T$COPY
                .byte B.CPTD
                .word 54672
                .byte 1
                .byte 125
                .word M$TVDN
                .byte V$CPT2-T$COPY
                .byte B.CPTD
                .word 55662
                .byte 1
                .byte 125
                .word M$TVUP
                .byte V$CFN2-T$COPY
                .byte B.CFND
                .word 55672
                .byte 1
                .byte 125
                .word M$TVDN
                .byte V$CFN2-T$COPY
                .byte B.CFND
                .word 0
; ───────────────────────────────────────────────────────────────────────────
; меню функции транспонирования
T$TRAN:         .ascii "SET"
                .byte 316
                .ascii "VOICES"
                .byte 205
V$TRCH:         .ascii "  A  "
                .byte 316
                .ascii "PATTERN"
                .byte 204
                .byte 163
V$TRPT:         .ascii "000"
                .byte 164
                .byte 316
                .ascii "FIRST NOTE "
                .byte 163
V$TRFN:         .ascii "000"
                .byte 164
                .byte 316
                .ascii "LAST"<202>"NOTE "
                .byte 163
V$TRLN:         .ascii "000"
                .byte 164
                .byte 316
                .ascii "SEMITONES"
                .byte 202
                .byte 163
V$TRST:         .ascii "000"
                .byte 164
                .byte 0
                .even
                .word 45662
                .byte 5
                .byte 125
                .word M$TSET
                .word 0
                .word 46662
                .byte 5
                .byte 125
                .word M$CCCH
                .byte V$TRCH-T$TRAN, B.TRCH
                .word 47662
                .byte 1
                .byte 125
                .word M$TVUP
                .byte V$TRPT-T$TRAN, B.TRPT
                .word 47672
                .byte 1
                .byte 125
                .word M$TVDN
                .byte V$TRPT-T$TRAN, B.TRPT
                .word 50662
                .byte 1
                .byte 125
                .word M$TVUP
                .byte V$TRFN-T$TRAN, B.TRFN
                .word 50672
                .byte 1
                .byte 125
                .word M$TVDN
                .byte V$TRFN-T$TRAN, B.TRFN
                .word 51662
                .byte 1
                .byte 125
                .word M$TVUP
                .byte V$TRLN-T$TRAN, B.TRLN
                .word 51672
                .byte 1
                .byte 125
                .word M$TVDN
                .byte V$TRLN-T$TRAN, B.TRLN
                .word 52662
                .byte 1
                .byte 125
                .word M$TVUP
                .byte V$TRST-T$TRAN, B.TRST
                .word 52672
                .byte 1
                .byte 125
                .word M$TVDN
                .byte V$TRST-T$TRAN, B.TRST
                .word 0
; ───────────────────────────────────────────────────────────────────────────
; меню выбора сэмпла для редактирования
T$SELE:         .ascii "SELECT"
                .byte 313
                .ascii "NEW SAMPLE"
                .byte 1
                .byte 315
                .ascii "SET"
                .byte 202
V$SLNS:         .byte ']
                .byte 0
                .even
                .word 56632
                .byte 3
                .byte 125
                .word SELCSN        ; подтверждение выбранного номера сэмпла в меню SAMPLE
                .word 0
                .word 56644
                .byte 1
                .byte 125
                .word CHNGSN        ; выбор номера сэмпла в меню SAMPLE
                .word 0
                .word 0
; ───────────────────────────────────────────────────────────────────────────
; меню пункта PLAY
T$PLAY:         .ascii "PATTERN"
                .byte 327
                .asciz "SONG"
                .even
                .word 47652
                .byte 10
                .byte 125
                .word M1PLAY
                .word PLYPTR        ; Пункт меню - играть раздел
                .word 50652
                .byte 10
                .byte 125
                .word M1PLAY
                .word PLYSNG        ; Пункт меню - играть всю мелодию
                .word 0
; ───────────────────────────────────────────────────────────────────────────
; меню задания темпа
T$TEMP:         .ascii "SELECT"
                .byte 326
                .ascii "NEW TEMP"
                .byte 327
                .byte 327
                .ascii "SET"
                .byte 202
V$TEMP:         .byte 141
                .asciz <30><36>
                .even
                .word 53656
                .byte 3
                .byte 125
                .word D$CANC        ; Отмена действия
                .word 0
                .word 53670
                .byte 1
                .byte 125
                .word CHNGTM        ; задание нового темпа
                .word 0
                .word 0
; ───────────────────────────────────────────────────────────────────────────
; Меню удаления
T$DELT:         .byte 37
                .ascii "CANCEL"
                .byte 325
                .ascii "POSITION"
                .byte 326
                .ascii "PATTERN"
                .byte 327
                .asciz "SONG"
                .even
                .word 52652
                .byte 10
                .byte 252
                .word D$CANC        ; Отмена действия
                .word 0
                .word 53652
                .byte 10
                .byte 252
                .word D$POSI        ; Удаление позиции в списке разделов
                .word 0
                .word 54652
                .byte 10
                .byte 252
                .word D$PATR        ; Удаление раздела
                .word 0
                .word 55652
                .byte 10
                .byte 252
                .word D$SONG        ; Удаление всей мелодии
                .word 0
                .word 0
; ───────────────────────────────────────────────────────────────────────────
; меню подтверждения удаления
T$SURE:         .ascii "ARE YOU SURE ?"
                .byte 310
                .byte 311
                .ascii "YES"
                .byte 202
                .asciz "NO"
                .even
                .word 60334
                .byte 2
                .byte 377
                .word NOTCNF        ; Не подтверждение действия
                .word 0
                .word 60322
                .byte 3
                .byte 377
                .word YESCNF        ; Подтверждение действия
                .word 0
                .word 0
; ───────────────────────────────────────────────────────────────────────────
; меню редактора раздела reset channel
T$RESE:         .ascii "RESET"
                .byte 313
                .ascii "CHANNEL"
                .byte 37
                .byte '>
V$CRCH:         .byte 'C
                .byte '<
                .byte 314
                .ascii "YES"
                .byte 202
                .asciz "NO"
                .even
                .word 65342
                .byte 2
                .byte 125
                .word NORSCH    ; отказ делать Reset Channel
                                ; отказ делать очистку до конца канала
                .word 0
                .word 65330
                .byte 3
                .byte 125
                .word YERSCH    ; подтверждение Reset Channel
                .word 0
                .word 0
; ───────────────────────────────────────────────────────────────────────────
; меню редактора раздела стереть до конца канала
T$ERTN:         .ascii "ERASE TO END"
                .byte 313
                .ascii "CHANNEL>"
V$ERCH:         .ascii "A<"
                .byte 314
                .asciz "YES"<202>"NO"
                .even
                .word 65342
                .byte 2
                .byte 125
                .word NORSCH    ; отказ делать Reset Channel
                                ; отказ делать очистку до конца канала
                .word 0
                .word 65330
                .byte 3
                .byte 125
                .word YEERTE    ; Подтверждение очистки до конца канала
                .word 0
                .word 0
; ───────────────────────────────────────────────────────────────────────────

B37442:         .byte 165
                .byte 166
                .byte 166
                .byte 166
                .byte 166
                .byte 166
                .byte 36
                .ascii "CHAN:A"
                .byte 35
                .byte 166
                .byte 166
                .byte 166
                .byte 36
                .ascii "CHAN:B"
                .byte 35
                .byte 166
                .byte 166
                .byte 166
                .byte 36
                .ascii "CHAN:C"
                .byte 35
                .byte 166
                .byte 167
                .byte 0
                .even
                .word 0 ; конец строки, нет меню.
; строки для выбора каналов копирования и транспонирования
CH.A:           .asciz "  A  "
CH.B:           .asciz "  B  "
CH.C:           .asciz "  C  "
CHABC:          .asciz "A,B,C"
                .even
; ───────────────────────────────────────────────────────────────────────────

; строка какая-то
B37314:         .byte 174
                .byte 210
                .byte 174
                .byte 210
                .byte 174
                .byte 1
                .byte 170
                .byte 210
                .byte 170
                .byte 210
                .byte 170
                .byte 1
                .byte 170
                .byte 210
                .byte 170
                .byte 210
                .byte 170
                .byte 1
                .byte 170
                .byte 210
                .byte 170
                .byte 210
                .byte 170
                .byte 1
                .byte 170
                .byte 210
                .byte 170
                .byte 210
                .byte 170
                .byte 1
                .byte 170
                .byte 210
                .byte 170
                .byte 210
                .byte 170
                .byte 1
                .byte 170
                .byte 210
                .byte 170
                .byte 210
                .byte 170
                .byte 1
                .byte 170
                .byte 210
                .byte 170
                .byte 210
                .byte 170
                .byte 1
                .byte 176
                .byte 210
                .byte 176
                .byte 210
                .byte 176
                .byte 0
                .even
                .word 0 ; конец строки, нет меню.
; ещё какая-то строка
B37514:         .byte 173
                .byte 236
                .byte 175
                .byte 0
                .even
                .word 0 ; конец строки, нет меню.


; ███████████████████████████████████████████████████████████████████████████
; ████████████████████ РЕДАКТОР СЭМПЛОВ █████████████████████████████████████
; ███████████████████████████████████████████████████████████████████████████
SMPLED:         mov     #STACKH, SP
                iot     ; глушим сопр
                call    DRWWIN  ; Нарисовать окно с рамкой без тени
                                ; Входные параметры:
                .word   40000+100000    ; Слово - адрес экрана, бит 15 - флаг, не сохранять содержимое под окном
                .byte   40      ; Байт - высота в символах
                .byte   40      ; Байт - ширина в символах
                .byte   125     ; Байт - маска цвета фона
                .byte   377     ; Байт - инверсная маска цвета символов
                call    DRWWNH  ; Нарисовать окно с рамкой с тенью
                                ; Входные параметры:
                .word   40702+100000    ; Слово - адрес экрана, бит 15 - флаг, не сохранять содержимое под окном
                .byte   16      ; Байт - высота в символах
                .byte   22      ; Байт - ширина в символах
                .byte   0       ; Байт - маска цвета фона
                .byte   125     ; Байт - инверсная маска цвета символов
                mov     #41016, R1  ; Рисуем окошки редактора сэмплов
                mov     #T$TVOL, R0
                call    OUTSTR  ; Вывод строки.
                                ; Вход: R0 - адрес строки, R1 - адрес экрана
                call    S1340   ; вывод огибающих
                call    S1540   ; вывод маски
                mov     #W1350, F2114
                mov     #46, W2162
                call    S2736   ; вывод длительностей
                call    DRWWNH  ; Нарисовать окно с рамкой с тенью
                                ; Входные параметры:
                .word   60002+100000    ; Слово - адрес экрана, бит 15 - флаг, не сохранять содержимое под окном
                .byte   16      ; Байт - высота в символах
                .byte   22      ; Байт - ширина в символах
                .byte   0       ; Байт - маска цвета фона
                .byte   125     ; Байт - инверсная маска цвета символов
                mov     #60016, R1
                mov     #T$TNSE, R0
                call    OUTSTR  ; Вывод строки.
                                ; Вход: R0 - адрес строки, R1 - адрес экрана
                call    S1436   ; вывод огибающих
                call    S1652   ; вывод маски
                mov     #W1446, F2114
                mov     #63, W2162
                call    S2654   ; вывод длительностей
                call    DRWWNH  ; Нарисовать окно с рамкой с тенью
                                ; Входные параметры:
                .word   40750+100000    ; Слово - адрес экрана, бит 15 - флаг, не сохранять содержимое под окном
                .byte   20      ; Байт - высота в символах
                .byte   12      ; Байт - ширина в символах
                .byte   0       ; Байт - маска цвета фона
                .byte   0       ; Байт - инверсная маска цвета символов
                mov     #41056, R1
                mov     #T$TTON, R0
                call    OUTSTR  ; Вывод строки.
                                ; Вход: R0 - адрес строки, R1 - адрес экрана
                call    S14376
                call    S3444
                call    S3510
                mov     #14, R4
1$:             call    S3560
                dec     R4
                bpl     1$

L4706:          call    DRWWNH  ; Нарисовать окно с рамкой с тенью
                                ; Входные параметры:
                .word   42002   ; Слово - адрес экрана, бит 15 - флаг, не сохранять содержимое под окном
                .byte   4       ; Байт - высота в символах
                .byte   36      ; Байт - ширина в символах
                .byte   252     ; Байт - маска цвета фона
                .byte   377     ; Байт - инверсная маска цвета символов
                mov     #43404, R1  ; выводим меню и обрабатываем его
                mov     #T$SEMN, R0
                jmp     OUTSTR      ; Вывод строки.
                                    ; Вход: R0 - адрес строки, R1 - адрес экрана

; ───────────────────────────────────────────────────────────────────────────
; Изменение выбранной огибающей сэмпла
S$CHNG:         mov     (R0)+, R5
                call    RESWND  ; Восстановление области экрана из буфера
                call    RESWND  ; Восстановление области экрана из буфера
                call    (R5)
L011$:          mov     #STACKH, SP
                br      L4706
; ───────────────────────────────────────────────────────────────────────────
; очистка выбранной огибающей сэмпла
S$CLRS:         mov     CURSAM, R5
                mov     (R0)+, R0   ; флаг, что очищаем: 0 - громкость
                                    ;                   1 - тон
                                    ;                   -1 - шум
                bne     1$
                mov     #7417, (R5) ; байты для зацикливания громкости
                clr     4(R5)       ; маска
                add     #46, R5
                br      5$
; ───────────────────────────────────────────────────────────────────────────

1$:             bpl     4$
                mov     #7417, 10(R5)   ; байты для зацикливания шума
                clr     6(R5)   ; маска
                clr     12(R5)  ; старшие биты длительности
                add     #63, R5
5$:             mov     #15, R0
2$:             clrb    (R5)+
                sob     R0, 2$
                br      3$
; ───────────────────────────────────────────────────────────────────────────

4$:             mov     #7417, 2(R5)    ; байты для зацикливания тона
                mov     #15, R0
                add     #14, R5
6$:             clr     (R5)+
                sob     R0, 6$
3$:             call    RESWND  ; Восстановление области экрана из буфера
                call    RESWND  ; Восстановление области экрана из буфера
                br      L011$

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

S1340:          mov     #52500, W1036
                mov     W1350, R1
                call    S1210
                tst     2(R5)
                bmi     1$
                mov     #S1670, F1422
                br      2$
; ───────────────────────────────────────────────────────────────────────────

1$:             mov     #S1254, F1422
2$:             mov     CURSAM, R5
                add     #46, R5
                clr     R3
3$:             movb    (R5)+, R0
                asl     R0
                call    @F1422
                inc     R4
                cmp     R4, #13.
                blo     3$
                return
; End of function S1340

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

S1436:          mov     #71500, W1036
                mov     W1446, R1
                mov     CURSAM, R5
                call    S1242
                tst     -4(R5)
                bmi     1$
                mov     #S1670, F1524
                br      2$
; ───────────────────────────────────────────────────────────────────────────

1$:             mov     #S1254, F1524
2$:             mov     CURSAM, R5
                add     #63, R5
                clr     R3
3$:             movb    (R5)+, R0
                call    @F1524
                inc     R4
                cmp     R4, #13.
                blo     3$
                return
; End of function S1436

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

S1242:          add     #10, R5
                br      01214$

S1210:          mov     CURSAM, R5
01214$:         clr     R4

S1222:          movb    (R5)+, @#SAMBUF
                movb    (R5)+, @#SAMBUF+1
                bic     #170360, @#SAMBUF
                return

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

S1670:          bic     #177740, R0
                cmpb    R4, @#SAMBUF
                blo     5$
                mov     #W35000, R2
                cmpb    R4, @#SAMBUF+1
                blos    1$
5$:             mov     #W35040, R2
1$:             mov     #40, R3
                mov     R1, -(SP)
                tst     R0
                beq     2$
3$:             mov     (R2), (R1)
                sub     #200, R1
                dec     R3
                sob     R0, 3$
                ble     4$
2$:             clr     (R1)
                sub     #200, R1
                sob     R3, 2$
4$:             mov     (SP)+, R1
                tst     (R1)+
                return

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

S1254:          bic     #177740, R0
                mov     R0, -(SP)
                sub     R3, R0
                bpl     1$
                add     R0, R3
                negb    R0

1$:             swab    R3
                asr     R3
                sub     R3, R1
                cmpb    R4, @#SAMBUF
                blo     2$
                mov     #W35000, R2
                cmpb    R4, @#SAMBUF+1
                blos    3$
2$:             mov     #W35040, R2
3$:             call    S1004
                add     R3, R1
                tst     (R1)+
                mov     (SP)+, R3
                return
; End of function S1254

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

S1004:          jsr     R5, @#PUSHA
                bmi     1$  ; проверка R0 на знак
                add     #20, R2
1$:             mov     R2, R5
                mov     R1, -(SP)
                bic     #177700, R1
                add     W1036, R1
2$:             sub     #200, R1
                mov     (R2), (R1)
                cmp     R1, (SP)
                bhi     2$
                mov     (SP)+, R1
                mov     #20, R4
                asl     R0
                asl     R0
                asl     R0
                asl     R0
                bic     #177000, R0
                add     #B34020, R0

4$:             clr     R2
                bisb    -(R0), R2
                mov     R2, R3
                bic     #177760, R2
                bic     R2, R3
                asr     R3
                asr     R3
                asr     R3
                asr     R3
                add     R5, R2
                add     R5, R3
                mov     (R3), (R1)
                beq     3$
                mov     (R2), 177600(R1)
                beq     31$
                sub     #400, R1
                sob     R4, 4$
31$:            sub     #200, R1

3$:             mov     W1036, R2
                sub     #10000, R2
5$:             clr     (R1)
                sub     #200, R1
                cmp     R1, R2
                bhi     5$
                return
; End of function S1004


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

S1652:          mov     CURSAM, R5
                mov     6(R5), R5
                mov     W1446, R1
                br      1554$

S1540:          mov     CURSAM, R5
                mov     4(R5), R5
                mov     W1350, R1

1554$:          add     #376, R1
                mov     #16, R4
                mov     #40000, R2
                mov     R2, R0
                br      1$
; ───────────────────────────────────────────────────────────────────────────

3$:             asr     R5
                bcs     2$
                mov     #40000, R0
                br      1$
; ───────────────────────────────────────────────────────────────────────────

2$:             mov     #77777, R0
1$:             mov     R2, (R1)
                mov     R0, 100(R1)
                mov     R0, 200(R1)
                mov     R0, 300(R1)
                mov     R0, 400(R1)
                mov     R2, 500(R1)
                mov     #52525, R2
                tst     (R1)+
                sob     R4, 3$
                return
; End of function S1540

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

S2736:          call    S2622
1$:             movb    (R5)+, R2
                bic     #177417, R2
                call    PRNCH
                sob     R3, 1$
                return
; End of function S2736

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

S2654:          call    S2622
2$:             movb    (R5)+, R2
                bic     #177437, R2
                asr     R4
                bcc     1$
                add     #20, R2
1$:             call    PRNCH
                sob     R3, 2$
                return
; End of function S2654

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

S2622:          mov     @F2114, R1
                mov     CURSAM, R5
                add     #1300, R1
                mov     12(R5), R4
                add     W2162, R5
                mov     #15, R3
                return
; End of function S2622

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


S3510:          mov     CURSAM, R5
                add     #14, R5
                mov     #15, R4
                mov     W3452, R1
                add     #16, R1
1$:             mov     (R5)+, R2
                swab    R2
                bic     #177417, R2
                call    PRNCH
                add     #776, R1
                sob     R4, 1$
                return
; End of function S3510

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

S3444:          mov     CURSAM, R5
                mov     W3452, R1
                mov     #36, R2
                tst     2(R5)
                bmi     1$
                inc     R2
1$:             mov     #15, R3
2$:             call    OUTCHR  ; Вход: R2 - код символа, R1 - адрес вывода
                add     #776, R1
                sob     R3, 2$
                return

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

PRNCH:          add     #RMPLFN, R2 ; фонт для быстрой генерации нотных символов
                mov     R1, -(SP)
                mov     #10, R0
1$:             mov     (R2)+, (R1)
                add     #100, R1
                sob     R0, 1$
                mov     (SP)+, R1
                tst     (R1)+
                return
; End of function PRNCH


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

S14376:         call    DRWWNH  ; Нарисовать окно с рамкой с тенью
                                ; Входные параметры:
                .word   61450+100000    ; Слово - адрес экрана, бит 15 - флаг, не сохранять содержимое под окном
                .byte   14      ; Байт - высота в символах
                .byte   12      ; Байт - ширина в символах
                .byte   377     ; Байт - маска цвета фона
                .byte   252     ; Байт - инверсная маска цвета символов
                mov     #T$CRLN, R0
                mov     #71552, R1
                call    OUTSTR  ; Вывод строки.
                                ; Вход: R0 - адрес строки, R1 - адрес экрана
                call    DRWWIN  ; Нарисовать окно с рамкой без тени
                                ; Входные параметры:
                .word   62452+100000    ; Слово - адрес экрана, бит 15 - флаг, не сохранять содержимое под окном
                .byte   6       ; Байт - высота в символах
                .byte   10      ; Байт - ширина в символах
                .byte   0       ; Байт - маска цвета фона
                .byte   252     ; Байт - инверсная маска цвета символов
S14450:         mov     #63454, R1
                mov     #B37712, R0
                call    OUTSTR  ; Вывод строки.
                                ; Вход: R0 - адрес строки, R1 - адрес экрана

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

S5346:          clr     COLMSK
                clr     BGCOLR
                return
; End of function S5346
; End of function S14450

; ───────────────────────────────────────────────────────────────────────────
; Меню выбора пункта редактора сэмплов
; Вход: R0 - адрес адреса блока параметров
S$MENU:         mov     (R0), R0
                mov     (R0)+, R2   ; адрес экрана
                mov     R2, W5010   ; его на место
                add     #1402, R2   ; адрес вывода строки
                mov     R2, -(SP)   ; запомним
                mov     (R0)+, W37252   ; параметр - подпрограмма
                mov     (R0)+, W37262   ; параметр - аргумент
                sub     #100, R2    ; ещё манипуляции с адресом экрана
                mov     R2, W37244  ; это адреса менюшки  change/clear
                add     #2000, R2
                mov     R2, W37254
                call    DRWWNH  ; Нарисовать окно с рамкой с тенью
                                ; Входные параметры:
W5010:          .word   44404   ; Слово - адрес экрана, бит 15 - флаг, не сохранять содержимое под окном
                .byte   6       ; Байт - высота в символах
                .byte   10      ; Байт - ширина в символах
                .byte   377     ; Байт - маска цвета фона
                .byte   252     ; Байт - инверсная маска цвета символов
                mov     (SP)+, R1
                mov     #T$SESM, R0
                jmp     OUTSTR  ; Вывод строки.
                                ; Вход: R0 - адрес строки, R1 - адрес экрана
; выход из редактора сэмплов.
M$QUIT:         call    RESWND  ; нужно восстановить окошко из буфера, чтобы он не переполнялся
                jmp     TRP4    ; и заново перезапускаем рок монитор

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

; подпрограмма редактора огибающей громкости
S1VOLP:         mov     #F2760, R0
                br      0S1$
; ───────────────────────────────────────────────────────────────────────────
; подпрограмма редактора огибающей шума
S1NSEP:         mov     #F2776, R0
0S1$:           mov     (R0)+, F2020
                mov     (R0)+, F2024
                mov     (R0)+, F2030
                mov     (R0)+, F2114
                mov     (R0)+, W2170
                mov     (R0)+, W2246
                mov     (R0)+, W2162

                call    @F2020
                call    @F2024
                call    @F2030
                clr     R4
                br      3$
; ───────────────────────────────────────────────────────────────────────────
; Обработка клавиатуры в редакторе огибающих
4$:             call    S14470
                cmpb    R0, #10     ; Стрелка влево
                bne     1$
                tst     R4
                beq     4$
                dec     R4

3$:             mov     #2, R0
                br      2$
; ───────────────────────────────────────────────────────────────────────────

1$:             cmpb    R0, #31     ; Стрелка вправо
                bne     5$
                cmp     R4, #14
                bhis    4$
                inc     R4
                mov     #-2, R0
2$:             mov     R4, R1
                asl     R1
                add     @F2114, R1
                add     W2120, R1
                add     R1, R0
                mov     W2126, R2
                mov     #W35100, R3
6$:             mov     (R3)+, (R1)
                clr     (R0)
                add     #100, R0
                add     #100, R1
                sob     R2, 6$
                br      4$
; ───────────────────────────────────────────────────────────────────────────

5$:             mov     CURSAM, R1
                add     W2162, R1
                add     R4, R1
                mov     W2170, R2
                movb    (R1), R3
                cmpb    R0, #32     ; Стрелка вверх
                bne     7$
                inc     R3
                br      8$
; ───────────────────────────────────────────────────────────────────────────

7$:             cmpb    R0, #33     ; Стрелка вниз
                bne     9$
                dec     R3
8$:             bic     R2, R3
                com     R2
                bicb    R2, (R1)
                bisb    R3, (R1)
14$:            mov     R4, -(SP)
                call    @F2020
22$:            mov     (SP)+, R4
28$:            br      4$
; ───────────────────────────────────────────────────────────────────────────

9$:             mov     CURSAM, R3
                add     W2246, R3
                cmpb    R0, #40     ; Пробел
                bne     10$
                mov     #1, R2
                mov     R4, R5
                beq     11$
12$:            asl     R2
                sob     R5, 12$
11$:            xor     R2, (R3)
                mov     R4, -(SP)
                call    @F2024
                mov     (SP)+, R4
                br      4$
; ───────────────────────────────────────────────────────────────────────────

10$:            cmpb    R0, #'.     ; Точка
                bne     13$
                add     #100000, (R3)
                br      14$
; ───────────────────────────────────────────────────────────────────────────

13$:            cmpb    R0, #'0     ; Цифры 0-9
                blo     15$
                cmpb    R0, #'9
                bhi     15$
                sub     #'0, R0
                br      16$
; ───────────────────────────────────────────────────────────────────────────

15$:            cmpb    R0, #'A     ; Буквы A-F
                blo     17$
                cmpb    R0, #'F
                bhi     17$
                sub     #67, R0

16$:            bic     #177760, R0
                mov     R0, R5
                asl     R0
                asl     R0
                asl     R0
                asl     R0
                bicb    R2, (R1)
                com     R2
                bicb    R2, R0
                bisb    R0, (R1)
                mov     R4, -(SP)
                cmp     R2, #37
                bne     18$
                mov     CURSAM, R2
                mov     #1, R1
                tst     R4
                beq     19$
20$:            asl     R1
                sob     R4, 20$
19$:            asr     R5
                bcs     21$
                bic     R1, 12(R2)
                br      18$
; ───────────────────────────────────────────────────────────────────────────

21$:            bis     R1, 12(R2)
18$:            call    @F2030
                br      22$
; ───────────────────────────────────────────────────────────────────────────

17$:            cmpb    R0, #3      ; КТ
                bne     23$
                asl     R4
                add     @F2114, R4
                add     W2120, R4
                mov     W2126, R2
24$:            clr     (R4)
                add     #100, R4
                sob     R2, 24$
                return
; ───────────────────────────────────────────────────────────────────────────

23$:            mov     CURSAM, R5
                cmp     R2, #177760
                beq     25$
                add     #10, R5
25$:            cmpb    R0, #13     ; -|->
                bne     26$
                mov     #7417, (R5)
                br      14$
; ───────────────────────────────────────────────────────────────────────────

26$:            cmpb    R0, #26     ; Сдвижка в строке
                bne     27$
                movb    R4, (R5)
                br      14$
; ───────────────────────────────────────────────────────────────────────────

27$:            cmpb    R0, #27     ; Раздвижка в строке
                bne     28$
                movb    R4, 1(R5)
                br      14$

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

S14470:         mov     W2162, R1
                add     R4, R1
                add     CURSAM, R1
                movb    (R1), R3
                bic     W2170, R3
                mov     R4, -(SP)
                mov     #D10BUF, R4
                call    S3164
                bit     (R4)+, (R4)+
                add     #"00, (R4)
                mov     (R4), B37726
                call    S14450
                mov     (SP)+, R4
; End of function S14470
; ███████████████ S U B R O U T I N E ███████████████████████████████████████

S7716:          call    S5702
                cmpb    R0, #'!     ; Выбор октавы
                blo     005LR$
                cmpb    R0, #'(
                bhi     005LR$
                add     #20, R0
                movb    R0, V$SMOC
                sub     #61, R0
                asl     R0
                asl     R0
                mov     R0, R1
                asl     R0
                add     R1, R0
                mov     R0, SAMOCT
                mov     R4, -(SP)
                call    DRWWNH  ; Нарисовать окно с рамкой с тенью
                                ; Входные параметры:
                .word   55326   ; Слово - адрес экрана, бит 15 - флаг, не сохранять содержимое под окном
                .byte   6       ; Байт - высота в символах
                .byte   12      ; Байт - ширина в символах
                .byte   377     ; Байт - маска цвета фона
                .byte   252     ; Байт - инверсная маска цвета символов
; ───────────────────────────────────────────────────────────────────────────
                mov     #56730, R1
                mov     #T$SMPL, R0
                call    OUTSTR  ; Вывод строки.
                                ; Вход: R0 - адрес строки, R1 - адрес экрана
1$:             bit     #100, @#177716
                beq     1$
                call    RESWND  ; Восстановление области экрана из буфера
                mov     (SP)+, R4
                call    S5346
                br      S7716
; ───────────────────────────────────────────────────────────────────────────
005LR$:         return
; End of function S7716

; ───────────────────────────────────────────────────────────────────────────
; подпрограмма редактора огибающей тона
S1TONP:         call    S5346
                call    S3444
                call    S3510
                mov     #14, R4
1$:             call    S3560
                dec     R4
                bpl     1$
                clr     R4
5$:             mov     #1000, R0
7$:             mov     W3452, R1
                add     #14, R1
                mov     R4, R5
                swab    R5
                asl     R5
                add     R5, R1
                add     R1, R0
                mov     #W30700, R2
                mov     #10, R5
2$:             mov     (R2)+, (R1)
                add     #100, R1
                clr     (R0)
                add     #100, R0
                sob     R5, 2$
4$:             call    S7716
                cmpb    R0, #32     ; Стрелка вверх
                bne     3$
                tst     R4
                beq     4$
                dec     R4
                br      5$
; ───────────────────────────────────────────────────────────────────────────

3$:             cmpb    R0, #33     ; Стрелка вниз
                bne     6$
                cmp     R4, #14
                bhis    4$
                inc     R4
                mov     #177000, R0
                br      7$
; ───────────────────────────────────────────────────────────────────────────

6$:             mov     R4, R5
                asl     R5
                add     CURSAM, R5
                add     #14, R5
                mov     (R5), R1
                mov     R1, R2
                bic     #174000, R2
                cmpb    R0, #10     ; Стрелка влево
                bne     8$
                dec     R2
                cmp     R2, #1048.
                bne     9$
                mov     #999., R2
9$:             bic     #3777, (R5)
                bic     #174000, R2
                bis     R2, (R5)
15$:            call    S3560
                br      4$
; ───────────────────────────────────────────────────────────────────────────

8$:             cmpb    R0, #31     ; Стрелка вправо
                bne     10$
                inc     R2
                cmp     R2, #1000.
                bne     9$
                mov     #1049., R2
                br      9$
; ───────────────────────────────────────────────────────────────────────────

10$:            cmp     R0, #'0     ; Цифры 0-9
                blo     11$
                cmp     R0, #'9
                bhi     12$
                sub     #'0, R0
                br      13$
; ───────────────────────────────────────────────────────────────────────────

12$:            cmp     R0, #'A     ; Буквы A-F
                blo     11$
                cmp     R0, #'F
                bhi     11$
                sub     #67, R0
13$:            asl     R0
                asl     R0
                asl     R0
                asl     R0
                swab    R0
                bic     #170000, (R5)
                bis     R0, (R5)
                mov     R4, -(SP)
                mov     #0, COLMSK
                call    S3510
                mov     (SP)+, R4
                br      4$
; ───────────────────────────────────────────────────────────────────────────

11$:            cmpb    R0, #40     ; Пробел
                bne     14$
                mov     #4000, R0
                xor     R0, (R5)
                br      15$
; ───────────────────────────────────────────────────────────────────────────

14$:            mov     CURSAM, R5
                tst     (R5)+
                cmpb    R0, #'.     ; Точка
                bne     16$
                add     #100000, (R5)
                mov     #0, COLMSK
                call    S3444
                br      4$
; ───────────────────────────────────────────────────────────────────────────

16$:            cmpb    R0, #26     ; Сдвижка в строке
                bne     17$
                movb    R4, (R5)
20$:            mov     R4, -(SP)
                clr     R4
18$:            call    S3560
                inc     R4
                cmp     R4, #15
                blo     18$
                mov     (SP)+, R4
22$:            br      4$
; ───────────────────────────────────────────────────────────────────────────

17$:            cmpb    R0, #27     ; Раздвижка в строке
                bne     19$
                bicb    #177, 1(R5)
                bisb    R4, 1(R5)
                br      20$

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

19$:            cmpb    R0, #13     ; -|->
                bne     21$
                bis     #7417, (R5)
                br      20$
; ───────────────────────────────────────────────────────────────────────────

21$:            cmpb    R0, #3      ; КТ
                bne     22$
                mov     W3452, R1
                add     #14, R1
                asl     R4
                swab    R4
                add     R4, R1
                mov     #10, R2
23$:            clr     (R1)
                add     #100, R1
                sob     R2, 23$
                return

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

S3560:          mov     CURSAM, R5
                tst     (R5)+
                call    S1222
                mov     W3452, R1
                tst     (R1)+
                mov     R4, R0
                asl     R0
                add     R0, R5
                swab    R0
                add     R0, R1
                cmpb    R4, @#SAMBUF
                blo     11$
                mov     #0, COLMSK
                cmpb    R4, @#SAMBUF+1
                blos    12$
11$:            mov     #52525, COLMSK
12$:            mov     10(R5), R3

                jsr     R5, @#PUSHA
                mov     R3, -(SP)
                bit     #2000, R3
                beq     1$
                neg     R3
                mov     #'-, R2
                br      2$
; ───────────────────────────────────────────────────────────────────────────

1$:             mov     #'+, R2
2$:             call    OUTCHR  ; Вход: R2 - код символа, R1 - адрес вывода
                bic     #176000, R3
                mov     #D10BUF, R4
                call    S3164
                mov     #3, R3
                add     R3, R4

3$:             movb    (R4)+, R2
                add     #'0, R2
                call    OUTCHR  ; Вход: R2 - код символа, R1 - адрес вывода
                sob     R3, 3$
                mov     (SP)+, R3
                mov     #34, R2
                bit     #4000, R3
                beq     4$
                inc     R2
4$:             jmp     OUTCHR  ; Вход: R2 - код символа, R1 - адрес вывода

; End of function S3560

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


S5702:          call    GETCHR  ; получение кода нажатой клавиши с автоповтором.
                                ; синхронизация с таймером 50Гц
                                ; Выход: R0 - код
4$:             tstb    @#SAMCBP+L.PAUS
                bne     1$
                tst     MUTEAY
                beq     2$
1$:             mov     #NOTKEY, R3 ; Нотные клавиши
                mov     #12., R2
5$:             cmpb    R0, (R3)+
                bne     3$
                dec     R2
                add     SAMOCT, R2
                call    L6100
                call    INPCHR  ; получение кода нажатой клавиши с ожиданием.
                                ; Выход: R0 - код
                br      4$
; ───────────────────────────────────────────────────────────────────────────

3$:             sob     R2, 5$
2$:             return
; End of function S5702

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

; вход: R2 - номер ноты
L6100:          mov     PC, MUTEAY
                wait
                mov     #SAMCBP, R0
                mov     #/CHPLN+/AYLEN, R1  ; чистим оба буфера SAMCBP и SAMAYB, без этого работает некорректно
1$:             clr     (R0)+
                sob     R1, 1$
                mov     CURSAM, R0
                mov     #SAMCBP+L.ASMP, R1
                mov     R0, (R1)+
                mov     (R0), (R1)+
                mov     10(R0), (R1)+
                mov     2(R0), (R1)
                bic     #100000, (R1)
                movb    #355, @#SAMAYB+Y.MIXR
                mov     #SAMCBP, R5
                movb    R2, L.NOTN(R5)
                mov     #177400, (R5)+
                mov     #177777, (R5)
                clr     MUTEAY
                return

; ███████████████ S U B R O U T I N E ███████████████████████████████████████
; проигрыватель сэмплов
; блок параметров проигрывателя начинается с адреса SAMCBP
; блок регистров AY начинается с адреса SAMAYB
PLYSMP:         jsr     R5, @#PUSHA
                mov     #SAMCBP, R5
                decb    L.TSLV(R5)
                bpl     10$
                cmpb    L.TPSV(R5), L.ECYV(R5)
                beq     1$
                incb    L.TPSV(R5)
                movb    L.TPSV(R5), R0
                cmpb    R0, #13.
                blo     2$
                decb    L.TPSV(R5)
                clr     L.CVLV(R5)
                mov     PC, MUTEAY
                br      10$
; ───────────────────────────────────────────────────────────────────────────

1$:             movb    L.BCYV(R5), R0
                movb    R0, L.TPSV(R5)
2$:             mov     #1, R4
                mov     R0, R3
                beq     3$
4$:             asl     R4
                sob     R3, 4$
3$:             mov     L.ASMP(R5), R3
                add     R3, R0
                bicb    #2, @#SAMAYB+Y.MIXR
                bit     R4, 4(R3)
                bne     5$
                bisb    #2, @#SAMAYB+Y.MIXR
5$:             clr     R1
                bisb    46(R0), R1
                mov     R1, R2
                bic     #360, R1
                bic     R1, R2
                asr     R2
                asr     R2
                beq     6$
                sub     #3, R2
6$:             movb    R2, L.TSLV(R5)
                clrb    L.FLCV(R5)
                tst     4(R3)
                bmi     7$
                movb    R1, L.CVLV+1(R5)
                comb    L.FLCV(R5)
                br      10$
; ───────────────────────────────────────────────────────────────────────────

7$:             clr     R4
                movb    L.CVLV+1(R5), R0
                movb    R1, L.RVLV+1(R5)
                sub     R0, R1
                bpl     8$
                neg     R1
                inc     R4
8$:             swab    R1
                call    DIVIDE
                tst     R4
                beq     9$
                neg     R1
9$:             mov     R1, L.DVLV(R5)
                ; с громкостью разобрались, теперь с шумом
10$:            decb    L.TSLN(R5)
                bpl     19$
                cmpb    L.TPSN(R5), L.ECYN(R5)
                beq     11$
                incb    L.TPSN(R5)
                movb    L.TPSN(R5), R0
                cmpb    R0, #13.
                blo     12$
                decb    L.TPSN(R5)
                br      19$
; ───────────────────────────────────────────────────────────────────────────

11$:            movb    L.BCYN(R5), R0
                movb    R0, L.TPSN(R5)
12$:            mov     #1, R4
                mov     R0, R3
                beq     13$
14$:            asl     R4
                sob     R3, 14$
13$:            mov     L.ASMP(R5), R3
                add     R3, R0
                bicb    #20, @#SAMAYB+Y.MIXR
                bit     R4, 6(R3)
                bne     15$
                bisb    #20, @#SAMAYB+Y.MIXR
15$:            clr     R1
                bisb    63(R0), R1
                mov     R1, R2
                bic     #340, R1
                bic     R1, R2
                bit     R4, 12(R3)
                beq     16$
                add     #20, R2
16$:            asr     R2
                asr     R2
                beq     17$
                sub     #3, R2
17$:            movb    R2, L.TSLN(R5)
                clrb    L.FLCN(R5)
                tst     6(R3)
                bmi     18$
                movb    R1, L.CVLN+1(R5)
                comb    L.FLCN(R5)
                br      19$
; ───────────────────────────────────────────────────────────────────────────

18$:            clr     R4
                movb    L.CVLN+1(R5), R0
                movb    R1, L.RVLN+1(R5)
                sub     R0, R1
                bpl     20$
                inc     R4
                neg     R1
20$:            swab    R1
                call    DIVIDE
                tst     R4
                beq     21$
                neg     R1
21$:            mov     R1, L.DVLN(R5)
                ; с шумом разобрались, теперь с тоном
19$:            decb    L.TSLT(R5)
                bpl     28$
                cmpb    L.TPST(R5), L.ECYT(R5)
                beq     22$
                incb    L.TPST(R5)
                movb    L.TPST(R5), R0
                cmpb    R0, #13.
                blo     23$
                decb    L.TPST(R5)
                br      28$
; ───────────────────────────────────────────────────────────────────────────

22$:            movb    L.BCYT(R5), R0
                movb    R0, L.TPST(R5)
23$:            mov     L.ASMP(R5), R3
                asl     R0
                add     R3, R0
                mov     14(R0), R0
                mov     R0, R1
                bit     #2000, R0
                beq     24$
                neg     R1
24$:            bic     #176000, R1
                movb    L.NOTN(R5), R4
                bit     #4000, R0
                beq     25$
                bit     #2000, R0
                bne     26$
                add     R1, R4
                cmp     R4, #140
                blo     27$
                mov     #137, R4
                br      27$
; ───────────────────────────────────────────────────────────────────────────

26$:            sub     R1, R4
                bpl     27$
                clr     R4
27$:            asl     R4
                mov     NOTCLK(R4), R4
                br      29$
; ───────────────────────────────────────────────────────────────────────────

25$:            asl     R4
                mov     NOTCLK(R4), R4
                bit     #2000, R0
                beq     30$
                add     R1, R4
                br      29$
; ───────────────────────────────────────────────────────────────────────────

30$:            sub     R1, R4
                bpl     29$
                clr     R4
29$:            mov     R4, R1
                clrb    L.FLCT(R5)
                mov     R0, R2
                swab    R2
                bic     #177417, R2
                asr     R2
                asr     R2
                beq     31$
                sub     #3, R2
31$:            movb    R2, L.TSLT(R5)
                tst     2(R3)
                bmi     32$
                mov     R1, L.CVLT+2(R5)
                comb    L.FLCT(R5)
                br      28$
; ───────────────────────────────────────────────────────────────────────────

32$:            mov     L.CVLT+2(R5), R4
                mov     R1, L.RVLT(R5)
                sub     R4, R1
                bpl     33$
                neg     R1
                incb    L.FLCT(R5)
33$:            call    DIVIDE
                mov     #10, R0
                clr     R4
35$:            asl     R4
                asl     R3
                cmp     R3, R2
                blo     34$
                sub     R2, R3
                inc     R4
34$:            sob     R0, 35$
                tstb    L.FLCT(R5)
                beq     36$
                neg     R4
                neg     R1
                dec     R1
36$:            movb    R4, L.DVLT+1(R5)
                mov     R1, L.DVLT+2(R5)
                ; всё, заполняем регистры
28$:            tstb    L.FLCV(R5)
                bmi     37$
                add     L.DVLV(R5), L.CVLV(R5)
                tstb    L.TSLV(R5)
                bne     37$
                mov     L.RVLV(R5), L.CVLV(R5)
                comb    L.FLCV(R5)
37$:            movb    L.CVLV+1(R5), @#SAMAYB+Y.AMPB
                tstb    L.FLCN(R5)
                bmi     38$
                add     L.DVLN(R5), L.CVLN(R5)
                tstb    L.TSLN(R5)
                bne     38$
                mov     L.RVLN(R5), L.CVLN(R5)
                comb    L.FLCN(R5)
38$:            movb    L.CVLN+1(R5), @#SAMAYB+Y.NOIS
                tstb    L.FLCT(R5)
                bmi     39$
                add     L.DVLT(R5), L.CVLT(R5)
                adc     L.CVLT+2(R5)
                add     L.DVLT+2(R5), L.CVLT+2(R5)
                tstb    L.TSLT(R5)
                bne     39$
                mov     L.RVLT(R5), L.CVLT+2(R5)
                comb    L.FLCT(R5)
39$:            mov     L.CVLT+2(R5), @#SAMAYB+Y.CLKB
                mov     #SAMAYB+AYLEN, R4
                mov     #177714, R1
                mov     #1000, R3
                mov     #362, R2
40$:            mov     R2, (R1)
                movb    -(R4), R0
                com     R0
                movb    R0, (R1)
                incb    R2
                bmi     40$
                bit     #100, @#177716
                beq     41$
                tstb    L.PAUS(R5)
                bne     41$
                comb    L.PAUS(R5)
                mov     R5, R4
                inc     R4
                movb    L.ECYV(R5), (R4)+
                movb    L.ECYN(R5), (R4)+
                movb    L.ECYT(R5), (R4)+
                decb    L.ECYV(R5)
                decb    L.ECYN(R5)
                decb    L.ECYT(R5)
                clrb    L.TSLV(R5)
                clrb    L.TSLN(R5)
                clrb    L.TSLT(R5)
41$:            return
; End of function PLYSMP

; ───────────────────────────────────────────────────────────────────────────
CURSAM:         .word   0   ; адрес текущего сэмпла
SAMOCT:         .word   24. ; текущая октава в проигрывателе сэмплов
SAMBUF:         .word   0   ; буфер из двух байтов
F2020:          .word   0
F2024:          .word   0
F2030:          .word   0
F2114:          .word   0
W2170:          .word   0
W2246:          .word   0
W2162:          .word   0
; ───────────────────────────────────────────────────────────────────────────
W1350:          .word   52306
F1422:          .word   S1254
W1446:          .word   71306
F1524:          .word   S1254
W3452:          .word   42452   ; константа
W1036:          .word   71500   ; константа
W2126:          .word   7       ; константа
W2120:          .word   2300    ; константа
; ───────────────────────────────────────────────────────────────────────────
F2760:          .word   S1340   ; второй блок параметров редактора огибающей громкости
                .word   S1540
                .word   S2736
                .word   W1350
                .word   177760
                .word   4
                .word   46
F2776:          .word   S1436   ; второй блок параметров редактора огибающей шума
                .word   S1652
                .word   S2654
                .word   W1446
                .word   177740
                .word   6
                .word   63
; ───────────────────────────────────────────────────────────────────────────
S$VOLP:         .word   44404   ; Блок параметров для редактора огибающей громкости
                .word   S1VOLP  ; инициализация п/п редактора огибающей громкости
                .word   0
S$NSEP:         .word   44420   ; Блок параметров для редактора огибающей шума
                .word   S1NSEP  ; инициализация п/п редактора огибающей шума
                .word   -1
S$TONP:         .word   44432   ; Блок параметров для редактора огибающей тона
                .word   S1TONP  ; собственно подпрограмма редактора огибающей тона
                .word   2
; ───────────────────────────────────────────────────────────────────────────
W35000:         .word 37777
                .word 7777
                .word 1777
                .word 377
                .word 77
                .word 17
                .word 3
                .word 0
                .word 37777
                .word 37774
                .word 37760
                .word 37700
                .word 37400
                .word 36000
                .word 30000
                .word 0

W35040:         .word 25252
                .word 5252
                .word 1252
                .word 252
                .word 52
                .word 12
                .word 2
                .word 0
                .word 25252
                .word 25250
                .word 25240
                .word 25200
                .word 25000
                .word 24000
                .word 20000
                .word 0

W35100:         .word 300
                .word 1760
                .word 7774
                .word 7774
                .word 0
                .word 0
                .word 0
                .word 0

; ───────────────────────────────────────────────────────────────────────────
; Это индикаторы для редактора сэмплов. По 20 байтов на элемент.
; каждый байт - это два четверобития.
                .byte 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356
B34020:         .byte 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 216
                .byte 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 152
                .byte 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 316, 150
                .byte 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 254, 106
                .byte 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 316, 212, 106
                .byte 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 254, 150, 106
                .byte 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 316, 212, 150, 104
                .byte 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 254, 212, 146, 44
                .byte 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 316, 252, 210, 106, 44
                .byte 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 254, 212, 150, 106, 44
                .byte 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 316, 252, 210, 150, 106, 44
                .byte 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 254, 252, 210, 146, 106, 44
                .byte 356, 356, 356, 356, 356, 356, 356, 356, 356, 316, 254, 212, 210, 146, 104, 44
                .byte 356, 356, 356, 356, 356, 356, 356, 356, 356, 314, 252, 212, 150, 146, 104, 44
                .byte 356, 356, 356, 356, 356, 356, 356, 356, 316, 254, 252, 210, 150, 146, 104, 44
                .byte 356, 356, 356, 356, 356, 356, 356, 356, 314, 252, 212, 210, 146, 146, 104, 44
                .byte 356, 356, 356, 356, 356, 356, 356, 316, 254, 252, 210, 210, 146, 106, 104, 44
                .byte 356, 356, 356, 356, 356, 356, 356, 314, 252, 252, 210, 150, 146, 106, 104, 42
                .byte 356, 356, 356, 356, 356, 356, 316, 254, 252, 212, 210, 150, 146, 104, 104, 42
                .byte 356, 356, 356, 356, 356, 356, 314, 252, 252, 210, 210, 146, 146, 104, 104, 42
                .byte 356, 356, 356, 356, 356, 316, 254, 252, 212, 210, 210, 146, 146, 104, 104, 42
                .byte 356, 356, 356, 356, 356, 314, 252, 252, 212, 210, 150, 146, 146, 104, 104, 42
                .byte 356, 356, 356, 356, 316, 314, 252, 252, 210, 210, 150, 146, 106, 104, 104, 42
                .byte 356, 356, 356, 356, 314, 254, 252, 252, 210, 210, 146, 146, 106, 104, 104, 42
                .byte 356, 356, 356, 316, 314, 252, 252, 212, 210, 210, 146, 146, 106, 104, 104, 42
                .byte 356, 356, 356, 314, 254, 252, 252, 210, 210, 150, 146, 146, 106, 104, 104, 42
                .byte 356, 356, 316, 314, 252, 252, 212, 210, 210, 150, 146, 146, 104, 104, 104, 42
                .byte 356, 356, 314, 254, 252, 252, 212, 210, 210, 146, 146, 146, 104, 104, 44, 42
                .byte 356, 316, 314, 252, 252, 252, 210, 210, 210, 146, 146, 106, 104, 104, 44, 42
                .byte 356, 314, 254, 252, 252, 212, 210, 210, 150, 146, 146, 106, 104, 104, 44, 42
                .byte 316, 314, 252, 252, 252, 210, 210, 210, 150, 146, 146, 106, 104, 104, 44, 42

T$CRLN:         .ascii "CAROLINE"<1>"SOFTWARE"
                .byte 326
                .asciz "@ 1993"
                .even
                .word 0

B37712:         .byte 30, 37
                .ascii "LEVEL:"<1>
                .byte 326
                .ascii " >"
B37726:         .ascii "15"
                .asciz "<"
                .even
                .word 0

T$SMPL:         .ascii "SAMPLE "
V$SMSM:         .byte ']
                .byte 1
                .byte 1
                .ascii "OCTAVE "
V$SMOC:         .byte '3
                .byte 0
                .even
                .word 0

T$TVOL:         .asciz <37>"VOLUME"
                .even
                .word 0

T$TNSE:         .asciz <37>"NOISE"
                .even
                .word 0

T$TTON:         .asciz <37>"TONE"
                .even
                .word 0

T$SEMN:         .asciz <34>"VOLUME NOISE TONE OTHER QUIT"
                .even
                .word 43304
                .byte 6
                .byte 125
                .word S$MENU    ; Меню выбора пункта редактора сэмплов
                                ; Вход: R0 - адрес адреса блока параметров
                .word S$VOLP    ; Блок параметров для редактора огибающей громкости
                .word 43322
                .byte 5
                .byte 125
                .word S$MENU    ; Меню выбора пункта редактора сэмплов
                                ; Вход: R0 - адрес адреса блока параметров
                .word S$NSEP    ; Блок параметров для редактора огибающей шума
                .word 43336
                .byte 4
                .byte 125
                .word S$MENU    ; Меню выбора пункта редактора сэмплов
                                ; Вход: R0 - адрес адреса блока параметров
                .word S$TONP    ; Блок параметров для редактора огибающей тона
                .word 43350
                .byte 5
                .byte 125
                .word M$SAMP    ; Меню выбора другого сэмпла
                .word 0
                .word 43364
                .byte 4
                .byte 125
                .word M$QUIT
                .word 0
                .word 0

T$SESM:         .asciz <35>"CHANGE"<1><1>"CLEAR"
                .even
W37244:         .word 45706
                .byte 6
                .byte 377
                .word S$CHNG        ; Изменение выбранной огибающей сэмпла
W37252:         .word 0
W37254:         .word 47706
                .byte 6
                .byte 377
                .word S$CLRS        ; очистка выбранной огибающей сэмпла
W37262:         .word 0
                .word 0

; делаем независимость от монитора БК11М
PUSHA:          mov     R4, -(SP)
                mov     R3, -(SP)
                mov     R2, -(SP)
                mov     R1, -(SP)
                mov     R0, -(SP)
                call    (R5)
                mov     (SP)+, R0
                mov     (SP)+, R1
                mov     (SP)+, R2
                mov     (SP)+, R3
                mov     (SP)+, R4
                mov     (SP)+, R5
                return

; выход в оболочку
M$EXIT:         call    CNFIRM
                ; если согласны, продолжаем действия по выходу.
                mov     #100000, R2
                mov     #20000, R1
ANDHK1:         br      1$
                ; возвращаем страницу 4 на место
                mov     #42000, R0
                mov     #36000, R4  ; стр.3->окно0, стр.4->окно1
                mov     #16000, R5  ; стр.5->окно0, стр.4->окно1
                mov     #100000, -(SP)
                ; выход в оболочку ОС, для андос/мкдос
                br      2$
; ───────────────────────────────────────────────────────────────────────────
; выход в оболочку ОС, для ксидос
1$:             ; возвращаем страницу 6 на место
                mov     #45400, R0
                mov     #37400, R4  ; стр.3->окно0, стр.6->окно1
                mov     #54400, R5  ; стр.7->окно0, стр.5->окно1
                mov     #63000, -(SP)
                mov     R5, @#NPAGE
2$:             mov     R0, @#177662    ; выключаем таймер и устанавливаем нужную палитру
                mov     R4, @#177716
3$:             mov     -40000(R2), (R2)+   ; копируем содержимое стр.3 в стр.6 или в стр.4
                sob     R1, 3$
                mov     R5, @#177716
                return

; опции
M$OPTS:         mov     CurrMenuPt, -(SP)
                mov     SP, BF$SPD
                mov     #14000, @#NPAGE ; стр.5->окно0, стр.1->окно1
                call    SETPGE
                jmp     OVLOPT  ; идём в оверлейную часть за опциями.

                .org    40000

                .END

