
;регистры AY
AY.TonA         = 0
AY.TonB         = 2
AY.TonC         = 4
AY.Noise        = 6
AY.Mixer        = 7
AY.AmplitudeA   = 8.
AY.AmplitudeB   = 9.
AY.AmplitudeC   = 10.
AY.Envelope     = 11.
AY.EnvelopeType = 13.

;ChannelsVars
CHP.Note_Skip_Counter               = 0     ;byte
CHP.Number_Of_Notes_To_Skip         = 1     ;byte
CHP.Initial_Noise                   = 2     ;word
CHP.Current_Noise                   = 4     ;word
CHP.Note                            = 6.    ;word
CHP.Addition_To_Note                = 8.    ;word
CHP.Current_Ton_Sliding             = 10.   ;word
CHP.Substruction_for_Ton_Sliding    = 12.   ;word
CHP.Ton_Deviation                   = 14.   ;word
CHP.Addition_To_Amplitude           = 16.   ;word
CHP.Ton_Sliding_Counter             = 18.   ;byte
CHP.Amplitude_Delay                 = 19.   ;byte
CHP.Amplitude_Delay_Counter         = 20.   ;byte
CHP.Volume                          = 21.   ;byte
CHP.Envelope_Enabled                = 22.   ;byte
CHP.Sound_Enabled                   = 23.   ;byte

CHP.Initial_Point_In_Ornament       = 24.   ;word
CHP.Point_In_Ornament               = 26.   ;word
CHP.Loop_Point_In_Ornament          = 28.   ;word

CHP.Initial_Point_In_Sample         = 30.   ;word
CHP.Point_In_Sample                 = 32.   ;word
CHP.Loop_Point_In_Sample            = 34.   ;word
CHP.Sample_Finished                 = 36.   ;byte
CHP.Break_Sample_Loop               = 37.   ;byte
CHP.Address_In_Pattern              = 38.   ;word
CHP.Tone_Reg                        = 40.   ;byte Tone_Reg + Ampl_Reg должны быть выровнены по слову
CHP.Ampl_Reg                        = 41.   ;byte

CHP=42.

MDLADDR=10000
E36BP=320

;загрузка модуля.
Load:           mov     #1000, SP
                mtps    SP
                mov     #E36BP, R1
                mov     R1, R0
                mov     #3, (R0)+
                mov     #MDLADDR, (R0)+
                clr     (R0)+
                mov     #10, R2
1$:             mov     #20040, (R0)+
                sob     R2, 1$
                emt     36
                tstb    1(R1)
                beq     2$
                halt

2$:             call    Start_Play
                jmp     Load

; это для воспроизведения в основном цикле
Start_Play:     mov     #42400, @#177662    ; запрещаем прерывания по вектору 100
                mov     SP, MSP
                mov     @#4, MV4            ; прерывание по вектору 4
                mov     #NV4, @#4           ; поменяем на своё, чтобы по кнопке СТОП прекращать играть
                mov     #102, @#100         ; меняем вектор
                mov     #2, @#102
                mov     #MDLADDR, R1
                call    Init
                mov     #2400, @#177662
1$:             call    Play                ; играем квант
                wait                        ; ждём прерывания от вектора 100
                bit     #100, @#177716      ; пока клавиша не нажата
                bne     1$                  ; продолжаем играть
                ; нажатие любой клавиши - прекращение игры
NV4:            mov     #42400, @#177662    ; запрещаем прерывания по вектору 100
                call    MUTE                ; глушим AY
                mov     MV4, @#4            ; всё восстанавливаем назад
                mov     MSP, SP
                return

; это для воспроизведения в фоне
;Start_Play:     mov     #42400, @#177662    ; запрещаем прерывания по вектору 100
;                mov     @#4, MV4            ; прерывание по вектору 4
;                mov     #NV4, @#4           ; поменяем на своё, чтобы по кнопке СТОП прекращать играть
;                mov     #TRPT, @#100        ; адрес фоновой процедуры воспроизведения
;                mov     #340, @#102         ; адрес вектора
;                mov     #MDLADDR, R1
;                call    Init                ; инициализация переменных модуля воспроизведения
;                mov     #2400, @#177662     ; разрешаем прерывания обратно
;                return                      ; и выход, правда там уже надо не на загрузку следующего модуля
;                                            ; выходить, а куда-нибудь, куда надо
;
;NV4:            mov     #42400, @#177662    ; запрещаем прерывания по вектору 100
;                call    MUTE                ; глушим AY
;                mov     MV4, @#4            ; всё восстанавливаем назад
;                halt                        ; и делаем прерывание по вектору 4
;                                            ; или какие-то свои действия

