;мой блок проигрывания для Rock Mon v.2.1

;структура блока параметров канала
TMPTIK=0        ;(1) счетчик тиков = темп
TPOSV=1         ;(1) текущий фрагмент громкости в сэмпле
TPOSN=2         ;(1) текущий фрагмент шума в сэмпле
TPOST=3         ;(1) текущий фрагмент тона в сэмпле
ASAMPL=4        ;(2) адрес текущего сэмпла
BCYCV=6         ;(1) начальный фрагмент зацикливания громкости в сэмпле
BCYCN=7         ;(1) начальный фрагмент зацикливания шума в сэмпле
BCYCT=10        ;(1) начальный фрагмент зацикливания тона в сэмпле
ECYCV=11        ;(1) конечный фрагмент зацикливания громкости в сэмпле
ECYCN=12        ;(1) конечный фрагмент зацикливания шума в сэмпле
ECYCT=13        ;(1) конечный фрагмент зацикливания тона в сэмпле
LNG1V=14        ;(1) длительность звучания текущего фрагмента громкости
LNG1N=15        ;(1) длительность звучания текущего фрагмента шума
DVV=16          ;(2) приращение при плавном изменении громкости
TVV=20          ;(2) текущее значение громкости в ст.байте
EVV=22          ;(2) конечное значение громкости в ст.байте
DVN=24          ;(2) приращение при плавном изменении шума
TVN=26          ;(2) текущее значение шума в ст.байте
EVN=30          ;(2) конечное значение шума в ст.байте
DVT=32          ;(4) приращение при плавном изменении тона
TVT=36          ;(4) текущее значение тона в ст.слове
EVT=42          ;(2) конечное значение тона
LNG1T=44        ;(2) длительность звучания текущего фрагмента тона
VPER=46         ;(1) период волнового пакета
VALUE=47        ;(1) -приращение громкости
NSPCE=50        ;(1) количество пустых нот
TSPCE=51        ;(1) текущее количество пустых нот
ACHNL=52        ;(2) адрес в голосе текущего паттерна
VOLPAK=54       ;(1) признак волпака (<0 - волпак, >=0 - нет)
NDLT=55         ;(1) длительность звучания первого фрагмента
L1FR=56         ;(2) текущая длительность звучания первого фрагмента
PAUSE=60        ;(1) флаг: 0 - нота, ^0 - пауза
NNOTE=61        ;(1) номер текущей ноты
CNOC=62         ;(1) 0,2,4
CNMT=63         ;(1) 1,2,4
CNMN=64         ;(1) 10,20,40
CNOA=65         ;(1) 10,11,12

CHPLN=70

;регистры AY
CLKA=0
CLKB=2
CLKC=4
NOISE=6
MIXER=7
AMPLA=10
AMPLB=11
AMPLC=12
PERIOD=13
VPAY=15

AYLEN=16

AYREG=CHPLN+CHPLN+CHPLN     ;начало области регистров AY в массиве переменных
ADATA=AYREG+AYLEN           ;начало области данных(мелодии) в массиве переменных

                                ;а так будет работа по прерыванию
START:  MOV     #102,@#100      ;MOV    #LOOP,@#100
        MOV     #2,@#102
        MOV     #5400,@#177662
        CALL    INITPL          ;JMP    INITPL
LOOP:   CALL    PLAY
        WAIT                    ;RTI
        TSTB    @#177660
        BPL     LOOP
        RESET
        RETURN

INITRM: JMP     INITPL
PLAY:   JSR     R5,@#154512
        CALL    EXPNOT          ;формируем квант данных для передачи в AY
        ADD     #15,R3
        MOV     #363,R2
        MOV     #177714,R5      ;и заполняем регистры AY
0$:     MOV     R2,(R5)
        MOVB    -(R3),R0
        COMB    R0
        MOVB    R0,(R5)
        INCB    R2
        BMI     0$
        RETURN

TMASK:  .WORD   1,2,4,10,20,40,100,200,400,1000,2000,4000,10000

;деление
;вход:  R1 - делимое
;       R2 - делитель
;выход: R1 - целая часть
;       R3 - остаток
DIVIDE: CLR     R3
        MOV     #20,R0
