
;регистры 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

B.b7ix0             = 200
B.b6ix0             = 100
B.Enabled           =  40
B.b4ix0             =  20
B.MixNoise          =  10
B.Ornament_Enabled  =   4
B.Gliss             =   2
B.MixTon            =   1

CHP.ix0                     = 0     ;byte маска:200 - b7ix0
                                    ;           100 - b6ix0
                                    ;            40 - enabled
                                    ;            20 - b4ix0
                                    ;            10 - MixNoise
                                    ;             4 - Ornament_Enabled
                                    ;             2 - Gliss
                                    ;             1 - MixTon
CHP.ix21                    = 1     ;byte
CHP.Note                    = 2.    ;word
CHP.Volume                  = 4.    ;byte
CHP.Envelope_Enabled        = 5.    ;byte
CHP.Sample_Tik_Counter      = 6.    ;byte
CHP.Ornament_Tik_Counter    = 7.    ;byte
CHP.SamplePointer           = 8.    ;word
CHP.Point_In_Sample         = 10.   ;word
CHP.OrnamentPointer         = 12.   ;word
CHP.Point_In_Ornament       = 14.   ;word
CHP.Current_Ton_Sliding     = 16.   ;word
CHP.Ton_Slide_Step          = 18.   ;word
CHP.Transposit              = 20.   ;word

CHP.ix27                    = 22.   ;word
CHP.Address_In_Pattern      = 24.   ;word
CHP.Tone_Reg                = 26.   ;byte Tone_Reg + Ampl_Reg должны быть выровнены по слову
CHP.Ampl_Reg                = 27.   ;byte

CHP=28.

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$:
START:          mov     SP, MSP
                mov     @#4, MV4
                mov     #NV4, @#4
                mov     #V100, @#100
                mov     #340, @#102
                mov     #MDLADDR, R1
                call    Init
                bcs     2$
                mov     #2400, @#177662
1$:             call    Play
                wait
                bit     #100, @#177716
                bne     1$
NV4:            mov     #42400, @#177662
                call    MUTE
2$:             mov     MV4, @#4
                mov     MSP, SP
                jmp     Load

V100:           rti
MSP:            .word   0
MV4:            .word   0

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

Play:           decb    DelayCounter
                bgt     1$
                movb    Delay, DelayCounter
                decb    Lines_Counter
                bgt     2$

                mov     #Channel_C, R5
                mov     Positions_Pointer, R4
                call    NextPattern
                movb    R2, Lines_Counter
                call    NextPattern
                call    NextPattern
                movb    (R4), Delay
                movb    (R4)+, DelayCounter
                mov     R4, Positions_Pointer

2$:             mov     #Channel_C, R5
                call    PatternInterpreter
                sub     #CHP, R5
                call    PatternInterpreter
                sub     #CHP, R5
                call    PatternInterpreter

1$:             clrb    TempMixer
                mov     #Channel_C, R5
                call    GetRegisters
                sub     #CHP, R5
                call    GetRegisters
                sub     #CHP, R5
                call    GetRegisters
                movb    TempMixer, R0
                comb    R0
                bic     #0xffc0, R0
                mov     #Channel_A, R5
                mov     #B.MixNoise, R1
                mov     #B.MixTon, R2
                call    SetMix
                call    SetMix
                call    SetMix
                movb    R0, AYREGS + AY.Mixer
ROUT:           ;вывод регистров
                mov     #177714, R5
                mov     #362, R1
                mov     #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


SetMix:         bitb    #B.MixNoise, CHP.ix0(R5)
                bne     1$
                bisb    R1, R0
1$:             bitb    #B.MixTon, CHP.ix0(R5)
                bne     2$
                bisb    R2, R0
2$:             asl     R2
                asl     R1
                add     #CHP, R5
                return

NextPattern:    movb    (R4)+, R0   ;Index[Positions_Pointer]
                bne     3$
                mov     SQT_LoopPointer, R4
                movb    (R4)+, R0
3$:             bicb    #B.b4ix0, CHP.ix0(R5)
                aslb    R0
                bcc     4$
                bisb    #B.b4ix0, CHP.ix0(R5)