MSP:            .word   0
MV4:            .word   0

TRPT:           mov     R0, -(SP)
                mov     R1, -(SP)
                mov     R2, -(SP)
                mov     R3, -(SP)
                mov     R4, -(SP)
                mov     R5, -(SP)
                call    Play
                mov     (SP)+, R5
                mov     (SP)+, R4
                mov     (SP)+, R3
                mov     (SP)+, R2
                mov     (SP)+, R1
                mov     (SP)+, R0
                rti

MUTE:           clr     AYREGS + AY.AmplitudeA
                clrb    AYREGS + AY.AmplitudeC
                movb    #77, AYREGS + AY.Mixer
                jmp     ROUT


Play:           decb    DelayCounter    ; уменьшаем текущий счётчик темпа
                bgt     1$              ; если ещё не пришло время брать новую ноту
                movb    Delay, DelayCounter
                mov     PC, R5
                add     #Channel_A-., R5
                decb    CHP.Note_Skip_Counter(R5)
                bpl     0SkipA$
                mov     CHP.Address_In_Pattern(R5), R4
                cmpb    (R4), #377      ; конец раздела?
                bne     3$              ; нет ещё - просто возьмём новую ноту
                clrb    R1
                bisb    CurrentPosition, R1
                mov     R1, R0          ; текущая позиция
                incb    R1              ; а это, какая будет следующая
                cmpb    R1, ASC_Number_Of_Positions ;до конца дошли?
                blo     2$              ; нет ещё
                movb    ASC_LoopingPosition, R1 ; иначе - позиция зацикливания
2$:             movb    R1, CurrentPosition ; сохраняем
                add     ASC_PositionsPointers, R0   ; адрес списка позиций
                clr     R1
                bisb    (R0), R1        ; номер раздела
                mov     R1, R0
                asl     R0
                add     R1, R0
                asl     R0              ; *6
                mov     ASC_PatternsPointers, R3
                add     R3, R0          ; смещения в таблице разделов
                clr     R4
                bisb    (R0)+, R4
                swab    R4
                bisb    (R0)+, R4
                swab    R4
                add     R3, R4          ; новый адрес канала A
                clr     CHP.Initial_Noise(R5)

                clr     R1
                bisb    (R0)+, R1
                swab    R1
                bisb    (R0)+, R1
                swab    R1
                add     R3, R1          ; новый адрес канала B
                mov     R1, Channel_B + CHP.Address_In_Pattern
                clr     Channel_B + CHP.Initial_Noise

                clr     R1
                bisb    (R0)+, R1
                swab    R1
                bisb    (R0)+, R1
                swab    R1
                add     R3, R1          ; новый адрес канала C
                mov     R1, Channel_C + CHP.Address_In_Pattern
                clr     Channel_C + CHP.Initial_Noise

3$:             call    PatternInterpreter
                mov     R4, CHP.Address_In_Pattern(R5)

0SkipA$:        add     #CHP, R5
                decb    CHP.Note_Skip_Counter(R5)
                bpl     0SkipB$
                mov     CHP.Address_In_Pattern(R5), R4
                call    PatternInterpreter
                mov     R4, CHP.Address_In_Pattern(R5)

0SkipB$:        add     #CHP, R5
                decb    CHP.Note_Skip_Counter(R5)
                bpl     0SkipC$
                mov     CHP.Address_In_Pattern(R5), R4
                call    PatternInterpreter
                mov     R4, CHP.Address_In_Pattern(R5)

0SkipC$:
1$:             clrb    TempMixer
                mov     PC, R5
                add     #Channel_A-., R5
                call    GetRegisters
                call    GetRegisters
                call    GetRegisters
                movb    TempMixer, AYREGS + AY.Mixer
                movb    Envelope_Base, AYREGS + AY.Envelope
                movb    Envelope_Base + 1, AYREGS + AY.Envelope + 1