1$:     ASL     R1
        ROL     R3
        CMP     R3,R2
        BLO     0$
        SUB     R2,R3
        INC     R1
0$:     SOB     R0,1$
        BIC     #140000,R1
        TST     R4
RET$1:  RETURN

;чтение очередной ноты в канале
GETNOT: MOVB    (PC)+,(R5)
TEMP:   .WORD   0
        DECB    TSPCE(R5)
        BPL     RET$1
NEXT$3: MOV     R5,R3
        ADD     #ACHNL,R3
        MOV     (R3)+,R4        ;MOV ACHNL(R5),R4
        CLRB    (R3)+           ;CLRB VOLPAK(R5)
NEXT$2: MOVB    (R3)+,(R3)      ;MOVB NDLT(R5),L1FR(R5)
NEXT$1: MOVB    (R4)+,R1        ;берем очередной байт
        CMPB    (PC)+,R1        ;конец паттерна?
ENDPTN: .WORD   377
        BNE     0$              ;нет
        MOV     (PC)+,R0        ;да
CURATR: .WORD   0               ;текущий адрес в таблице разделов
LOOP$1: MOVB    (R0)+,R1        ;номер следующего паттерна
        BPL     1$              ;а паттерны то кончились
        MOV     (PC)+,R0        ;тогда - начнем сначала
BGNATR: .WORD   0
        BR      LOOP$1

1$:     MOVB    (R0)+,R2
        MOV     R2,HEIGHT       ;высота паттерна
        MOV     R0,CURATR
        ASL     R1              ;┐
        MOV     R1,R0           ;│умножаем номер паттерна на 6
        ASL     R1              ;│
        ADD     R1,R0           ;┘
        MOV     (PC)+,R1        ;адрес начала смещений до
BGNONA: .WORD   0               ;нотных массивов
        ADD     R1,R0
        ADD     (R0)+,R1
        MOV     R1,ACHNL(R5)    ;адрес голоса A
        ADD     (R0)+,R1
        MOV     R1,ACHNL+CHPLN(R5) ;адрес голоса B
        ADD     (R0)+,R1
        MOV     R1,ACHNL+CHPLN+CHPLN(R5) ;адрес голоса C
        BR      NEXT$3

0$:     TSTB    R1              ;пауза?
        BEQ     2$              ;да - обработать
        CMPB    #376,R1         ;отсутствует нота?
        BNE     3$
;обработка отсутствия ноты
        CLR     (R3)            ;CLR L1FR(R5)
        BR      4$

3$:     DECB    R1              ;смотрим, что за нота
        CMPB    #140,R1
        BLOS    5$
;обработка значения нот
        ADD     (PC)+,R1        ;прибавим высоту паттерна
HEIGHT: .WORD   0               ;высота проигрыша всего паттерна
        SWAB    R1
        CLRB    R1
        MOV     R1,PAUSE(R5)
        MOVB    #-1,TPOSV(R5)
        MOV     #-1,TPOSN(R5)
        BR      6$

5$:     MOV     R1,R0
        BIC     #177760,R1      ;сделаем тут значение переменной
        CMPB    #160,R0
        BLOS    7$
;обработка номеров сэмплов
        SWAB    R1              ;┐
        ASR     R1              ;│умножим номер сэмпла на 100
        ASR     R1              ;┘
        ADD     (PC)+,R1        ;прибавим адрес начала сэмплов
BGNASA: .WORD   0
        MOV     R5,R2
        BIT     (R2)+,(R2)+
        MOV     R1,(R2)+        ;адрес сэмпла
        MOVB    (R1)+,(R2)+     ;начало зацикливания для громкости
        MOVB    7(R1),(R2)+     ;начало зацикливания для шума
        MOVB    1(R1),(R2)+     ;начало зацикливания для тона
        MOVB    (R1)+,(R2)+     ;конец зацикливания для громкости
        MOVB    7(R1),(R2)+     ;конец зацикливания для шумп
        MOVB    1(R1),(R2)      ;конец зацикливания для тона
        BICB    #200,(R2)
        BR      NEXT$1