4$:             bic     #177400, R0
                add     SQT_PatternsPointer, R0
                clr     R1
                bisb    (R0)+, R1
                swab    R1
                bisb    (R0)+, R1
                swab    R1          ;Address_In_Pattern
                movb    (R1)+, R2   ;размер раздела
                mov     R1, CHP.Address_In_Pattern(R5)
                movb    (R4)+, R0
                movb    R0, R1
                bic     #0xfff0, R0 ;младшие 4 бита - громкость
                movb    R0, CHP.Volume(R5)
                asr     R1
                asr     R1
                asr     R1
                asr     R1  ;старшие 4 бита - транспозиция, причём знаковая.
                mov     R1, CHP.Transposit(R5)
                clrb    CHP.ix21(R5)
                sub     #CHP, R5
                return

;R5 - адрес блока параметров
PatternInterpreter:
                tstb    CHP.ix21(R5)            ;if ix21 <> 0 then
                beq     1$                      ;begin
                decb    CHP.ix21(R5)            ;  Dec(ix21);
                bitb    #B.b7ix0, CHP.ix0(R5)   ;  if b7ix0 then Call_LC191;
                beq     2$
                call    LC191
2$:             return                          ;  exit
                                                ;end;

1$:             mov     CHP.Address_In_Pattern(R5), R4  ;Ptr := Address_In_Pattern;
                bisb    #B.b6ix0, CHP.ix0(R5)           ;b6ix0 := True;
                bicb    #B.b7ix0, CHP.ix0(R5)           ;b7ix0 := False;

                clr     R0
                bisb    (R4), R0                ;case Index[Ptr] of
                cmpb    R0, #0x5f
                bhi     0x60                    ;0..$5f:
                                                ;begin
                mov     R0, CHP.Note(R5)        ;  Note := Index[Ptr];
                mov     R4, CHP.ix27(R5)        ;  ix27 := Ptr;
                inc     R4                      ;  Inc(Ptr);
                call    LC283                   ;  Call_LC283;
                bitb    #B.b6ix0, CHP.ix0(R5)   ;if b6ix0 then
                beq     3$
                mov     R4, CHP.Address_In_Pattern(R5)  ;Address_In_Pattern := Ptr;
3$:             return                          ;  break
                                                ;end;
0x60:           cmpb    R0, #0x6e
                bhi     0x6f                    ;$60..$6e:
                                                ;begin
                sub     #0x60, R0
                call    SetEffect               ;  Call_SetEffect(Index[Ptr] - $60);
                return                          ;  break
                                                ;end;
0x6f:           cmpb    R0, #0x7f
                bhi     0x80                    ;$6f..$7f:
                                                ;begin
                bicb    #B.Enabled + B.MixNoise + B.MixTon, CHP.ix0(R5) ;MixNoise := False;
                                                                    ;MixTon := False;
                                                                    ;Enabled := False;
                sub     #0x6f, R0               ;  if Index[Ptr] <> $6f then
                beq     4$
                call    SetEffect               ;    Call_SetEffect(Index[Ptr] - $6f)
                return
                                                ;  else
4$:             inc     R4
                mov     R4, CHP.Address_In_Pattern(R5) ;Address_In_Pattern := Ptr + 1;
                return                          ;  break
                                                ;end;
0x80:           cmpb    R0, #0xbf
                bhi     0xc0                    ;$80..$bf:
                                                ;begin
                mov     R4, R2
                inc     R2
                mov     R2, CHP.Address_In_Pattern(R5)  ;Address_In_Pattern := Ptr + 1;
                mov     R0, R2
                bic     #0xfff0, R2             ; Index[Ptr] and 15;
                cmpb    R0, #0x9f               ; if Index[Ptr] in [$80..$9f] then
                bhi     5$                      ;  begin
                bitb    #0x10, R0               ;   if Index[Ptr] and 16 = 0 then
                bne     6$
                add     R2, CHP.Note(R5)        ;     Inc(Note, Index[Ptr] and 15)
                br      7$
                                                ;   else
6$:             sub     R2, CHP.Note(R5)        ;     Dec(Note, Index[Ptr] and 15)
                br      7$                      ;  end
                                                ; else
                                                ;  begin
5$:             movb    R2, CHP.ix21(R5)        ;   ix21 := Index[Ptr] and 15;
                bitb    #0x10, R0               ;   if Index[Ptr] and 16 = 0 then
                beq     8$                      ;     break;
                tstb    R2                      ;   if ix21 <> 0 then
                beq     7$
                bisb    #B.b7ix0, CHP.ix0(R5)   ;     b7ix0 := True
                                                ;  end;