ROUT:           ;вывод регистров
                mov     #177714, R5
                mov     #362, R1
                mov     PC, R4
                add     #AYREGS + AY.EnvelopeType-., R4
                movb    (R4), R0
                bmi     1$
                mov     R1, (R5)
                comb    R0
                movb    R0, (R5)
1$:             inc     R1
2$:             mov     R1, (R5)
                movb    -(R4), R0
                comb    R0
                movb    R0, (R5)
                incb    R1
                bmi     2$
                return

;вход:  R5 - адрес блока параметров канала
;       R4 - адрес в разделе
PatternInterpreter:
                clr     Initialization_Of_Sample_Disabled ;+clrb Initialization_Of_Ornament_Disabled
                clrb    CHP.Ton_Sliding_Counter(R5)
                clrb    CHP.Amplitude_Delay_Counter(R5)

0Loop$:         clr     R0
                bisb    (R4)+, R0
                cmpb    R0, #0xF0
                bhis    01$
                cmpb    R0, #0xE0
                beq     0Vol0$
                bhi     0VolN$
                cmpb    R0, #0xC0
                bhis    0Ornm$
                cmpb    R0, #0xA0
                bhis    0Smpl$
                cmpb    R0, #0x60
                bhis    0Skip$
                cmpb    R0, #0x5f
                beq     0x5f
                cmpb    R0, #0x5e
                beq     0x5e
                cmpb    R0, #0x56
                bhis    0Ret$
                mov     R0, CHP.Note(R5)
                mov     CHP.Initial_Noise(R5), CHP.Current_Noise(R5)
                tstb    CHP.Ton_Sliding_Counter(R5)
                bgt     10$
                clr     CHP.Current_Ton_Sliding(R5)
10$:            tstb    Initialization_Of_Sample_Disabled
                bne     11$
                clr     CHP.Addition_To_Amplitude(R5)
                clr     CHP.Ton_Deviation(R5)
                mov     CHP.Initial_Point_In_Sample(R5), CHP.Point_In_Sample(R5)
                movb    #-1, CHP.Sound_Enabled(R5)
                clrb    CHP.Sample_Finished(R5)
                clrb    CHP.Break_Sample_Loop(R5)
11$:            tstb    Initialization_Of_Ornament_Disabled
                bne     12$
                mov     CHP.Initial_Point_In_Ornament(R5), CHP.Point_In_Ornament(R5)
                clr     CHP.Addition_To_Note(R5)
12$:            tstb    CHP.Envelope_Enabled(R5)
                beq     0Ret$
                clr     R0
                bisb    (R4)+, R0
                mov     R0, Envelope_Base
                br      0Ret$

0x5f:           clrb    CHP.Sound_Enabled(R5)
                br      0Ret$

0x5e:           movb    #-1, CHP.Break_Sample_Loop(R5)
0Ret$:          movb    CHP.Number_Of_Notes_To_Skip(R5), CHP.Note_Skip_Counter(R5)
                return

0Vol0$:         movb    #0x0f, CHP.Volume(R5)
                movb    #0x10, CHP.Envelope_Enabled(R5)
                br      0Loop$

0VolN$:         sub     #0xE0, R0
                movb    R0, CHP.Volume(R5)
                clrb    CHP.Envelope_Enabled(R5)
                br      0Loop$

0Ornm$:         sub     #0xC0, R0
                asl     R0
                mov     ASC_OrnamentsPointers, R2
                add     R2, R0
                clr     R1
                bisb    (R0)+, R1
                swab    R1
                bisb    (R0)+, R1
                swab    R1
                add     R2, R1
                mov     R1, CHP.Initial_Point_In_Ornament(R5)
                br      0Loop$

0Smpl$:         sub     #0xA0, R0
                asl     R0
                mov     ASC_SamplesPointers, R2
                add     R2, R0
                clr     R1
                bisb    (R0)+, R1
                swab    R1
                bisb    (R0)+, R1
                swab    R1
                add     R2, R1
                mov     R1, CHP.Initial_Point_In_Sample(R5)
0Loop2$:        br      0Loop$