7$:     TSTB    R0
        BMI     8$
;обработка громкостей
        SUB     #17,R1
        MOVB    R1,VALUE(R5)    ;громкость - это value-17
        BR      NEXT$1

8$:     CMPB    #220,R0
        BLOS    9$
;обработка длительностей ноты
        ASL     R1
        MOVB    R1,-(R3)        ;MOVB R1,NDLT(R5)
        BR      NEXT$2

9$:     CMPB    #240,R0
        BLOS    10$
;обработка формы пакета
        MOVB    (R4)+,VPER(R5)  ;период пакета
        MOVB    R0,VOLPAK(R5)   ;если волпак, то должен быть <0
        MOV     #362,@#177714
        COMB    R1
        MOVB    R1,@#177714     ;устанавливаем форму пакета
        BR      NEXT$1

;обработка пустых нот
10$:    SUB     #240,R0
        MOVB    R0,NSPCE(R5)    ;количество пустых нот
        BR      NEXT$1

;обработка паузы
2$:     CLR     (R3)+           ;CLR L1FR(R5)
        TSTB    (R3)            ;TSTB PAUSE(R5)
        BNE     4$
        DECB    (R3)            ;DECB PAUSE(R5)
        MOV     R5,R2
        INC     R2
        MOVB    10(R2),(R2)+
        MOVB    10(R2),(R2)+
        MOVB    10(R2),(R2)
6$:     CLR     LNG1V(R5)
        CLRB    LNG1T(R5)
4$:     MOV     R4,ACHNL(R5)
        MOVB    NSPCE(R5),TSPCE(R5)
        RETURN

L1700:  MOV     R0,R3
        ASL     R3
        MOV     TMASK(R3),R4
        MOV     ASAMPL(R5),R3
        ADD     R3,R0
        RETURN

MIXER$: BIT     R4,R3
        BNE     0$
        BISB    R0,VARPRT+AYREG+MIXER
        BR      1$
0$:     BICB    R0,VARPRT+AYREG+MIXER
1$:
;работа с длительностями звучания, сюда попадает длит*16
;результат:
;0 -0; 1 -1; 2 -5; 3 -9; N -(N*4-3)
L1724:  ASR     R2
        ASR     R2
        BEQ     0$
        SUB     #3,R2
0$:     ADD     L1FR(R5),R2
        RETURN

SBR3:   MOVB    R1,EVV+1(R5)
        TST     R3              ;огибающую изменять плавно?
        BMI     1$
        MOVB    R1,TVV+1(R5)    ;нет
        RETURN
1$:     MOVB    TVV+1(R5),R0    ;да - плавное изменение
        CLR     R4
        SUB     R0,R1
        BPL     2$
        NEG     R1
        INC     R4
2$:     SWAB    R1
        CALL    DIVIDE
        BEQ     3$
        NEG     R1
3$:     MOV     R1,DVV(R5)
        RETURN

L2042:  INC     R4
        INCB    (R4)
        MOVB    (R4),R0
        TSTB    PAUSE(R5)
        BNE     0$
        CMPB    10(R4),R0
        BHIS    0$
        MOVB    5(R4),R0
        MOVB    R0,(R4)
0$:     CMPB    R0,#15
        BLO     1$
        DECB    (R4)
1$:     RETURN

        .ASCII  "(c)GID prod."
SIGID:  .ASCII  "*CAROLINE*"

EXPNOT: MOV     PC,R5
        ADD     (PC)+,R5
        .WORD   @VARPRT+2
        CLRB    VARPRT+AYREG+NOISE
        CALL    2(PC)
        MOV     PC,-(SP)
        DECB    (R5)
        BGT     0$
        CALL    GETNOT

0$:     DECB    LNG1V(R5)
        BPL     1$
;достаем из сэмпла новую громкость и ее длительность
        CLR     DVV(R5)
        MOV     R5,R4
        CALL    L2042
        BLO     2$
        CLR     TVV(R5)
        BR      1$