7$:             call    LC191                   ;  Call_LC191;
8$:             return                          ;  break
                                                ;end;
                                                ;$c0..$ff:
                                                ;begin
0xc0:           mov     R4, CHP.ix27(R5)        ;  ix27 := Ptr;
                inc     R4
                mov     R4, CHP.Address_In_Pattern(R5) ;Address_In_Pattern := Ptr + 1;
                bic     #0xffe0, R0             ;Index[Ptr] and 31
                call    SetSample               ;  Call_SetSample(Index[Ptr] and 31);
                return                          ;  break
                                                ;end;
;применить параметры последней ноты или последний сэмпл
;ix27 - указатель на ноту (0..5F) или код сэмпла (C0..FF)
LC191:          mov     CHP.ix27(R5), R4        ;Ptr := ix27;
                bicb    #B.b6ix0, CHP.ix0(R5)   ;b6ix0 := False;
                movb    (R4), R0                ;case Index[Ptr] of
                bpl     10$
                                                ;$80..$ff:
                bic     #0xffe0, R0             ; Index[Ptr] and 31
                call    SetSample               ; Call_SetSample(Index[Ptr] and 31);
                return
                                                ;0..$7f:
10$:            inc     R4                      ; Inc(Ptr);
                call    LC283                   ; Call_LC283
                return

;применение параметров ноты
;за нотой параметр - 1..3 байта
;b0: биты   7, 6:
;           0 х - присутствует только эффект, при этом биты 6..0 - код эффекта, b1 - параметр эффекта
;           1 0 - присутствует только сэмпл, при этом биты 5..1 - номер сэмпла
;           1 1 - присутствует всё. при этом биты b0:5..1 - номер сэмпла
;                                       биты b0:0 b1:7..4 - номер орнамента, b0:0 - старший бит
;                                       биты b1:3..0 - код эффекта, b2 - параметр эффекта
LC283:          movb    (R4), R0                ;case Index[Ptr] of
                bmi     11$
                                                ;0..$7f:
                call    SetEffect               ; Call_SetEffect(Index[Ptr]);
                br      13$
                                                ;$80..$ff:
11$:            mov     R0, R2
                asr     R0
                bic     #0xffe0, R0             ; if Index[Ptr] shr 1 and 31 <> 0 then
                beq     12$
                call    SetSample               ;   Call_SetSample(Index[Ptr] shr 1 and 31);
12$:            bitb    #64., R2                ; if Index[Ptr] and 64 <> 0 then
                beq     13$                     ; begin
                inc     R4
                clr     R0
                bisb    (R4), R0                ;  Temp := Index[Ptr + 1] shr 4;
                asrb    R2                      ;  if Index[Ptr] and 1 <> 0 then Temp := Temp or 16;
                rorb    R0
                asr     R0
                asr     R0
                asr     R0                      ;  if Temp <> 0 then
                beq     15$
                call    SetOrnament             ;    Call_SetOrnament(Temp);
15$:                                            ;  inc(Ptr);
                movb    (R4), R0                ;  if Index[Ptr] and 15 <> 0 then
                bic     #0xfff0, R0
                beq     13$
                call    SetEffect               ;    Call_SetEffect(Index[Ptr] and 15)
                                                ; end
13$:            inc     R4                      ;inc(Ptr)
                return

;вход:  R0 - параметр 1..1f
SetOrnament:    asl     R0
                add     SQT_OrnamentsPointer, R0    ;a * 2 + SQT_OrnamentsPointer
                clr     R2
                bisb    (R0)+, R2
                swab    R2
                bisb    (R0)+, R2
                swab    R2
                mov     R2, CHP.OrnamentPointer(R5)         ;OrnamentPointer := PWord(@Index[a * 2 + SQT_OrnamentsPointer])^;
                tst     (R2)+
                mov     R2, CHP.Point_In_Ornament(R5)       ;Point_In_Ornament := OrnamentPointer + 2;
                movb    #32., CHP.Ornament_Tik_Counter(R5)  ;Ornament_Tik_Counter := 32;
                bisb    #B.Ornament_Enabled, CHP.ix0(R5)    ;Ornament_Enabled := True
                return

