;
; ╔═════════════════════════════════════════════════════════════════════════╗
; ║     This file is generated by The Interactive Disassembler (IDA)        ║
; ║     Copyright (c) 2006 by DataRescue sa/nv, <ida@datarescue.com>        ║
; ║ Licensed to: Nikto                                                      ║
; ╚═════════════════════════════════════════════════════════════════════════╝
;
; File Name   : decrypted part of tape loader
; Format      : Binary file
; Base Address: 0000h Range: 43ECh - 45F0h Loaded length: 0204h

; Processor:        К1801ВМ1
; Target assembler: BKTurbo8 Cross Assembler
; ═══════════════════════════════════════════════════════════════════════════
TLPICAddr = 41760   ; адрес, где располагается магнитофонный загрузчик для загрузки заставки
TLGMCAddr = 400     ; адрес, где располагается магнитофонный загрузчик для загрузки игры
.include "Bally_const.asm"

.la TLPICAddr       ; программа не перемещаемая, по умолчанию располагается по этому адресу
; ───────────────────────────────────────────────────────────────────────────
; первый кусок начало ----- размер 66 слов ------
TLBase:         ; адрес для расчёта смещений
Retry$:         mov     (PC)+, @(PC)+
PatchTL01:      .word   TrapTo14, 14                            ; patch TrapTo14 <- 1030 (TrapTo14 с адреса 400)
                mov     #20, -(SP)
                mov     #DoCount$, -(SP) ; 3322
                mov     #400, @#300     ; предполагаем проверку имени файла
                mov     #177716, R3
                mov     #40, R5

; Поиск начала файла
PPNF:           mov     #4000, R2       ; поиск нулей
                clr     R0              ; длительность предыдущего импульса
                ; - чтение импульса
4$:             clr     R4              ; длительность текущего импульса

1$:             bit     R5, (R3)        ; ждём сигнала
                beq     1$

2$:             inc     R4              ; считаем длительность сигнала
                bit     R5, (R3)
                bne     2$
                ; определение разброса
                sub     R4, R0          ; вычисляем разницу в длине импульсов
                bmi     3$              ; если текущий длиньше предыдущего - переход
                cmp     R0, #2          ; если разница слишком велика
                bhi     PPNF            ; начнём сначала

3$:             mov     R4, R0          ; текущий -> предыдущий
                sob     R2, 4$          ; и так много раз
                ; настройка на скорость
                clr     R0              ; аккумулятор
                mov     #128., R2       ; читаем 128 импульсов

5$:             call    @#117376        ; чтение бита
                                        ; Выход: R4 - длительность импульса
                add     R4, R0          ; суммируем
                sob     R2, 5$
                ; - вычисление границы 0
                mov     #7, R2          ; делим на 128

6$:             asr     R0
                sob     R2, 6$
                mov     R0, R4
                asr     R4
                add     R4, R0          ; прибавляем L/2
                mov     R0, @#314       ; граница нуля: (среднее арифметическое 128 импульсов) * 1.5

; Поиск маркера
10$:            clr     R4

11$:            inc     R4              ; считаем длительность сигнала
                bit     R5, (R3)
                bne     11$
                cmp     R4, R0          ; сигнал больше чем нулевой импульс?
                bhi     13$             ; да - переход
                clr     R4              ; нет - считаем длительность отсутствия сигнала

12$:            inc     R4
; второй кусок начало ----- размер 121 слов ------
                bit     R5, (R3)
                beq     12$
                cmp     R4, R0          ; отсутствие сигнала больше чем нулевой импульс?
                bcs     10$             ; нет - переход
                incb    @#300           ; да - у нас инверсное чтение

13$:            asl     R0
                cmp     R4, R0          ; импульс больше чем 2*L0 ?
                bhi     14$             ; да - начнём поиск с начала
                mov     #24, R2         ; размер заголовка
                br      16$
; ───────────────────────────────────────────────────────────────────────────

14$:            asl     R0
                cmp     R4, R0          ; импульс больше чем 4*L0 ?
                bhi     15$             ; да что-то особенное
                jmp     @(PC)+          ; начинаем с начала