2$:     CALL    L1700
        MOV     4(R3),R3 ;маска в огибающей громкости
        CLR     R1
        BISB    46(R0),R1
        MOV     R1,R2
        BIC     #360,R1 ;значение громкости
        BIC     R1,R2   ;длительность фрагмента громкости
        MOVB    CNMT(R5),R0
        CALL    MIXER$
        CALL    SBR3
        MOVB    R2,LNG1V(R5)

1$:     DECB    LNG1N(R5)
        BPL     3$
;достаем из сэмпла новый уровень шума и его длительность
        MOV     R5,R4
        INC     R4
        CLR     DVN(R5)
        CALL    L2042
        BHIS    3$
        CALL    L1700
        CLR     R1
        BISB    63(R0),R1
        MOV     R1,R2
        BIC     #340,R1 ;значение шума
        BIC     R1,R2
        BIT     12(R3),R4
        BEQ     4$
        BISB    #20,R2  ;длительность фрагмента шума
4$:     MOV     6(R3),R3 ;маска в огибающей шума
        MOVB    CNMN(R5),R0
        CALL    MIXER$
        ADD     #DVN-DVV,R5
        CALL    SBR3
        ADD     #DVV-DVN,R5
        MOVB    R2,LNG1N(R5)

3$:     DECB    LNG1T(R5)
        BPL     5$
;достаем из сэмпла новый тон и его длительность
        MOV     R5,R4
        TST     (R4)+
        CLR     DVT(R5)
        CLR     DVT+2(R5)
        CALL    L2042
        BHIS    5$
        ASL     R0
        MOV     ASAMPL(R5),R3
        ADD     R3,R0
        MOV     14(R0),R2
        MOV     R2,R4
        SWAB    R2
        BIC     #176000,R4
        BITB    #4,R2           ;минус?
        BEQ     6$
        BIS     #176000,R4      ;да
6$:     MOVB    NNOTE(R5),R1
        BITB    #10,R2          ;изменение в полутонах?
        BEQ     7$              ;нет
        ADD     R4,R1           ;да - просто прибавим
        BPL     8$              ;и проконтролируем
        CLR     R1              ;чтоб не вылезло
        BR      7$

8$:     CMP     #137,R1         ;за пределы
        BHIS    7
        MOV     #137,R1
7$:     ASL     R1
        ADD     PC,R1
        ADD     (PC)+,R1
        .WORD   @NOTCLK+2
        MOV     (R1),R1         ;получим частоту
        BITB    #10,R2          ;снова проверим: изменение в полутонах??
        BNE     9$              ;да пойдем туда
        SUB     R4,R1           ;отнимем значение от частоты
        BPL     9$
        CLR     R1
9$:     BIC     #177417,R2      ;получим длительность * 16
        CALL    L1724
        MOVB    R2,LNG1T(R5)
        MOV     R1,EVT(R5)
        TST     2(R3)           ;ноту менять плавно?
        BMI     10$
        MOV     R1,TVT+2(R5)    ;нет
        BR      5$

10$:    CLR     R4              ;плавное изменение ноты
        SUB     TVT+2(R5),R1
        BPL     11$
        NEG     R1
        INC     R4
11$:    CALL    DIVIDE
        BEQ     12$
        COM     R1
12$:    MOV     R1,DVT+2(R5)
        MOV     #10,R0
        CLR     R1
14$:    ASL     R1
        ASL     R3
        CMP     R3,R2
        BLO     13$
        SUB     R2,R3
        INC     R1
13$:    SOB     R0,14$
        TST     R4
        BEQ     15$
        NEG     R1
15$:    MOVB    R1,DVT+1(R5)
;заполняем регистры AY
5$:     MOV     PC,R3
        ADD     (PC)+,R3
        .WORD   @VARPRT+AYREG+2 ;начало снимка памяти для сопра
        MOVB    CNOA(R5),R4     ;смещение до регистра амплитуды
        ADD     R3,R4
        MOV     R5,R0
        ADD     #DVV+1,R0
        ADD     (R0)+,(R0) ;DVV,TVV      ;прибавляем к текущей амплитуде значение для плавного изменения
        TSTB    LNG1V(R5)       ;а надо ли плавно изменять?
        BNE     16$
        MOV     2(R0),(R0) ;EVV,TVV     ;нет - сразу подставляем конечный результат