;вход:  мл.байт R0 - параметр 0..1f
SetSample:      asl     R0
                add     SQT_SamplesPointer, R0  ;a * 2 + SQT_SamplesPointer
                clr     R2
                bisb    (R0)+, R2
                swab    R2
                bisb    (R0)+, R2
                swab    R2
                mov     R2, CHP.SamplePointer(R5)                       ;SamplePointer := PWord(@Index[a * 2 + SQT_SamplesPointer])^;
                tst     (R2)+
                mov     R2, CHP.Point_In_Sample(R5)                     ;Point_In_Sample := SamplePointer + 2;
                movb    #32., CHP.Sample_Tik_Counter(R5)                ;Sample_Tik_Counter := 32;
                clrb    CHP.Envelope_Enabled(R5)                        ;Envelope_Enabled := False;
                bicb    #B.Ornament_Enabled + B.Gliss, CHP.ix0(R5)      ;Ornament_Enabled := False;
                                                                        ;Gliss := False;
                bisb    #B.Enabled + B.MixNoise + B.MixTon, CHP.ix0(R5) ;Enabled := True;
                                                                        ;MixNoise := True;
                                                                        ;MixTon := True
                return

;вход:  R0 - параметр (число > 0)
SetEffect:      inc     R4                              ;inc(Ptr);
                bitb    #B.b6ix0, CHP.ix0(R5)           ;if b6ix0 then
                beq     20$
                                                        ;begin
                bicb    #B.b6ix0, CHP.ix0(R5)           ;  b6ix0 := False
                mov     R4, R2
                inc     R2
                mov     R2, CHP.Address_In_Pattern(R5)  ;  Address_In_Pattern := Ptr + 1;
                                                        ;end;
20$:            dec     R0                              ;case a - 1 of
                bpl     21$
                                                        ;else begin
22$:            movb    #0x10, CHP.Envelope_Enabled(R5) ;  Envelope_Enabled := True;
                bic     #0xfff0, R0
                movb    R0, AYREGS + AY.EnvelopeType    ;  SoundChip[CNum].SetEnvelopeRegister((a - 1) and 15);
                movb    (R4), AYREGS + AY.Envelope      ;  SoundChip[CNum].RegisterAY.Index[11] := Index[Ptr];
                return                                  ;end;

21$:            cmp     R0, #7
                bhi     22$
                movb    (R4), R1    ;Index[Ptr]
                asl     R0
                add     R0, PC
                br      00$
                br      01$
                br      02$
                br      03$
                br      04$
                br      05$
                ;br     06$
                ;br     07$
06$:            neg     R1
07$:            mov     R1, CHP.Ton_Slide_Step(R5)      ;  7:Ton_Slide_Step := Index[Ptr] / 6:Ton_Slide_Step := -Index[Ptr];
                clr     CHP.Current_Ton_Sliding(R5)     ;  Current_Ton_Sliding := 0;
                bisb    #B.Gliss, CHP.ix0(R5)           ;  Gliss := True;
                return

00$:            bitb    #B.b4ix0, CHP.ix0(R5)           ;if b4ix0 then Volume := Index[Ptr] and 15;
                beq     23$
24$:            bic     #0xfff0, R1                     ;Index[Ptr] and 15;
                movb    R1, CHP.Volume(R5)
23$:            return

01$:            bitb    #B.b4ix0, CHP.ix0(R5)           ;if b4ix0 then Volume := (Volume + Index[Ptr]) and 15;
                beq     23$
                movb    CHP.Volume(R5), R0
                add     R0, R1                          ;Volume + Index[Ptr]
                br      24$

02$:            bitb    #B.b4ix0, CHP.ix0(R5)           ;if b4ix0 then
                beq     25$                             ; begin
                movb    R1, Channel_A + CHP.Volume      ;  PlParams[CNum].SQT_A.Volume := Index[Ptr];
                movb    R1, Channel_B + CHP.Volume      ;  PlParams[CNum].SQT_B.Volume := Index[Ptr];
                movb    R1, Channel_C + CHP.Volume      ;  PlParams[CNum].SQT_C.Volume := Index[Ptr];
25$:            return                                  ; end;