0Skip$:         sub     #0x60, R0
                movb    R0, CHP.Number_Of_Notes_To_Skip(R5)
                br      0Loop2$

01$:            bic     #0xfff0, R0 ;код FF сюда попадать не должен
                mov     R0, R1
                asl     R1
                add     R1, PC
                br      0xF0
                br      0xF1
                br      0xF2
                br      0xF3
                br      0xF4
                br      0xF5
                br      0xF6
                br      0xF7
                br      0xF8
                br      0xF9
                br      0xFA
                br      0xFB
                br      0xFC
0Loop1$:        br      0Loop2$ ;0xFD
0xFE:
0xFC:
0xFA:
0xF8:           movb    R0, AYREGS + AY.EnvelopeType
                br      0Loop2$

0xF0:           movb    (R4)+, R0   ;signed byte -> word
                mov     R0, CHP.Initial_Noise(R5)
                br      0Loop2$

0xF1:           incb    Initialization_Of_Sample_Disabled
                br      0Loop2$

0xF3:           incb    Initialization_Of_Sample_Disabled
0xF2:           incb    Initialization_Of_Ornament_Disabled
                br      0Loop2$

0xF4:           movb    (R4)+, Delay
                br      0Loop2$

0xF5:           movb    (R4)+, R0   ;signed byte -> word
                neg     R0
02$:            asl     R0
                asl     R0
                asl     R0
                asl     R0
                mov     R0, CHP.Substruction_for_Ton_Sliding(R5)
                movb    #-1, CHP.Ton_Sliding_Counter(R5)
                br      0Loop2$

0xF6:           movb    (R4)+, R0   ;signed byte -> word
                br      02$

0xF7:           incb    Initialization_Of_Sample_Disabled
                mov     CHP.Current_Ton_Sliding(R5), R1
                asr     R1
                asr     R1
                asr     R1
                asr     R1          ;delta_ton
                movb    1(R4), R3
                cmpb    R3, #0x56
                bhis    03$
                mov     CHP.Note(R5), R0
                asl     R0
                add     ASM_Table(R0), R1
05$:            asl     R3
                sub     ASM_Table(R3), R1
03$:            asl     R1
                asl     R1
                asl     R1
                asl     R1
                movb    (R4)+, R2
                movb    R2, CHP.Ton_Sliding_Counter(R5)
                mov     R1, CHP.Current_Ton_Sliding(R5)
                call    DIVDE$      ; знаковое деление
                                    ; вход:  R1 - делимое
                                    ;        R2 - делитель
                                    ; выход: R1 - целая часть
                                    ;        R3 - остаток
                                    ; портит R0
                neg     R1
                mov     R1, CHP.Substruction_for_Ton_Sliding(R5)
                sub     R3, CHP.Current_Ton_Sliding(R5)
                br      0Loop1$

0xF9:           movb    1(R4), R3
                cmpb    R3, #0x56
                bhis    04$
                mov     CHP.Note(R5), R0
                asl     R0
                mov     ASM_Table(R0), R1   ;delta_ton
                br      05$

04$:            mov     CHP.Current_Ton_Sliding(R5), R1
                asr     R1
                asr     R1
                asr     R1
                asr     R1          ;delta_ton
                br      03$

0xFB:           movb    (R4)+, R0
                aslb    R0
                aslb    R0
                aslb    R0          ;Amplitude_Delay := Index[Address_In_Pattern] shl 3;
                bcc     07$
                mov     #0xf8, R1
                xor     R1, R0
                add     #9., R0     ;bit 0 - знаковый, а биты 7-3 - модуль
07$:            movb    R0, CHP.Amplitude_Delay(R5)
                movb    R0, CHP.Amplitude_Delay_Counter(R5)
                br      0Loop1$

; знаковое деление (вообще без никаких проверок на ошибки и переполнение)
; вход:  R1 - делимое       + - + -
;        R2 - делитель      + + - -
; выход: R1 - целая часть   + - - + : xor знаков
;        R3 - остаток       + - + - : зависит от делимого
; портит R0
DIVDE$:         push    R5
                push    R4
                tst     R1  ;какой знак делимого?
                sxt     R4  ;бит N не изменяет, но в зависимости от него задаёт значение
                bpl     3$  ;>=0 - R4 == 0
                neg     R1  ;<0 - R4 == -1, и меняем знак