PatchTL02:      .word   Retry$                                  ; patch Retry$ <- 400 (Retry$ с адреса 400)
; ───────────────────────────────────────────────────────────────────────────

15$:            mov     #50, R2         ; размер данных

16$:            mov     #322, R1        ; адрес блока параметров
PatchTL00:      mov     R1, R3          ; сюда записывается 510, это переход
                                        ; на Next14$

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

; Поиск маркера и Чтение блока
; Вход: R1  - адрес ОЗУ
;       R2  - длина блока

PPM:            mov     @#314, R0       ; длительность нуля
                tstb    @#300           ; инверсное чтение?
                bne     3$              ; да
                ; прямое чтение
1$:             clr     R4              ; счётчик

2$:             inc     R4              ; считаем длительность импульса
                bit     R5, (R3)
                bne     2$
                cmp     R4, R0          ; если импульс короче нуля
                bcs     1$              ; всё сначала
                br      5$
; ───────────────────────────────────────────────────────────────────────────
; инверсное чтение

3$:             clr     R4              ; счётчик

4$:             inc     R4              ; считаем длительность отсутствия импульса
                bit     R5, (R3)
                beq     4$
                cmp     R4, R0          ; если импульс короче нуля
                bcs     3$              ; всё сначала

5$:             asl     R0
                asl     R0
                cmp     R4, R0          ; импульс длиньше 2*L0
                bhi     Retry$-6        ; да - идём заново искать начало файла !!! ошибка
                                        ; нет - нашли маркер, за ним читаем бит.
                call    @#117376        ; Чтение бита
; End of function PPM                   ; Выход:  R4 - длительность бита


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

; Чтение блока
; Вход: R1  - адрес ОЗУ
;       R2  - длина блока

PCTBL:          mov     #10, R0

PCTBL3$:        br      PCTBL2$

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


PCTBIT:         call    PCTBIT2         ; двойной

PCTBIT2:        tstb    @#300           ; инверсное чтение?
                bne     4$              ; да
                ; прямое чтение
                clr     R4              ; счётчик длины бита

1$:             inc     R4              ; считаем длительность сигнала
                bit     R5, (R3)
                bne     1$

2$:             inc     R4              ; считаем длительность отсутствия сигнала
                bit     R5, (R3)
                beq     2$

3$:             cmp     R4, #60         ; получилось такое?
                bhi     PCTBIT2         ; если больше, то считать сначала
                return
; ───────────────────────────────────────────────────────────────────────────
                ; инверсное чтение
4$:             clr     R4              ; счётчик длины бита

5$:             inc     R4              ; считаем длительность отсутствия сигнала
                bit     R5, (R3)
                beq     5$

6$:             inc     R4              ; считаем длительность сигнала
                bit     R5, (R3)
                bne     6$
                br      3$
; End of function PCTBIT

PCTBL2$:        call    PCTBIT          ; читаем бит
                cmp     R4, @#314       ; смотрим, что насчитали
                bhi     1$              ; больше - единица
                clc                     ; меньше - 0
                br      2$
; ───────────────────────────────────────────────────────────────────────────

1$:             sec
; третий кусок начало ----- размер 130 слов ------

2$:             rorb    (R1)
                mov     @#316, R4
                tst     (SP)+
                rtt                     ; переходим крутить счётчик
; ───────────────────────────────────────────────────────────────────────────

TrapTo14:       tst     -(SP)           ; после каждой команды счётчика выполняться будет это
                mov     R4, @#316
                sob     R0, PCTBL3$
                add     #1, R1
                sob     R2, PCTBL       ; Чтение блока
                                        ; Вход: R1  - адрес ОЗУ
                                        ;       R2  - длина блока
                return
; ───────────────────────────────────────────────────────────────────────────

Next14$:        call    @#117260        ; Поиск маркера и Чтение блока
                                        ; Вход: R1  - адрес ОЗУ
                                        ;       R2  - длина блока
                tstb    @#301           ; имя проверять?
                beq     3$              ; нет
                mov     #10, R2
                mov     #326, R1