03$:            bitb    #B.b4ix0, CHP.ix0(R5)           ;if b4ix0 then
                beq     25$                             ; begin
                movb    Channel_A + CHP.Volume, R0      ;  with PlParams[CNum].SQT_A do
                add     R1, R0                          ;   Volume := (Volume + Index[Ptr]) and 15;
                bic     #0xfff0, R0
                movb    R0, Channel_A + CHP.Volume
                movb    Channel_B + CHP.Volume, R0      ;  with PlParams[CNum].SQT_B do
                add     R1, R0                          ;   Volume := (Volume + Index[Ptr]) and 15;
                bic     #0xfff0, R0
                movb    R0, Channel_B + CHP.Volume
                movb    Channel_C + CHP.Volume, R0      ;  with PlParams[CNum].SQT_C do
                add     R1, R0                          ;   Volume := (Volume + Index[Ptr]) and 15;
                bic     #0xfff0, R0                     ; end;
                movb    R0, Channel_C + CHP.Volume
                return

04$:            bitb    #B.b4ix0, CHP.ix0(R5)           ;if b4ix0 then
                beq     28$                             ;  with PlParams[CNum].SQT do
                                                        ;   begin
27$:            bic     #0xffe0, R1                     ;    DelayCounter := Index[Ptr] and 31;
                bne     26$
                mov     #32., R1                        ;    if DelayCounter = 0 then DelayCounter := 32;
26$:            movb    R1, DelayCounter
                movb    R1, Delay                       ;    Delay := DelayCounter;
28$:            return                                  ;   end;

05$:            bitb    #B.b4ix0, CHP.ix0(R5)           ;if b4ix0 then
                beq     28$                             ; with PlParams[CNum].SQT do
                                                        ;  begin
                movb    DelayCounter, R0                ;   DelayCounter := (DelayCounter + Index[Ptr]) and 31;
                add     R0, R1          ;DelayCounter + Index[Ptr]
                br      27$

;R5 - адрес блока параметров
GetRegisters:
                aslb    TempMixer
                bitb    #B.Enabled, CHP.ix0(R5)
                bne     1$
                movb    CHP.Ampl_Reg(R5), R0
                clrb    AYREGS(R0)
                return

1$:             mov     CHP.Point_In_Sample(R5), R4 ;Point_In_Sample
                movb    (R4)+, R0   ;b0
                mov     R0, R1
                bic     #0xfff0, R1 ;Amplitude := b0 and 15;
                beq     2$
                movb    CHP.Volume(R5), R2
                sub     R2, R1
                bpl     3$
                clr     R1
                br      3$

2$:             movb    CHP.Envelope_Enabled(R5), R1
3$:             movb    CHP.Ampl_Reg(R5), R2
                movb    R1, AYREGS(R2)

                movb    (R4), R1        ;b1
                bitb    #64., R1
                beq     5$
                bisb    #B.MixTon, TempMixer
5$:             bitb    #32., R1
                beq     10$
                bisb    #B.MixNoise, TempMixer
                bic     #0xff0f, R0 ;биты 7..4 - биты 4..1 шума
                asr     R0
                asr     R0
                asr     R0
                aslb    R1          ;бит 7 - бит 0 шума
                adcb    R0
                movb    R0, AYREGS + AY.Noise
10$:

                mov     CHP.Note(R5), R0                    ;j := Note;
                bitb    #B.Ornament_Enabled, CHP.ix0(R5)    ;if Ornament_Enabled then
                beq     6$
                push    R4                                  ;begin
                mov     CHP.Point_In_Ornament(R5), R4
                movb    (R4)+, R3
                add     R3, R0                              ; inc(j, Index[Point_In_Ornament]);
                movb    CHP.Ornament_Tik_Counter(R5), R3
                decb    R3                                  ; Dec(Ornament_Tik_Counter);
                bne     7$                                  ; if Ornament_Tik_Counter = 0 then
                mov     CHP.OrnamentPointer(R5), R4         ;  begin
                movb    (R4)+, R2
                cmpb    R2, #32.                            ;   if Index[OrnamentPointer] <> 32 then
                beq     8$                                  ;    begin
                movb    (R4)+, R3                           ;     Ornament_Tik_Counter := Index[OrnamentPointer + 1];
                                                            ;     Point_In_Ornament := OrnamentPointer + 2 + Index[OrnamentPointer];
                br      9$                                  ;    end
8$:                                                         ;   else
                mov     CHP.SamplePointer(R5), R1           ;    begin
                movb    (R1)+, R2
                movb    (R1), R3                            ;     Ornament_Tik_Counter := Index[SamplePointer + 1];
                inc     R4                                  ;     Point_In_Ornament := OrnamentPointer + 2 + Index[SamplePointer];