3$:             tst     R2  ;какой знак делителя?
                sxt     R5  ;флаг знака делителя
                bpl     4$  ;>=0 - R5 == 0
                neg     R2  ;<0 - R5 == -1, и меняем знак
4$:             xor     R4, R5 ;флаг знака результата целой части
                clr     R3
                mov     #20, R0
2$:             asl     R1
                rol     R3
                cmp     R3, R2
                blo     1$
                sub     R2, R3
                inc     R1
1$:             sob     R0, 2$
                tst     R5  ;какой знак должен быть у целой части?
                beq     5$  ;+
                neg     R1  ;-
5$:             tst     R4  ;какой знак должен быть у остатка?
                beq     6$  ;+
                neg     R3  ;-
6$:             pop     R4
                pop     R5
                return


GetRegisters:   tstb    CHP.Sample_Finished(R5)
                bne     1$
                tstb    CHP.Sound_Enabled(R5)
                bne     2$
1$:             clr     R3  ;амплитуда 0, тон - не изменяется
                jmp     Ret0$

2$:             mov     CHP.Addition_To_Amplitude(R5), R1
                movb    CHP.Amplitude_Delay_Counter(R5), R0
                beq     31$
                cmpb    R0, #16.
                blt     4$
                sub     #8., R0
                cmp     R1, #-15.
                bge     5$
                inc     R1
                br      3$

5$:             cmp     R1, #15.
                ble     3$
                dec     R1
                br      3$

4$:             bitb    #1, R0 ;Amplitude_Delay_Counter < 16
                beq     7$
                cmp     R1, #-15.
                ble     8$
                dec     R1
                br      8$

7$:             cmp     R1, #15.
                bge     8$
                inc     R1
8$:             movb    CHP.Amplitude_Delay(R5), R0
3$:             movb    R0, CHP.Amplitude_Delay_Counter(R5)

31$:            mov     CHP.Point_In_Sample(R5), R4
                movb    (R4), R0    ;Index[Point_In_Sample]
                bpl     9$
                mov     R4, CHP.Loop_Point_In_Sample(R5)
9$:             mov     R0, R2
                bic     #177637, R2 ;and 96.
                cmp     R2, #32.
                bne     10$
                movb    #-1, CHP.Sample_Finished(R5)
10$:            movb    1(R4), R2   ;signed byte -> word
                add     R2, CHP.Ton_Deviation(R5)

                movb    2(R4), R3   ;Index[Point_In_Sample + 2]
                mov     R3, R2
                bic     #177766, R2 ;and 9
                asl     R2
                asl     R2
                asl     R2
                bisb    R2, TempMixer
                clrb    Sample_Says_OK_for_Envelope
                mov     R3, R2
                bic     #177771, R2 ;and 6
                cmp     #2, R2
                bne     11$
                incb    Sample_Says_OK_for_Envelope
11$:            cmp     #4, R2
                bne     12$
                cmp     R1, #-15.
                ble     12$
                dec     R1
12$:            cmp     #6, R2
                bne     13$
                cmp     R1, #15.
                bge     13$
                inc     R1
13$:            mov     R1, CHP.Addition_To_Amplitude(R5)

                asr     R3
                asr     R3
                asr     R3
                asr     R3
                bic     #0xFFF0, R3
                add     R1, R3  ;Amplitude
                bpl     14$
                clr     R3
14$:            cmp     R3, #16.
                blo     15$
                mov     #15., R3 ;0..15.
15$:            movb    CHP.Volume(R5), R2  ;1..15.
                inc     R2
;умножение
;вход:  R3 - множимое (мл.байт)
;       R2 - множитель (мл.байт)
;выход: R3 - произведение (слово)
                mov     #10, R0
                swab    R3
1m$:            asl     R3
                bcc     0m$
                add     R2, R3
0m$:            sob     R0, 1m$

                asr     R3
                asr     R3
                asr     R3
                asr     R3
                ;всё, в R3 - готовая амплитуда
                movb    (R4), R0
                aslb    R0
                aslb    R0
                aslb    R0
                movb    R0, R0 ;signed byte -> word
                asr     R0
                asr     R0
                asr     R0
                tstb    Sample_Says_OK_for_Envelope
                beq     16$
                bitb    #64., TempMixer
                beq     16$
                add     R0, Envelope_Base
                br      17$