16$:    MOVB    1(R0),R1   ;TVV+1     ;текущее значение амплитуды
        BEQ     18$             ;если 0, то ничего не делать
        TSTB    VOLPAK(R5)      ;волпак есть?
        BPL     17$             ;нет
        MOVB    #20,(R4)        ;ставим признак волпака
        BISB    CNMN(R5),MIXER(R3) ;запрещаем шум
        MOVB    VPER(R5),PERIOD(R3)
        BR      19$

17$:    MOVB    VALUE(R5),R2
        ADD     R2,R1
        BPL     18$
        CLR     R1
18$:    MOVB    R1,(R4)         ;формируем амплитуду в канале
19$:    BIT     (R0)+,(R0)+ ;EVV
        ADD     (R0)+,(R0)+ ;DVN,TVN
        TSTB    LNG1N(R5)
        BNE     20$
        MOV     (R0),-(R0)  ;EVN,TVN
20$:    BITB    CNMN(R5),MIXER(R3)
        BNE     21$
        MOVB    TVN+1(R5),R0
        CMPB    NOISE(R3),R0
        BHIS    21$
        MOVB    R0,NOISE(R3)
21$:    MOVB    CNOC(R5),R4     ;смещение до регистра частоты
        ADD     R3,R4
        MOV     R5,R2
        ADD     #TVT,R2
        ADD     DVT(R5),(R2)+ ;TVT
        ADC     (R2)          ;TVT+2
        ADD     DVT+2(R5),(R2)+
        TSTB    LNG1T(R5)
        BNE     22$
        MOV     (R2),-2(R2)   ;EVT,TVT+2
22$:    MOV     -(R2),(R4)

LGONX:  CLR     L1FR(R5)
        ADD     #CHPLN,R5
        RETURN

INITPL: NOP
        JSR     R5,@#154512
        RESET
        MOVB    #377,VARPRT+AYREG+MIXER ;глушим все
        MOV     PC,R5
        ADD     (PC)+,R5
        .WORD   @VARPRT+ADATA+2 ;начало области темпа и смещений
        MOV     R5,R4
        MOV     (R5)+,TEMP
        MOV     (R5)+,R0
        ADD     R4,R0
        MOV     R0,BGNATR       ;это начало
        MOV     R0,CURATR       ;списка разделов
        MOV     (R5)+,R0
        ADD     R4,R0
        MOV     R0,BGNONA       ;это начало таблицы смещений
                                ;до нотных массивов
        MOV     R5,BGNASA       ;это начало сэмплов
        MOV     PC,R5
        ADD     (PC)+,R5
        .WORD   @VARPRT+2
        MOV     PC,R4
        ADD     (PC)+,R4
        .WORD   @ENDPTN+2
        CALL    2(PC)
        MOV     PC,-(SP)
        CLRB    (R5)
        MOV     R4,ACHNL(R5)
        MOV     BGNASA,ASAMPL(R5)
        CLR     NSPCE(R5)
        MOVB    #-20,VALUE(R5)
        BR      LGONX

NOTCLK: .WORD   7370,7020,6540,6200,5730,5450,5210,4760
        .WORD   4540,4340,4130,3740
        .WORD   3574,3410,3260,3100,2754,2624,2504,2370
        .WORD   2260,2160,2054,1760
        .WORD   1676,1604,1530,1440,1366,1312,1242,1174
        .WORD   1130,1070,1026,770
        .WORD   737,702,654,620,573,545,521,476
        .WORD   454,434,413,374
        .WORD   357,341,326,310,275,262,250,237
        .WORD   226,216,205,176
        .WORD   167,160,153,144,136,131,124,117
        .WORD   113,107,102,77
        .WORD   73,70,65,62,57,54,52,47,45,43,41,37
        .WORD   35,34,32,31,27,26,25,23,22,21,20,17

;3520 начало переменной части на каждый канал по 70 байтов
;потом 16 байтов на регистры AY
VARPRT:
        .END

                     Формат ROCK_MONITORа:

                            Музыка:
────────────┬──────────────────────────────────────────────────
 Смещение:  │                    Значение:
────────────┼──────────────────────────────────────────────────
    0       │  номер ноты (0-пауза, 176-отсутствует, бит7=1 -
            │  у V отсутствует параметр).
    1       │  байт атрибутов:
            │  76543210
            │  │││  └───── признак отсутствия периода.
            │  ││└──────── признак отсутствия номера сэмпла.
            │  │└───────── признак отсутствия формы пакета.
            │  └────────── признак присутствия Volume.
    2       │  байт параметров:
            │  76543210
            │  └┴┴┤└┴┴┤
            │     │   └─── громкость.
            │     └─────── номер сэмпла.
    3       │  период огибающей или длительность ноты.
────────────┴──────────────────────────────────────────────────

                  Формат хранения паттернов:

             ┌─────────────────────────────────┐ (куча нулей
             │ голос А паттерн 0,177777,177777 │ этого же раз-
             │ голос В паттерн 0,177777,177777 │ мера,если го-
             │ голос С паттерн 0,177777,177777 │ лос пустой)
             └─────────────────┬───────────────┘
             ┌─────────────────┴───────────────┐
             │ голос А паттерн 1,177777,177777 │
             │ ............................... │
             │ ............................... │
             └─────────────────┬───────────────┘
                               │
                               
                            И т.д.

                       Атрибуты музыки:

─────────────────────┬─────────────────────────────────────────
     Смещение:       │                Значение:
─────────────────────┼─────────────────────────────────────────
       33000         │ Список всех паттернов в формате:
                     │ Слово 0 - адрес начала паттерна 0
                     │ Слово 1 - общая длина паттерна 0 в байтах
                     │ Слово 2 - адрес начала паттерна 1
                     │ ..............
       34772         │ Темп (Crack vers. by (c) GID)
       34774         │ Количество паттернов в нотном тексте.
       34776         │ Количество разделов в музыке - 1.
       35000         │ Список разделов в формате:
                     │ Байт 0  - PATTERN
                     │ Байт 1  - HEIGHT
                     │ Байт 2  - PATTERN
                     │ ..............
─────────────────────┴─────────────────────────────────────────
                    Формат одного сэмпла:
─────────────────────┬─────────────────────────────────────────
       36000         │ Два байта: первый - номер начала зацик-
                     │ ливаемого фрагмента громкости (с нуля),
                     │ второй номер последнего зацикливаемого
                     │ фрагмента (15.,15. если зацикливания
                     │ нет).
       36002         │ То же самое для тона с той разницей, что
                     │ старший бит является признаком плавного
                     │ изменения.
       36004         │ Маска тона в огибающей громкости (стар-
                     │ ший бит - признак плавного изменения).
       36006         │ Маска в огибающей шума (то же самое).
       36010         │ Байты для зацикливания шума (см. выше)
       36012         │ Младшие биты для длины фрагментов в оги-
                     │ бающей шума.
       36014         │ Список фрагментов огиб. тона в формате:
                     │ Байт 0  - размер первой  колонки
                     │ Байт 1  - 76543210
                     │           └┴┴┤││└┴─ два старших бита
                     │              │││     размера колонки
                     │              ││└─── признак минуса
                     │              │└──── признак измерения
                     │              │       в полутонах.
                     │              └───── длительность пер-
                     │                      вой колонки.
                     │ Байт 2  - размер второй колонки
                     │ ..................
       36046         │ Список фрагментов огибающей громкости
                     │ в формате:
                     │ Байт 0: 76543210
                     │         └┴┴┤└┴┴┴ размер первой колонки.
                     │            └──── длительность.
                     │ Байт 1:        ............
       36063         │ Список фрагментов огибающей шума в фор-
                     │ мате:
                     │ Байт 0: 76543210
                     │         └┴┤└┴┴┴┴ размер первой колонки.
                     │           └───── длительность (старшие
                     │                   биты см.выше)
                     │ Байт 1:        ............
       36100         │ СЭМПЛ 2:   ************************
─────────────────────┴─────────────────────────────────────────