9$:             add     R2, R4
                                                            ;    end
                                                            ;  end
7$:                                                         ; else
                                                            ;  inc(Point_In_Ornament)
                movb    R3, CHP.Ornament_Tik_Counter(R5)
                mov     R4, CHP.Point_In_Ornament(R5)
                pop     R4                                  ;end;
6$:

                add     CHP.Transposit(R5), R0
                bpl     11$
                clr     R0
11$:            cmp     R0, #0x60
                blo     12$
                mov     #0x5f, R0
12$:
                clr     R1
                bisb    (R4)+, R1           ;b1 - ст. байт
                swab    R1
                bisb    (R4)+, R1           ;Index[Point_In_Sample + 2] - мл. байт
                asl     R0
                mov     SQT_Table(R0), R0   ;Ton := SQT_Table[j]
                asl     R1                  ;бит 12 - знаковый
                asl     R1                  ;распространим знак
                asl     R1
                asr     R1
                asr     R1
                asr     R1
                sub     R1, R0              ;если знак +, то вычитаем; если знак -, то прибавляем
                bitb    #B.Gliss, CHP.ix0(R5)
                beq     15$
                add     CHP.Current_Ton_Sliding(R5), R0
                add     CHP.Ton_Slide_Step(R5), CHP.Current_Ton_Sliding(R5)
15$:            bic     #0xf000, R0 ;Ton
                movb    CHP.Tone_Reg(R5), R1
                mov     R0, AYREGS(R1)

                movb    CHP.Sample_Tik_Counter(R5), R2
                decb    R2                                  ;Dec(Sample_Tik_Counter);
                bne     13$                                 ;if Sample_Tik_Counter = 0 then
                mov     CHP.SamplePointer(R5), R3           ; begin
                movb    (R3)+, R0       ;Index[SamplePointer]
                movb    (R3)+, R2                           ;  Sample_Tik_Counter := Index[SamplePointer + 1];
                cmpb    R0, #32.                                ;  if Index[SamplePointer] = 32 then
                bne     14$                                 ;   begin
                bicb    #B.Enabled + B.Ornament_Enabled, CHP.ix0(R5)    ;    Enabled := False;
                                                            ;    Ornament_Enabled := False
                                                            ;   end;
14$:            mov     R3, R4                              ;  Point_In_Sample := SamplePointer + 2 + Index[SamplePointer] * 3
                add     R0, R4
                add     R0, R4
                add     R0, R4
                                                            ; end
                                                            ;else
                                                            ; inc(Point_In_Sample, 3);
13$:            movb    R2, CHP.Sample_Tik_Counter(R5)
                mov     R4, CHP.Point_In_Sample(R5)
                return

Init:           mov     R1, Module_Address
                movb    #1, Delay
;загруженный модуль сначала нужно подготовить
                mov     R1, R0
                add     #12., R1        ;реальный адрес таблицы сэмплов
                tst     (R0)+
                mov     (R0)+, R2   ;SQT_SamplesPointer
                sub     R1, R2      ;SQT_SamplesPointer - 12 смещение между реальностью и тем, что в модуле
                mov     R1, SQT_SamplesPointer
                mov     (R0)+, R1
                sub     R2, R1
                mov     R1, SQT_OrnamentsPointer
                mov     (R0)+, R1
                sub     R2, R1
                mov     R1, SQT_PatternsPointer
                mov     (R0)+, R1
                add     #2, R2      ;i := SQT_SamplesPointer - 10;
                sub     R2, R1      ;i2 := SQT_PositionsPointer - i;
                mov     R1, Positions_Pointer
                mov     (R0)+, R1
                sub     R2, R1
                mov     R1, SQT_LoopPointer
;а теперь нужно скорректировать все адреса и внутри модуля
                mov     SQT_SamplesPointer, R1
                cmp     R1, R0
                beq     2$
0$:             sec
                return

2$:             mov     SQT_OrnamentsPointer, R1
                ;скорректируем таблицу сэмплов
4$:             cmp     R0, R1
                bhis    3$
                mov     2(R0), R3
                sub     (R0), R3
                sub     R2, (R0)+
                cmp     R3, #0x62   ;размер сэмпла
                bne     0$          ;не такой - ошибка
                br      4$