PatchTL12: ; тут адрес +2, надо аргумент патчить
1$:             cmp     <Name$-326>(R1), (R1)+                  ; patch <Name$-326> <- 714 тоже корректируем
                beq     2$
                br      WrongFile$      ; не то имя
                .word 171717
; ───────────────────────────────────────────────────────────────────────────

2$:             sob     R2, 1$

3$:             mov     (PC)+, R1       ; адрес
PatchTL03:      .word   PICLoad                                 ; patch 10000 <- 5300
                mov     @#324, R2       ; длина
                call    PPM             ; читаем файл
                mov     #302, R1        ; адрес
                mov     #2, R2          ; длина
                call    PCTBL           ; читаем КС
                mov     (PC)+, R5
PatchTL04:      .word   PICLoad                                 ; patch 10000 <- 5300
                mov     @#324, R4       ; посчитаем КС того, что загрузили
                call    @#116622        ; Подсчёт контрольной суммы.
                                        ; Вход:  R4 - длина массива
                                        ;        R5 - адрес начала массива
                                        ; Выход: R0 - контрольная сумма
                                        ;        R4 == 0
                                        ;        R5 - адрес за концом массива
                cmp     R0, @#302       ; сравним
                bne     WrongCS$        ; !!! тут не то чтобы ошибка, но слишком далеко за пределы ведёт
                mov     (PC)+, R2       ; расшифровываем
PatchTL05:      .word   PICCryptLen                             ; patch 2400 <- 15240
                mov     (PC)+, R1
PatchTL06:      .word   PICLoad                                 ; patch 10000 <- 5300

C4$:            mov     (R1), R0
PatchTL07:      neg     R0                                      ; patch neg <- dec
                swab    R0
                mov     R0, (R1)+
                sob     R2, C4$
                jmp     @(PC)+          ; запускаем
PatchTL08:      .word   PICLoad                                 ; patch 10000 <- 5300
; ───────────────────────────────────────────────────────────────────────────

WrongFile$:     mov     (PC)+, R1
PatchTL09:      .word   60                                      ; patch 60 <- 0
                mov     (PC)+, R2
PatchTL10:      .word   1                                       ; patch 1 <- 3
                call    @#107272        ; EMT 24 - установка курсора по координатам
                                        ; Вход: R1 - координата X
                                        ;       R2 - координата Y
                mov     #326, R1
                mov     #13, R2
                call    @#107050        ; EMT 20 - вывод строки символов
                                        ; Вход: R1 - адрес строки
                                        ;       R2 - длина мл байт, символ огр ст байт
                jmp     @(PC)+
PatchTL11:      .word   Retry$                                  ; patch Retry$ <- 400 (Retry$ с адреса 400)
; ───────────────────────────────────────────────────────────────────────────
Name$:          .ascii "BALLY.PIC       "                       ; patch "PI <- "GM
                .word 0
                .word 0
                .word 0
                .word 177777
                .word 0
                .word 40352
; вот тут конец кусков, на самом деле последний кусок короче на слово
                .blkb   34.
; ───────────────────────────────────────────────────────────────────────────

WrongCS$:       halt

; смещения от начала программы, для упрощения
OffsTL00 = PatchTL00 - TLBase
OffsTL01 = PatchTL01 - TLBase
OffsTL02 = PatchTL02 - TLBase
OffsTL03 = PatchTL03 - TLBase
OffsTL04 = PatchTL04 - TLBase
OffsTL05 = PatchTL05 - TLBase
OffsTL06 = PatchTL06 - TLBase
OffsTL07 = PatchTL07 - TLBase
OffsTL08 = PatchTL08 - TLBase
OffsTL09 = PatchTL09 - TLBase
OffsTL10 = PatchTL10 - TLBase
OffsTL11 = PatchTL11 - TLBase
OffsTL12 = PatchTL12+2 - TLBase
OffsTL13 = Name$+6 - TLBase


                .END