16$:            add     R0, CHP.Current_Noise(R5)
17$:            movb    (R4), R0
                add     #3, R4
                bitb    #64., R0
                beq     18$
                tstb    CHP.Break_Sample_Loop(R5)
                bne     19$
                mov     CHP.Loop_Point_In_Sample(R5), R4
                br      18$

19$:            bitb    #32., R0
                beq     18$
                movb    #-1, CHP.Sample_Finished(R5)
18$:            mov     R4, CHP.Point_In_Sample(R5)

                mov     CHP.Point_In_Ornament(R5), R4
                movb    (R4), R0    ;Index[Point_In_Ornament]
                bpl     20$
                mov     R4, CHP.Loop_Point_In_Ornament(R5)
20$:            movb    1(R4), R2   ;signed byte -> word
                add     R2, CHP.Addition_To_Note(R5)
                mov     R0, R2      ;бит 4 знаковый.
                mov     R0, R1
                bic     #0xfff0, R1
                bic     #0xffef, R2 ;(-shortint(Index[Point_In_Ornament] and $10)) or Index[Point_In_Ornament])
                neg     R2          ;распространяем бит 4 на все старшие биты
                bis     R1, R2
                add     R2, CHP.Current_Noise(R5)
                add     #2, R4
                bitb    #64., R0
                beq     21$
                mov     CHP.Loop_Point_In_Ornament(R5), R4
21$:            mov     R4, CHP.Point_In_Ornament(R5)

                bitb    #64., TempMixer
                bne     22$
                mov     CHP.Current_Ton_Sliding(R5), R0
                clrb    R0
                swab    R0  ;byte(Current_Ton_Sliding shr 8)
                add     CHP.Current_Noise(R5), R0
                bic     #0xffe0, R0
                movb    R0, AYREGS + AY.Noise

22$:            mov     CHP.Note(R5), R4
                add     CHP.Addition_To_Note(R5), R4
                bpl     23$
                clr     R4
23$:            cmp     R4, #0x56
                blo     24$
                mov     #0x55, R4
24$:            asl     R4
                add     PC, R4
                add     #ASM_Table-., R4
                mov     (R4), R4
                add     CHP.Ton_Deviation(R5), R4
                mov     CHP.Current_Ton_Sliding(R5), R0
                asr     R0
                asr     R0
                asr     R0
                asr     R0
                add     R0, R4
                bic     #0xf000, R4
                ;всё, в R4 - готовый тон
                movb    CHP.Tone_Reg(R5), R0
                add     PC, R0
                add     #AYREGS-., R0
                mov     R4, (R0)

                tstb    CHP.Ton_Sliding_Counter(R5)
                beq     25$
                blt     26$
                decb    CHP.Ton_Sliding_Counter(R5)
26$:            add     CHP.Substruction_for_Ton_Sliding(R5), CHP.Current_Ton_Sliding(R5)
25$:            tstb    Sample_Says_OK_for_Envelope
                beq     27$
                bisb    CHP.Envelope_Enabled(R5), R3
27$:
Ret0$:          asrb    TempMixer
                movb    CHP.Ampl_Reg(R5), R0
                movb    R3, AYREGS(R0)          ; !!! - неперемещема
                add     #CHP, R5
                return

;вход:  R1 - адрес загрузки модуля
Init:           mov     R1, Module_Address
                mov     R1, R5
                movb    (R1)+, Delay    ;темп
                movb    (R1)+, ASC_LoopingPosition ;предполагается что вторым байтом, но может и не быть.
                clr     R4
1$:             tst     (R1)+ ;+2
                call    GetAddr
                mov     R0, R3
                call    GetAddr
                mov     R0, R1
                call    GetWord
                cmp     R0, #0x40
                bne     0NoOk$
                mov     R3, R1
                call    GetWord
                cmp     R0, #0x40
                beq     0Ok$
0NoOk$:         inc     R4
                ;что-то не так. значит либо нет ASC_LoopingPosition, либо вообще не ASC
                clrb    ASC_LoopingPosition
                mov     R5, R1
                inc     R1
                cmp     R4, #2
                blo     1$
                ;если два раза сюда попали и оба раза неверно, то это не ASC
                sec
                return