3$:             mov     SQT_PatternsPointer, R1
                ;скорректируем таблицу орнаментов
6$:             cmp     R0, R1
                bhis    5$
                mov     2(R0), R3
                sub     (R0), R3
                sub     R2, (R0)+
                cmp     R3, #0x22   ;размер орнамента
                bne     0$          ;не такой - ошибка
                br      6$

                ;скорректируем таблицу разделов
5$:             ;но сначала нужно узнать размер таблицы.
                mov     Positions_Pointer, R5
                clr     R4
                clr     R3
14$:            tstb    (R5)
                beq     10$ ;конец таблицы
                tstb    R3  ;слишком много разделов
                bmi     0$  ;ошибка
                movb    (R5)+, R1
                bic     #0xff80, R1
                cmpb    R4, R1
                bhis    11$
                movb    R1, R4
11$:            inc     R5
                movb    (R5)+, R1
                bic     #0xff80, R1
                cmpb    R4, R1
                bhis    12$
                movb    R1, R4
12$:            inc     R5
                movb    (R5)+, R1
                bic     #0xff80, R1
                cmpb    R4, R1
                bhis    13$
                movb    R1, R4
13$:            inc     R5
                inc     R5
                add     #3, R3
                br      14$

10$:            mov     SQT_SamplesPointer, R1
                mov     (R1), R3
                asl     R4
                mov     R0, R1
                add     R4, R1
                cmp     R1, R3  ;перекрываем область сэмплов
                bhi     0$      ;ошибка
8$:             cmp     R0, R1
                bhis    7$
                sub     R2, (R0)+
                br      8$
7$:

                mov     #Vars, R1
                mov     #EoVars-Vars, R0
1$:             clrb    (R1)+
                sob     R0, 1$
                mov     #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:
                mov     R1, CHP.Tone_Reg(R5)
                add     #CHP, R5
                return


SQT_Table:      .word   0xd5d, 0xc9c, 0xbe7, 0xb3c, 0xa9b, 0xa02, 0x973, 0x8eb, 0x86b, 0x7f2, 0x780, 0x714
                .word   0x6ae, 0x64e, 0x5f4, 0x59e, 0x54f, 0x501, 0x4b9, 0x475, 0x435, 0x3f9, 0x3c0, 0x38a
                .word   0x357, 0x327, 0x2fa, 0x2cf, 0x2a7, 0x281, 0x25d, 0x23b, 0x21b, 0x1fc, 0x1e0, 0x1c5
                .word   0x1ac, 0x194, 0x17d, 0x168, 0x153, 0x140, 0x12e, 0x11d, 0x10d, 0xfe, 0xf0, 0xe2
                .word   0xd6, 0xca, 0xbe, 0xb4, 0xaa, 0xa0, 0x97, 0x8f, 0x87, 0x7f, 0x78, 0x71
                .word   0x6b, 0x65, 0x5f, 0x5a, 0x55, 0x50, 0x4c, 0x47, 0x43, 0x40, 0x3c, 0x39
                .word   0x35, 0x32, 0x30, 0x2d, 0x2a, 0x28, 0x26, 0x24, 0x22, 0x20, 0x1e, 0x1c
                .word   0x1b, 0x19, 0x18, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0xf, 0xe

                nop

Module_Address:             .word   0
SQT_SamplesPointer:         .word   0
SQT_OrnamentsPointer:       .word   0
SQT_PatternsPointer:        .word   0
Positions_Pointer:          .word   0
SQT_LoopPointer:            .word   0
Delay:                      .byte   0

Vars:
DelayCounter:               .byte   0
Lines_Counter:              .byte   0
CurrentPosition:            .byte   0
TempMixer:                  .byte   0
                            .even

Channel_A:      .blkb CHP
Channel_B:      .blkb CHP
Channel_C:      .blkb CHP
                .even
AYREGS:         .blkb 16.
Envelope_Base = AYREGS + 14.

;MDLADDR:
EoVars:         .end

;формат SQT модуля:
;смещение   размер  описание
;0          2       размер файла модуля
;2          2       абсолютный адрес таблицы сэмплов
;4          2       абсолютный адрес таблицы орнаментов
;6          2       абсолютный адрес таблицы разделов
;8          2       абсолютный адрес таблицы позиций
;10         2       абсолютный адрес позиции зацикливания
;12         -       начало таблицы абсолютных адресов сэмплов.