0Ok$:           mov     R5, R1
                tst     (R1)+
                tst     R4
                beq     2$
                dec     R1
2$:             call    GetAddr
                mov     R0, ASC_PatternsPointers
                call    GetAddr
                mov     R0, ASC_SamplesPointers
                call    GetAddr
                mov     R0, ASC_OrnamentsPointers
                movb    (R1)+, ASC_Number_Of_Positions
                mov     R1, ASC_PositionsPointers
                mov     PC, R1
                add     #Vars-., R1
                mov     #EoVars-Vars, R0
3$:             clrb    (R1)+
                sob     R0, 3$

                mov     PC, R0
                add     #EndOfPat-., R0
                mov     PC, R5
                add     #Channel_A-., R5
                mov     (PC)+, R1
                .byte   AY.TonA, AY.AmplitudeA
                call    FillCHP
                mov     (PC)+, R1
                .byte   AY.TonB, AY.AmplitudeB
                call    FillCHP
                mov     (PC)+, R1
                .byte   AY.TonC, AY.AmplitudeC
                call    FillCHP
                call    ROUT
                clc
                return

FillCHP:
                clrb    CHP.Note_Skip_Counter(R5)
                mov     R0, CHP.Address_In_Pattern(R5)
                mov     R1, CHP.Tone_Reg(R5)
                add     #CHP, R5
                return

;получение адреса по смещению, на которое указывает R1
;вход:  R1 - текущий адрес в файле
;выход: R0 - адрес
GetAddr:        call    GetWord
                add     Module_Address, R0
                return

GetWord:        clr     R0
                bisb    (R1)+, R0
                swab    R0
                bisb    (R1)+, R0
                swab    R0
                return

ASM_Table:
                .word   0xedc, 0xe07, 0xd3e, 0xc80, 0xbcc, 0xb22, 0xa82, 0x9ec, 0x95c, 0x8d6, 0x858, 0x7e0
                .word   0x76e, 0x704, 0x69f, 0x640, 0x5e6, 0x591, 0x541, 0x4f6, 0x4ae, 0x46b, 0x42c, 0x3f0
                .word   0x3b7, 0x382, 0x34f, 0x320, 0x2f3, 0x2c8, 0x2a1, 0x27b, 0x257, 0x236, 0x216, 0x1f8
                .word   0x1dc, 0x1c1, 0x1a8, 0x190, 0x179, 0x164, 0x150, 0x13d, 0x12c, 0x11b, 0x10b, 0xfc
                .word   0xee, 0xe0, 0xd4, 0xc8, 0xbd, 0xb2, 0xa8, 0x9f, 0x96, 0x8d, 0x85, 0x7e
                .word   0x77, 0x70, 0x6a, 0x64, 0x5e, 0x59, 0x54, 0x50, 0x4b, 0x47, 0x43, 0x3f
                .word   0x3c, 0x38, 0x35, 0x32, 0x2f, 0x2d, 0x2a, 0x28, 0x26, 0x24, 0x22, 0x20
                .word   0x1e, 0x1c

EndOfPat:                   .byte   377
Delay:                      .byte   0
ASC_Number_Of_Positions:    .byte   0
ASC_LoopingPosition:        .byte   0
Module_Address:             .word   0
ASC_PositionsPointers:      .word   0
ASC_PatternsPointers:       .word   0
ASC_OrnamentsPointers:      .word   0
ASC_SamplesPointers:        .word   0
Vars:
DelayCounter:               .byte   0
CurrentPosition:            .byte   0
TempMixer:                  .byte   0
Sample_Says_OK_for_Envelope:            .byte   0
Initialization_Of_Sample_Disabled:      .byte   0 ;Initialization_Of_Sample_Disabled + Initialization_Of_Ornament_Disabled
Initialization_Of_Ornament_Disabled:    .byte   0 ;должны быть выровнены по слову
Envelope_Base:              .word   0
                            .even

Channel_A:      .blkb CHP
Channel_B:      .blkb CHP
Channel_C:      .blkb CHP
                .even

AYREGS:         .blkb 16.
EoVars:
                .end
