;Доработанный тест контроллеров АльтПро с ДОЗУ 64-512КБ. Версия 4.74F
;Изменения и нововведения в v4.1:
;* Тест памяти определяет только её количество, и корректность байтового доступа.
;* Тест режимов работает и на БК-0010(01), и на БК-0011М, вывод результатов теста режимов сделан более
;  человекопонятным.
;* Определяется тип контроллера по признаку в слове 0167776.
;Изменения и нововведения в v4.3:
;* Изменён тест определения количества памяти.
;* Добавлен тест проверки на битые ячейки памяти.
;Изменения и нововведения в v4.41:
;* Тест режимов перенесён вперёд, перед тестом памяти.
;* Добавлен свой знакогенератор, чтобы не зависеть от мониторов БК10 и БК11.
;* Добавлено определение версии прошивки 555РТ5.
;* v4.41 - попытка исправить ошибки скроллинга.
;Изменения и нововведения в v4.51:
;* Добавлен тест переключения страниц в проблемных режимах.
;* При заполнении экрана информацией выводится сообщение "нажмите любую клавишу" и программа ожидает 
;  нажатия любой клавиши, кроме СТОП и управляющих естественно.
;  работы.
;* v4.51 - Иногда, в нештатных случаях могли возникнуть ситуации, когда регистр 177130 на БК-0010
;  накладывался на ПЗУ бейсика и это приводило к неправильной работе теста. Теперь это исправлено,
;  возникающее прерывание по вектору 4 при записи в 177130 теперь игнорируется.
;Изменения и нововведения в v4.72F:
;* Добавлены тесты конструктивных особенностей: доступ к регистрам HDD, тест буфера ОЗУ для HDD, реакция на команду RESET, реакция на биты 2 (код 4) и 3 (код 10)
;* v4.71 - уточнение реакции на биты 2 и 3.
;* v4.72 - ещё одно уточнение реакции на биты 2 и 3.
;Изменения и нововведения в v4.73F:
;* Тест памяти на ошибки немного усложнён.
;Изменения и нововведения в v4.74F:
;* Тест памяти на ошибки изменён. Добавлено длинное тестирование случайными числами, 
;  с целью проверки стабильности, длительность длинного тестирования можно задать свою,
;  а так же совсем отменить. 


OFSF8=400
SYNCW=55000

SCRCRD=160
SCRY=156
SCRFNT=166
SCRLNC=164

LNGTST=400    ;ячейка, где хранится длительность длинного тестирования
DECBUF=410

	.asect
	.=1000

BEG:    MTPS    #340
        MOV        #4,R4
        MOV        #PZP1,(R4)+        ;тест 10/11
        MFPS    (R4)
        MOV        #177716,R5
        MOV        #500,R2
        MOV        #60,(R2)        ;код раб.реж.10
        MOV        #42400,@#177662    ;белая палитра, тут на 10-ке случается прер. по вектору 4
        MOV        #100140,(R2)    ;признак и код раб.реж.11M
        MOV        #16000,(R5)        ;страницы ANDOS
PZP1:    CLR        R1
        MOV        (PC),R0            ;почувств.клав.на 6 МГц: > 40000 SOB
        MOV        #177130,R3
4$:    	MOV        R4,(R3)            ;R4 == строб 6
        MOVB    (PC),(R5)        ;звук (#200)
        MOV        (R2),(R3)        ;станд.режим
        MOV        R1,(R3)            ;строб 0
        MOVB    (PC),(R5)        ;звук (#300)
        MOV        #1000,SP
        SOB        R0,4$

; инициализация
TESTS:    CALL    SETLNT
        MOV        #100,@#177660
        MOV        #DISTRP,@#34
        MFPS    @#36
        TRAP    0
        TRAP    40
        MOV        #TTL,R3
        TRAP    20
        CALL    DETECT
        TST        VALUE1
        BEQ        MEMTS1    ;если после детекта найден контроллер альтпро
        BMI        MEMTS1    ;если прошивка не правильная, тоже тесты проведём, но мы прежупреждали.
        JMP        STOPT    ;иначе тестов памяти делать не будем.
;тесты памяти
MEMTS1:    MOV        #TZPREP,R3
        TRAP    20
;этап1
;1. пробуем все 32 кода страниц независимо от кол-ва памяти, для каждой страницы заполняем массив PGEERR
        CLR        R5
        MOV        #TRST11,@#4
        MOV        #123456,R4
        BR        OTR3
OTR2:    TST        (R5)+
OTR3:    CLR        PGEERR(R5)
        MOV        @#502,R2
        MOV        RAMCOD(R5),R1    ;берем очередной код
        BEQ        MEMTS2
        MOV        #'.,R0
        TRAP    16
        MOV        R1,R0
        TRAP    2            ;устанавливаем нужную страницу
        MOV        R0,R1        ;сохраним исправленный код
        ;проверим, а не подключали ли мы эту страницу ранее
        MOV        #1,R3        ;это признак, когда случился halt, 1 - не было чтения
        MOV        R2,R0
        ;проверим, а не подключали ли ранее
        CMP        (R0)+,R4    ;если нет чтения, тут будет halt ---+
        BEQ        1$            ;                                    |
        NOP                    ;                                    |
        INC        R3            ;2 - не было записи <- сюда --------+
        MOV        R4,(R2)+    ;если нет записи, тут будет halt ---+
        BR        2$            ;                                    |
        NOP                    ;                                    |
        BR        OTR2        ;<- сюда ---------------------------+
2$:        MOV        #17777,R0
3$:        MOV        R1,(R2)+    ;тут будет halt ----+
        SOB        R0,3$        ;                    |
        BR        4$            ;                    |
        BR        OTR2        ;<- сюда -----------+
4$:        ;сюда попадаем если не было halta ни при чтении, ни при записи во всей странице
        ;проведём байт тест
        MOV        R4,R2
        MOV        R2,(R2)        ;допустим, произошёл halt --+
        NOP                    ;                            |
        BR        8$            ;                            |
        BR        9$            ;< - сюда ------------------+
8$:        MOVB    R2,1(R2)    ;допустим, произошёл halt --+
        NOP                    ;                            |
        BR        10$            ;                            |
        BR        9$            ;< - сюда ------------------+
10$:    CMP        #27056,(R2)    ;а здесь halt перейдёт туда ------------+
        BEQ        OTR2    ;байт тест удачно пройден                    |
        NOP            ;байт тест провален                                |
9$:        BIS        #10,PGEERR(R5) ;признак ошибки байт теста < - сюда -+
        BR        OTR2
1$:        BIS        #100000,PGEERR(R5)    ;признак, что страницу уже подключали
        BR        OTR2
;этап2
;2. подсчитываем доступное кол-во ОЗУ
;    для каждой модели имеется набор ожидаемых кодов страниц.
;    выводим на экран ошибки только из этого набора
TRST21:    BIT        (SP)+,(SP)+
        CLR        R1
        BR        HLT
MEMTS2:    CLR        VALUE1
        MOV        #TRST21,@#4
        MOV        #TZDOZU,R3
        TRAP    20
        CLR        R5
        CLR        R1
NEXT1:    MOV        RAMCOD(R5),R0    ;берем очередной код
        BEQ        END0            ;если коды кончились - выход
        TRAP    22                ;выведем кол-во озу
        MOV        #40,R0
        TRAP    16
        MOV        PGEERR(R5),R4    ;проблемы с этой страницей были
        BPL        1$
        ;эту страницу уже подключали
        MOV        R1,-(SP)
        MOV        RAMCOD(R5),R0
        TRAP    2
        MOV        R0,R1
        MOV        #TZ2US1,R3
        TRAP    20
        TRAP    24
        MOV        #TZ2US2,R3
        TRAP    20
        MOV        @#502,R1
        MOV        2(R1),R1        ;код страницы, с которой уже подключали.
HLT:    TRAP    24
        MOV        (SP)+,R1
        BR        NEXT0
1$:        BIT        #1,R4
        BEQ        2$
        ;не было чтения
        MOV        #TZ3RD,R3
        TRAP    20
        MOV        #TZ3HL,R3
        TRAP    20
2$:        BIT        #2,R4
        BEQ        7$
        ;не было записи
        MOV        #TZ3WR,R3
        TRAP    20
        MOV        #TZ3HL,R3
        TRAP    20
7$:        BIT        #10,R4
        BEQ        NEXT0
        ;не пройден байт-тест
        MOV        #TZ3BY,R3
        TRAP    20
NEXT0:    MOV        #TZ2ERC,R3
        TST        R4
        BNE        5$        ;какие-либо ошибки чтения-записи были?
        MOV        #6,R2    ;нет - курсор просто влево.
        TRAP    14
        BR        6$
5$:        TRAP    20        ;вывели ещё сообщение об ошибке, значит делаем перевод строки
        BMI        4$        ;если уже подключали, то не считается
6$:        ADD        #16.,R1    ;увеличим счетчик кб
4$:        TST        (R5)+    ;перемещаемся дальше по таблице
        CMP        R5,TZCN    ;для заданной модели контроллера таблица кончилась?
        BLO        NEXT1    ;если нет - продолжим
END0:    TRAP    22        ;выведем конечное кол-во озу

        CALL    TSTHDD
        CALL    TSTHDR
        CALL    TSTRST
        CALL    TSTBT2
        CALL    TSTBT3

;тест режимов
TREZ:    CALL    MEMTS4    ;заполняем память синхрокодом
        MOV        #7,ZN
        TRAP    40
        MOV        #TRZINF,R3
        TRAP    20
        CLR        ERCOD
        CMPB    @#167777,#374
        BLO        1$    ;если А16, то не проверять HDD ОЗУ
        CMPB    @#167776,#300
        BHIS    1$
        MOV        #240,SMKCON ;для контроллеров SMK там NOP
1$:        MOV        #REZ,R5
        MOV        TZCODS,R4
        MOV        #SYNCW,R2
        MOV        #AH,@#4
        MOV        #277,-(SP)    ;8 реж. * 8 банков

Z1:        MOV        @#500,R0
        BPL        10$
        TRAP    4            ;для БК11М, надо включать стандартный режим,
        MOV        #100000,R1    ;чтобы
        MOV        #20000,R0    ;чистить верхнее ОЗУ, чтобы гарантированно отличить его от 
12$:    CLR        (R1)+        ;ДОЗУ
        SOB        R0,12$        ;это нужно делать каждый раз при смене режима
10$:    MOVB    (R5),R1        ;выводим код режима.
        TRAP    24
        MOV        #':,R0
        TRAP    16
        CLR        VALUE1
        MOV        #100172,R3    ;начальный адрес для проверки
Z2:        MOV        R3,TZADDR
        MOV        #1003,ZC    ;BNE 3$ = норм.!!!
        MOVB    (R5),R0        ;очередной режим
        BNE        7$            ;привязка к коду режима !!!
        TST        @#500
        BMI        7$            ;если БК11 - не надо никаких привязок
        CMP        R3,#120000
        BHIS    7$            ;ПЗУ мон.БК10 может не откл:
        MOV        #240,ZC        ;ПЗУ есть = нет: != == halt
7$:        MOV        R0,TZMODE    ;режим для вывода на экран
        TRAP    4
        CMP        R3,#177172
        BEQ        2$
        INCB    (SP)
        BEQ        ZE
2$:        CLR        R0            ;тут накапливается код результата теста
        CMP        R2,(R3)        ;тестируем, есть ли доступ по чтению
ZC:        BNE        3$
        BEQ        4$
        CMP        (R0)+,(R0)+    ;<-halt сюда для cmp
4$:        CMP        (R0)+,(R0)+
        ;зесь R0 == 0, 4, 010 при !=, =, halt
3$:        MOV        R3,(R3)        ;тестируем, есть ли доступ по записи
        CMP        R2,(R3)        ;тестируем, работает ли запись как надо
        BEQ        6$            ;если запись прошла, но по чтению всё равно изначальный вариант
        NOP                    ;<-halt сюда для mov
        MOV        R2,(R3)        ;<-halt сюда для cmp
        CMP        R2,(R3)
        BR        5$
        BR        1$            ;<-halt сюда для mov
5$:        BNE        6$            ;<-halt сюда для cmp - !=
        INC        R0            ;write
6$:        INC        R0            ;nowr
1$:        CMP        R0,#11        ;для HALT-ОЗУ: R0=11->10
        BNE        7$            ;-
        CMPB    (SP),#327    ;это у нас сегмент 177000 в режиме 120?
        BNE        7$            ;нет
        DEC        R0            ;да, для старой версии прошивки подменяем код с ОЗУзч на ПУСТО
7$:        CMPB    (SP),#366    ;а это сегмент 160000 в режиме 100?
        BNE        SMKCON        ;нет
        CMP        R0,#4        ;да, а схема старая?
        BNE        SMKCON        ;нет, новая
        TST        (R0)+        ;для старой подменяем код ОЗУзз на ОЗУ
SMKCON:    BR        70$
        CMP        R3,#170172
        BNE        70$
        CMPB    (SP),#307    ;сегмент 177000 для режима 160
        BEQ        70$            ;не проверять
        SUB        #1000,R3    ;вот поэтому то у нас и проверяется 2 раза сегмент 17
        MOV        #6,R1
        BR        3$

70$:        MOVB    (R4)+,R1
3$:        CMPB    R0,R1
        BEQ        2$
        MOVB    R0,TRCODE        ;то, что есть - в мл.байт
        MOVB    R1,TRCODE+1        ;то, что должно быть - в ст.байт
        CALL    TRERR
        INC        VALUE1
        INC        ERCOD
2$:        ADD        #10000,R3
        BMI        Z2
        INC        R5
        TST        VALUE1
        BNE        8$
        MOV        #TROK,R3
        TRAP    20
8$:        TRAP    12
        DEC        (PC)+
ZN:        .WORD    7            ;всего 8 режимов
        BPL        Z1
ZE:        TST        ERCOD
        BEQ        11$
        MOV        #ERINFO,R3
        TRAP    20
11$:
;тест режимов 2
;проведем тесты переключения между режимами (20 и 100) и (20 и 0)
;по типу синхротеста.
TREZ2:    TRAP    40
        CMPB    @#167777,#374
        BLO        0MEMTS    ;если А16, то пропустить тест
        MOV        #TRSWPG,R3
        TRAP    20
        MOV        #TRST31,@#4
        MOV        #SWREZ,R4
70$:        MOV        R4,-(SP)
        CALL    MEMTS4    ;заполняем синхротест
        MOV        (SP)+,R4
        MOVB    (R4)+,R0    ;берём первый режим
        TSTB    (R4)
        BMI        MEMTS3
        MOV        R0,R1
        TRAP    4        ;включаем
        TRAP    24        ;рисуем на экране
        MOV        #"->,R0
        TRAP    16
        SWAB    R0
        TRAP    16
        MOVB    (R4),R0    ;берём режим, на который переключаемся
        MOV        R0,TZMODE
        MOV        R0,R1
        TRAP    4        ;включаем
        TRAP    24        ;рисуем на экране
        TRAP    12
        TST        R1
        BNE        1$
        MOV        #TRSKIP,R3
        TRAP    20
        BR        70$
1$:        MOV        @#502,R2
        MOV        #20000,R5
        CALL    SYNCTS    ;синхротест
        TRAP    12
        BR        70$
;этап3
;3. тестируем на сбойность доступное кол-во ОЗУ
;с подробным выводом каждого сбоя в таком виде:
;код - маска адрес:сбойные биты
MEMTS3:    CALL    MEMTS4
0MEMTS:    MOV        #TZERRS,R3
        TRAP    20
        MOV        #MEMTST,R4
        CALL    MEMSSS
        CALL    MEMTS4
        MOV        #TZEST2,R3
        TRAP    20
        MOV        #MEMTSU,R4
        CALL    MEMSSS
        SOB        R3,.
        SOB        R3,.
        SOB        R3,.
        SOB        R3,.
;проверка контрольной суммы.
CRCCHK:    TRAP    40
        MOV        #4,R4
        MOV        #STOPT,(R4)
        MOV        #CRCINF,R3
        TRAP    20
        TRAP    6
        TRAP    20    ;вывод следующего asciz
        CALL    CRC        ;считаем crc
        MOV        R0,R5    ;и преобразуем его в hex-текст
2$:        MOV        #4,R1
        CLR        R2
1$:        ROL        R0
        ROL        R2
        SOB        R1,1$
        ADD        #101,R2
        MOVB    R2,(R3)+
        SOB        R4,2$
        CMP        -(R3),-(R3)
        TRAP    20    ;и выведем его на экран
3$:        MOV        #12,R4
4$:        CALL    CRC
        CMP        R5,R0
        BNE        5$
        SOB        R4,4$
        TRAP    20
        TST        -(R3)
        BR        3$
5$:        CLR        R0
        CALL    ERRR0
        SOB        R0,.
        BR        3$

;-------подпрограммы-
TRST11:    ;обработка halt для подготовительного этапа
        BIS        R3,PGEERR(R5)
AH:        ;обработка halt для теста режимов
        ADD        #4,(SP)
        RTI

MEMSSS:    MOV        #TRST31,@#4
        CLR        R1
NEXT32:    MOV        RAMCOD(R1),R0    ;берем очередной код
        BEQ        END31            ;если коды кончились - выход
        TST        PGEERR(R1)        ;эту страницу уже подключали
        BMI        NEXT31            ;да - ее не тестируем
        MOV        @#502,R2
        MOV        #20000,R5
        TRAP    2
        MOV        R0,TZMODE        ;сохраняем режим, т.к. для вывода на экран нужно включать стандартный режим
4$:        CALL    KEYPRS            ;если кнопка нажата, то может она ещё с прошлого раза нажата.
        BEQ        4$                ;подождём, пока отпустят.
        CALL    SYNCTS            ;синхротест
        CALL    MEMTSS
NEXT31:    TST        (R1)+            ;перемещаемся дальше по таблице
        CMP        R1,TZCN            ;для заданной модели контроллера таблица кончилась?
        BLO        NEXT32            ;если нет - продолжим
END31:    RETURN

;синхротест
SYNCTS:    CALL    MTINF2
        MOV        R1,-(SP)
        MOV        R5,R1
        MOV        R2,R3
        MOV        #SYNCW,R0        ;синхрокод
        MOV        R0,ERT31
2$:        CALL    KEYPRS
        BEQ        SKIP0
        CLR        VALUE1
        CMP        R0,(R3)
        BEQ        1$
        TST        VALUE1        ;если случился halt
        BNE        1$            ;то не надо, уже вывели сообщение об ощибке
        CALL    EROUT2        ;выведем сообщение, что ошибка синхротеста
1$:        INC        R3
        INC        R3
        SOB        R1,2$
SKIP0:    CALL    KEYPRS            ;если кнопка нажата, то может она ещё с прошлого раза нажата.
        BEQ        SKIP0            ;подождём, пока отпустят.
        MOV        (SP)+,R1
        RETURN
        
;если случился halt при тестировании
TRST31:    CALL    EROUT1
TRST30:    RTI                    ;продолжим тесты, как будто ничего не было

MEMTSS:    MOV        #2,R3
        CLR        R0
1$:        COM        R0    ;-1
        CALL    (R4)
        COM        R0    ;0
        CALL    (R4)
        SOB        R3,1$
        MOV        #16.,R3
        INC        R0    ;1
2$:        CALL    (R4)
        ASL        R0
        SOB        R3,2$
        TST        (R3)+ ;2
3$:        CLR        R0
        CALL    (R4)
        COM        R0    ;-1
        CALL    (R4)
        SOB        R3,3$
        MOV        #16.,R3
        DEC        R0    ;-2
4$:        CALL    (R4)
        SEC
        ROL        R0
        SOB        R3,4$
        TST        (R3)+ ;2, R0 = -1
5$:        CALL    (R4)
        COM        R0
        CALL    (R4)
        COM        R0
        SOB        R3,5$
        MOV        #16.,R3    ;R0 = -1
6$:        CALL    (R4)
        CLC
        ROR        R0
        SOB        R3,6$
        MOV        #16.,R3    ;R0 = 0
7$:        CALL    (R4)
        SEC
        ROR        R0
        SOB        R3,7$
        TST        (R3)+ ;2, R0 = -1
8$:        CALL    (R4)
        COM        R0
        CALL    (R4)
        COM        R0
        SOB        R3,8$
;добавляем длительное тестирование
        TST        @#LNGTST
        BEQ        10$
9$:        MOV        #-1,R0
        CALL    RANDOM
        CALL    (R4)
        SOB        R3,9$
10$:    RETURN

MEMTST:    MOV        R3,-(SP)
        MOV        R4,-(SP)
        TRAP    32
        MOV        R5,R4
        MOV        R2,R3
1$:        CALL    KEYPRS
        BEQ        MSKIP
        CLR        VALUE1
        CLR        ERT31
        MOV        R0,(R3)
        INC        ERT31
        CMP        R0,(R3)
        BEQ        70$
        ;случилась ошибка. надо вывести на экран
        TST        VALUE1
        BNE        70$
        CALL    ERROUT
70$:        INC        R3
        INC        R3
        SOB        R4,1$
        BR        0MOUT

MEMTSU:    MOV        R3,-(SP)
        MOV        R4,-(SP)
        TRAP    32
        MOV        R5,R4
        MOV        R2,R3
        CLR        ERT31
1$:        CALL    KEYPRS
        BEQ        MSKIP
        MOV        R0,(R3)
        INC        R3
        INC        R3
        SOB        R4,1$
        MOV        R5,R4
        MOV        R2,R3
        INC        ERT31
2$:        CALL    KEYPRS
        BEQ        MSKIP
        CLR        VALUE1
        CMP        R0,(R3)
        BEQ        70$
        ;случилась ошибка. надо вывести на экран
        TST        VALUE1
        BNE        70$
        CALL    ERROUT
70$:        INC        R3
        INC        R3
        SOB        R4,2$
0MOUT:    MOV        (SP)+,R4
        MOV        (SP)+,R3
        RETURN
MSKIP:    MOV        (SP)+,R4
        MOV        (SP)+,R3
        TST        (SP)+
        RETURN

ERRR0:    MOV        R3,-(SP)
        MOV        R1,-(SP)
        MOV        R0,-(SP)
        MOV        #TERR,R3
        TRAP    20
        MOV        SP,R3
        TRAP    20
        MOV        (SP)+,R0
        MOV        (SP)+,R1
        MOV        (SP)+,R3
        RETURN

;новый вид вывода сообщений об ошибках
;такого вида Segment-Code(Code) - в скобках то, что должно быть
TRERR:    ;портит R0,R1
        MOV        TZADDR,R1    ;адрес, из которого получаем номер сегмента по 10000 байт
        SWAB    R1
        ASR        R1
        ASR        R1
        ASR        R1
        ASR        R1
        BIC        #177760,R1    ;сегмент
        MOV        #26440,R0
        TRAP    16
        TRAP    10
        SWAB    R0
        TRAP    16
        MOV        TRCODE,R1    ;код, то что есть
        MOV        R1,-(SP)
        CLRB    (SP)        ;ст.байт - то, что должно быть
        BIC        (SP),R1        ;мл байт - то, что есть
        TRAP    10
        MOV        #"(),R0
        TRAP    16
        MOV        (SP)+,R1    ;код, то что должно быть
        SWAB    R1
        TRAP    10
        SWAB    R0
        TRAP    16
        RETURN

;подготовительный этап перед 3м этапом
;идея в том, чтобы заполнить все страницы памяти определённым кодом,
;чтобы отловить ошибку следующего вида: пишем в одну ячейку памяти,
;а меняются данные в какой-то другой ячейке в другой странице.
MEMTS4:    CLR        R5
        MOV        #SYNCW,R4
        MOV        #TRST30,@#4
11$:    MOV        @#502,R2
        MOV        RAMCOD(R5),R0    ;берем очередной код
        BEQ        10$
        TST        PGEERR(R5)    ;если на странице были ошибки
        BNE        12$            ;то её пропустим
        TRAP    2            ;устанавливаем нужную страницу
        MOV        #20000,R1
13$:    MOV        R4,(R2)+
        SOB        R1,13$
12$:    TST        (R5)+
        CMP        R5,TZCN
        BLO        11$
10$:    RETURN

MTMIN2:    TRAP    24        ;выведем код страницы, текущего режима
        MOV        #" -,R0
        TRAP    16
        SWAB    R0
        TRAP    16
        SWAB    R0
        TRAP    16
        MOV        R5,R1
        TRAP    30        ;выведем маску
        RETURN

MTMIN3:    TRAP    24        ;выведем код страницы, текущего режима
        MOV        #TZSYN1,R3
        TRAP    20
        RETURN

;вывод инфы о текущем режиме тестирования
MTINFO:    JSR        R5,PUSHA
        MOV        R0,R5
        MOV        TZMODE,R1
        TRAP    34
        BR        EROUE3

;вывод инфы о синхропоследовательности
MTINF2:    JSR        R5,PUSHA
        MOV        TZMODE,R1
        TRAP    36
EROUE3:    MOV        #15,R0
        TRAP    16
        BR        EROUE2
;вывод сообщения от ошибке синхропоследовательности
;на входе
;r3 - адрес, где случилась ошибка
EROUT2:    JSR        R5,PUSHA
        MOV        TZMODE,R1
        MOV        R3,-(SP)     ;адрес с ошибкой
        TRAP    36
        MOV        (SP),R1        ;выведем адрес, где случилась ошибка
        TRAP    26
        MOV        #':,R0
        TRAP    16
        MOV        @(SP)+,R1    ;выведем неправильное значение
        TRAP    26
        MOV        #TZSYNF,R3
        TRAP    20
        BR        EROUEN
;на входе
;r0 - маска, с которой случилась ошибка
;r3 - адрес, где случилась ошибка
ERROUT:    JSR        R5,PUSHA
        MOV        R0,R5    ;что должно быть
        MOV        TZMODE,R1
        MOV        (R3),-(SP)    ;что есть
        MOV        R3,-(SP) ;адрес с ошибкой
        TRAP    34
        MOV        #" :,R0
        TRAP    16            ;выведем ' '
        MOV        (SP)+,R1    ;выведем адрес, где случилась ошибка
        TRAP    26
        SWAB    R0
        TRAP    16            ;выведем ':'
        MOV        (SP)+,R1
        TRAP    30            ;выведем то, что прочлось
        BR        EROUEN

;обработка ошибки по halt.
;r3 - адрес, где случилась ошибка
EROUT1:    INC        VALUE1    ;признак halt 
        JSR        R5,PUSHA
        MOV        R0,R5    ;что должно быть
        MOV        TZMODE,R1
2$:        MOV        R3,-(SP) ;адрес с ошибкой
        TRAP    34
        MOV        #" :,R0
        TRAP    16            ;выведем ' '
        MOV        (SP)+,R1    ;выведем адрес, где случилась ошибка
        TRAP    26
        SWAB    R0
        TRAP    16            ;выведем ':'
        MOV        #TZ3WR,R3
        TST        ERT31
        BEQ        70$
        MOV        #TZ3RD,R3
70$:        TRAP    20
        MOV        #TZ3HL,R3
        TRAP    20
EROUEN:    MOV        #12,R0
        TRAP    16            ;перевод строки
EROUE2:    RETURN

SETPGE:    TST        @#500    ;БК11?
        BPL        VKL        ;нет
        BIC        #40,R0    ;да
VKL:    MOV        R0,CURMOD
VKL0:    MOV        @#4,VV4BUF
        MOV        #TRST30,@#4    ;прер по вектору 4 просто будем игнорировать.
        MOV        R0,@#177716
        MOV        #6,@#177130
        MOV        R0,@#177130
        MOV        #0,@#177130
        CLR        @#177716
        MOV        VV4BUF,@#4
        RETURN
VV4BUF:    .WORD    0    ;буфер сохранения вектора 4
CURMOD:    .WORD    0

VKLSTD:    MOV        R0,-(SP)
        MOV        @#500,R0
        TRAP    4
        MOV        (SP)+,R0
        RETURN

;выход из теста CRC по кнопке стоп
STOPT:    MOV        @#506,@#4
        MOV        #1000,SP
        TRAP    40
        MOV        #ENDTST,R3
        TRAP    20
        TRAP    6        ;ждём нажатия клавини
                        ;выходим
        HALT

ZAGR:    CALL    @#150170    ;БК11М - выход в клавиатурный монитор
        EMT        0
        EMT        1
        HALT

INIT:    MOV        #500,R1
        MOV        (R1)+,R0
        BPL        2$
        MOV        #100000,(R1)+    ;адр.нач.ОЗУ - 11M
        TST        (R1)+    ;SCR.INIT
        MOV        #ZAGR,(R1)        ;для вых.в MON
        MOV        #16000,@#114    ;как в ANDOS
        BR        1$

2$:        MOV        #120000,(R1)+    ;10
        TST        (R1)+
        MOV        #100274,(R1)
1$:        TRAP    4
        CALL    SCRINI
        RETURN

EMT6:    CALL    KEYPRS
        BNE        EMT6
        MOVB    @#177662,R0
        RETURN
KEYPRS:    BIT        #100,@#177716
        RETURN

JIRN:    MOV        R2,-(SP)
        MOV        R5,-(SP)
3$:        MOVB    (R3)+,R0    ;Портит R0
        BEQ        1$
        CMPB    R0,#220        ;200-220 - повтор 1-20,100 раз
        BGT        4$
        BLT        6$
        MOVB    #277,R0        ;полная строка !!!
6$:        MOVB    R0,R2
        CLR        -(SP)
        MOVB    (R3)+,(SP)
        MOV        R3,R5
5$:        MOV        SP,R3
        CALL    JIRN
        DECB    R2
        BMI        5$
        MOV        R5,R3
        TST        (SP)+
        BR        3$
4$:        CALL    PUTCH
        BR        3$
1$:        MOV        (SP)+,R5
        MOV        (SP)+,R2
        RETURN

;двигаем курсор на заданное количество раз влево,
;R2 - количество раз
CURLT:    MOV        #10,R0
7$:        TRAP    16
        SOB        R2,7$
        RETURN

TTIM:    MOV        R2,2(R5)    ;тест таймера
        MOV        R2,R0
        CALL    (R2)
        MOV        (R5),R0
        RETURN

CRC:    MOV        #160000,R1
        MOV        #4000,R2
        CLR        R0
70$:        ADD        (R1)+,R0
        ADC        R0
        SOB        R2,70$
        RETURN

;вывод в бинарном виде
;вход - R1 число
BINOUT:    JSR        R5,PUSHA
        MOV        #16.,R2
70$:        MOV        #30,R0
        ASL        R1
        ROL        R0
        TRAP    16
        SOB        R2,70$
        RETURN

;вывод числа из R1, без подавления ведущих нулей
D6OUT3:    JSR        R5,PUSHA
        MOV     #6,R4    ;максимальное кол-во цифр в числе
        BR        DGOUT$
;вывод 4-х значного числа из R1, без подавления ведущих нулей
D4OUT3:    JSR        R5,PUSHA
        MOV     #4,R4    ;максимальное кол-во цифр в числе
DGOUT$:    MOV        R4,R5    ;счетчик цифр
70$:        MOV     R1,R0
        BIC     #177770,R0    ;получим очередную цифру
        ADD     #'0,R0
        MOV     R0,-(SP)    ;в стек ее
        ROR     R1        ;пододвинем следующую, ADD бит С обнуляет, так что можно
        ASR     R1
        ASR     R1        ;цифры остались?
        SOB     R4,70$
1$:        MOV     (SP)+,R0
        TRAP    16
        SOB     R5,1$
        RETURN
;вывод десятичного числа с подавлением ведущих нулей
;вход:  R1 - число
DECOUT: JSR        R5,PUSHA
        CLR        R5
        MOV        #CONST,R2
6$:        CLR        R0
        MOV        (R2)+,R4
        BEQ        2$
1$:        SUB        R4,R1
        BCS        70$
        INC        R0
        BR        1$
70$:        ADD        R4,R1
        BIS        R0,R5
        BNE        4$
        CMP        #1,R4
        BEQ        4$
        MOV        #-20,R0    ;вместо ведущих нулей будем рисовать пробелы.
4$:        ADD        #'0,R0
        TRAP    16
        BR        6$
2$:        RETURN

;вывод числа из R1, с подавлением ведущих нулей
DGOUT:    JSR        R5,PUSHA
        MOV     #6,R4    ;максимальное кол-во цифр в числе
        CLR        R5        ;счетчик цифр
70$:        MOV     R1,R0
        BIC     #177770,R0    ;получим очередную цифру
        ADD     #'0,R0
        MOV     R0,-(SP)    ;в стек ее
        INC        R5
        ROR     R1        ;пододвинем следующую, ADD бит С обнуляет, так что можно
        ASR     R1
        ASR     R1        ;цифры остались?
        BEQ        1$        ;кончились - выход, если число отрицательное, то мы отработает все 6 цифр.
        SOB     R4,70$
1$:        MOV     (SP)+,R0
        TRAP    16
        SOB     R5,1$
        RETURN

;диспетчер трап
;сохранение регистров на совести подпрограмм
DISTRP:    MOV        (SP),-(SP)
        SUB        #2,(SP)
        MOV        @(SP)+,-(SP)
        BIC        #177401,(SP)    ;номера трапов только чётные, так мы экономим 1 слово
        ADD        #TRPTBL,(SP)
        MOV        @(SP)+,-(SP)
        CALL    @(SP)+
        RTI
TRPTBL:    .WORD    INIT    ;0
        .WORD    SETPGE    ;2
        .WORD    VKL        ;4
        .WORD    EMT6    ;6
        .WORD    DGOUT    ;10
        .WORD    OUTCR    ;12
        .WORD    CURLT    ;14
        .WORD    PUTCH    ;16
        .WORD    JIRN    ;20
        .WORD    DECOUT    ;22
        .WORD    D4OUT3    ;24
        .WORD    D6OUT3    ;26
        .WORD    BINOUT    ;30
        .WORD    MTINFO    ;32
        .WORD    MTMIN2    ;34
        .WORD    MTMIN3    ;36
        .WORD    VKLSTD    ;40

;вызов так: jsr r5,pusha, сохраняем все регистры
;но в r5 нельзя передать параметр, чтобы было можно, есть более сложный метод
PUSHA:    MOV        R4,-(SP)
        MOV        R3,-(SP)
        MOV        R2,-(SP)
        MOV        R1,-(SP)
        MOV        R0,-(SP)
        ;MOV    R5,-(SP) ;это - чтобы и в r5 можно было
        ;MOV    14(SP),R5    ;передавать параметры
        ;CALL    @(SP)+
        CALL    (R5)
        MOV        (SP)+,R0
        MOV        (SP)+,R1
        MOV        (SP)+,R2
        MOV        (SP)+,R3
        MOV        (SP)+,R4
        MOV        (SP)+,R5
        RETURN

;собственный знакогенератор
;инициализация экрана
SCRINI:    MOV        #40000,R1
        MOV        R1,R0
        MOV        R1,@#SCRCRD
        CLR        @#SCRY    ;Y координата, для рулонного сдвига
        CLR        @#SCRLNC ;счётчик строк
        MOV        #1330,@#177664
1$:        CLRB    (R1)+
        SOB        R0,1$
        MOV        #FONT8,R0
        SUB        #OFSF8,R0
        MOV        R0,@#SCRFNT
        RETURN

OUTCR:    MOV        #12,R0
PUTCH:  JSR        R5,PUSHA
        CALL    VKLSTP
        BIC        #177400,R0
        BITB    #140,R0
        BNE        1$
        ;обрабатываем спецсимволы
        MOV        @#SCRCRD,R3
        CMP        #15,R0
        BNE        23$
        BIC        #77,R3
        BR        31$
23$:        CMP        #12,R0
        BNE        21
        BIC        #77,R3
        BR        22$
21$:        CMP        #10,R0
        BNE        20$
        BIT        #77,R3
        BEQ        20$
        DEC        @#SCRCRD
        BR        20$
1$:        TSTB    R0
        BPL        2$
        SUB        #40,R0
2$:        ASL        R0
        ;MOV    R0,R2
        ASL        R0
        ASL        R0
        ;ADD    R2,R0
        ADD        @#SCRFNT,R0
        MOV        #10,R2
        MOV        @#SCRCRD,R1
        MOV        R1,R3
3$:        MOVB    (R0)+,(R1)
        ADD    #100,R1
        BPL        4$
        SUB        #40000,R1
4$:        SOB        R2,03
        ;двигаем адрес вывода
5$:        MOV        R3,R1
        MOV        #177700,R0
        BIC        R0,R1
        COM        R0
        CMP        R1,R0    ;дошли до конца строки?
        BHIS    10$        ;да, надо делать перевод строки
        INC        @#SCRCRD ;нет, просто на следующую позицию вправо
        BR        20$
10$:        BIC        R0,R3
22$:        INC        @#SCRLNC
        ADD        #1000,R3    ;высота символов 8 точек
        BPL        11$
        SUB        #40000,R3    ;это новая координата
11$:        MOV        R3,R2        ;если делать рулонный сдвиг, то прежде надо будет очистить от старого текста
        CMP        @#SCRY,#37    ;Если мы в самом низу
        BHIS    13$            ;то увеличивать координату больше не надо
        INC        @#SCRY        ;иначе увеличим
        BR        31$
13$:        ;делаем рулонный сдвиг
        MOV        @#177664,R0
        BIC        #177400,R0
        MOV        #10,R1        ;высота символов 8 точек
15$:        MOV        #40,R4
14$:        CLR        (R2)+
        SOB        R4,14
        TST        R2
        BPL        16$
        SUB        #40000,R2
16$:        INCB    R0
        BIS        #1000,R0
        MOV        R0,@#177664
        SOB        R1,15
31$:        MOV        R3,@#SCRCRD
        CMP        @#SCRLNC,#37
        BLT        20$
        MOV        #-1,@#SCRLNC
        MOV        #PRANYK,R3
        CALL    JIRN
32$:        CALL    KEYPRS
        BNE        32$
        TST        @#177662
33$:        CALL    KEYPRS
        BEQ        33$
        CALL    OUTCR
20$:
RETVKL:    MOV        R0,-(SP)
        MOV        CURMOD,R0
        BR        00VKL
VKLSTP:    MOV        R0,-(SP)
        MOV        @#500,R0
00VKL:    CALL    VKL0
        MOV        (SP)+,R0
        RETURN

;rnd генератор.
;вход: R0 - макс.значение
;выход: R0 - результат
RANDOM:    MOV        R1,-(SP)
        MOV        R2,-(SP)
        CALL    FRN
        MOV        R0,R1
        CLR        R2
        MOV        RAN,R0
        SEC
3A:        BIC        R2,R0
        ROR        R2
        CMP        R0,R1
        BHI        3A
        MOV        (SP)+,R2
        MOV        (SP)+,R1
        RETURN
FRN:    SWAB    (PC)+
RAN:    .WORD    0
        INCB    RAN
        ROLB    RAN+1
MM:        ADD        #0,RAN
        ADD        #3337,MM+2
        RETURN


DETECT:    TST        @#500        ;чтобы тест нельзя было запустить
        BPL        20$            ;повторно
        MOV        #140000,R0    ;сделаем переход на 
        BR        21$            ;выход в монитор
20$:    MOV        #100000,R0    ;потому что, этот кусок кода используется только один раз в начале
21$:    MOV        #137,@#1000    ;а затем затирается оперативными данными
        MOV        R0,@#1002
        ;определяем тип контроллера и кол-во памяти по значению в 167776
        CLR        VALUE1    ;флаг, что не найден контроллер альтпро
        CLR        SMKHDD
        MOV        @#167776,R5    ;в мл. байте версия прошивки
        MOV        R5,R0
        CLRB    R0
        BIC        R0,R5
        SWAB    R0            ;в мл байте код количества памяти
        CMPB    R0,#370
        BLO        70$
        MOV        #CODES,R3
        CLR        R4
2$:        TSTB    (R3)
        BEQ        70$
        CMPB    R0,(R3)+
        BEQ        1$
        INC        R4
        BR        2$

70$:        MOV        #NOALTP,R3
        TRAP    20
        INC        VALUE1
        RETURN

1$:        ;нашли
        MOV        #4,R3
        CMP        R4,R3    ;для а16 нечего делать
        BLO        3$        ;а если smk или a64m, надо определить, что это
        CMPB    R5,#300
        BHIS    3$
        COM        SMKHDD
        ADD        R3,R4
3$:        ASL        R4
        MOV        #FOUND,R3
        TRAP    20
        MOV        TZCTB(R4),TZCN
        MOV        NMTBL(R4),R3
        TRAP    20    ;выведем имя контроллера
        MOV        #VERS,R3
        TRAP    20    ;выведем версию, в нечеловекообразном виде
        MOV        R5,R1
        TRAP    10
        TRAP    12        ;вывели всё. теперь надо переходить к тестам
        ;теперь проверим какая прошивка, будем просто использовать кусок теста режимов.
        CMP        R4,#10    ;если это не СМК
        BLO        15$        ;то прошивку проверять не надо
        TST        @#500
        BPL        17$
        MOV        #CODS11,TZCODS
        BR        18$
17$:    MOV        #CODS,TZCODS
18$:    MOV        #AH,@#4
        MOV        #100,R0        ;код режима
        MOV        #SYNCW,R2    ;проверочное слово
        MOV        #160172,R3    ;адрес для проверки
        CLR        R5
        CALL    DTOLD
        CMP        #4,R0
        BNE        10$
        INC        R5
10$:    MOV        #120,R0
        MOV        #177172,R3
        CALL    DTOLD
        CMP        #11,R0
        BNE        11$
        INC        R5
11$:    MOV        #VERRT,R3
        TRAP    20
        TST        R5
        BNE        12$
        MOV        #RTOK,R3
        BR        14$
12$:    COM        VALUE1        ;отметим, что прошивка неправильная
        CMP        #2,R5
        BNE        13$
        MOV        #RTBAD,R3
        BR        14$
13$:    MOV        #RTERR,R3
14$:    TRAP    20
        RETURN
15$:    TST        @#500
        BPL        16$
        MOV        #CODA11,TZCODS
        RETURN
16$:    MOV        #CODA,TZCODS
        RETURN

DTOLD:    MOV        R0,-(SP)
        MOV        #20,R0        ;включаем режим 20, чтобы вписать куда нужно проверочное слово
        TRAP    4            ;чтобы алгоритм из теста режимов срабатывал стандартно
        MOV        R2,-40000(R3)
        MOV        (SP)+,R0
        TRAP    4            ;устанавливаем нужный режим
        CLR        R0            ;тут накапливается код результата теста
        CMP        R2,(R3)        ;тестируем, есть ли доступ по чтению
        BNE        3$
        BEQ        4$
        CMP        (R0)+,(R0)+    ;<-halt сюда для cmp
4$:        CMP        (R0)+,(R0)+
        ;зесь R0 == 0, 4, 010 при !=, =, halt
3$:        MOV        R3,(R3)        ;тестируем, есть ли доступ по записи
        CMP        R2,(R3)        ;тестируем, работает ли запись как надо
        BEQ        6$            ;если запись прошла, но по чтению всё равно изначальный вариант
        NOP                    ;<-halt сюда для mov
        MOV        R2,(R3)        ;<-halt сюда для cmp
        CMP        R2,(R3)
        BR        5$
        BR        1$            ;<-halt сюда для mov
5$:        BNE        6$            ;<-halt сюда для cmp - !=
        INC        R0            ;write
6$:        INC        R0            ;nowr
1$:        RETURN

TSTHDD:    TRAP    40
        MOV        #THINFO,R3
        TRAP    20
        TST        SMKHDD
        BNE        0OK
        MOV        #THERR,R3
        TRAP    20
        RETURN

0OK:    MOV        #AH,@#4
        MOV        #REGHDD,R5
        MOV        #377,R4
03$:    MOV        (R5)+,R1
        BEQ        0EX
        TRAP    10
        MOV        #": ,R0
        TRAP    16
        SWAB    R0
        TRAP    16
        MOV        #THRESL,R3
        MOV        R4,(R1)
        BR        00$
        NOP
        BR        01$
00$:    CMP        (R1),R4
        BR        02$
        NOP
        BR        01$
02$:    TST        (R3)+
01$:    TRAP    20
        BR        03$
0EX:    RETURN
REGHDD:    .WORD 177740,177742,177744,177746,177750,177752,177754,177756,177741,177743,0

;тест ОЗУ, выделенного под буфер HDD
TSTHDR:    TRAP    40
        MOV        #THINF2,R3
        TRAP    20
        TST        SMKHDD
        BNE        0OK
        MOV        #THERR,R3
        TRAP    20
        RETURN
;подготовим контрольный массив
0OK:    MOV        #30000,R5
        MOV        #3400,R4
        MOV        R5,R1
        MOV        R4,R2
        MOV        #123456,R0
        MOV        #65432,R3
2:        MOV        R0,(R1)+
        XOR        R0,R3
        ROL        R3
        ROR        R0
        ADC        R3
        BCC        1
        SWAB    R0
1:        ROL        R3
        ROR        R0
        ADC        R3
        BCC        0
        SWAB    R3
0:        ADD        R3,R0
        SOB        R2,2
;посчитаем его CRC
;и заодно скопируем в буфер ОЗУ HDD
        MOV        #TH4TR,@#4
        MOV        R5,R1
        MOV        R4,R2
        MOV        #170000,R3
        CLR        R0
70$:        MOV        (R1),(R3)+
        ADD        (R1)+,R0
        ADC        R0
        SOB        R2,70$
        MOV        R0,R5
        MOV        #160,R0
        TRAP    4
        SOB        R2,.
        TRAP    40
        MOV        #170000,R1
        MOV        R4,R2
        CLR        R0
1$:        ADD        (R1)+,R0
        ADC        R0
        SOB        R2,1$
        MOV        #THROK,R3
        CMP        R0,R5
        BEQ        2$
        MOV        #THRER,R3
        BR        2$
TH4TR:    BIT        (SP)+,(SP)+
        MOV        #THRERN,R3
2$:        TRAP    20
        RETURN

TSTRST:    ;тест влияния ресета
        MOV        #TRINFO,R3
        TRAP    20
;1. Заполним каждую страницу своим уникальным кодом.
        CALL    MEMFIL    ;ну, почти всю страницу, одного слова в одном месте достаточно
;2. Включаем стандартный режим
        TST        @#500
        BMI        011
        MOV        #120,R0
        TRAP    4
        BR        010

011:    MOV        #140,R0
        TRAP    4
        MOV        #16000,@#177716
        MOV        #100000,R1
        MOV        #20000,R0
10$:    CLR        (R1)+
        SOB        R0,10$
010:
;3. Запоминаем, что было
        CALL    RDCRD
;4. Делаем ресет
        RESET
;5. Смотрим, что стало
        CALL    RDRES
;Вывод результатов
        MOV        #ADDRSS,R5
        MOV        #DTAB,R4
12$:    MOV        (R5)+,R1
        BEQ        11$
        MOV        #TADDR,R3
        TRAP    20
        TRAP    26
        CMP        DTAA-DTAB(R4),(R4)+
        BNE        13$
        CMP        DTAA-DTAB(R4),(R4)+
        BNE        14$
        MOV        #TANRM,R3
        TRAP    20
        BR        12$
14$:    MOV        -2(R4),R1
        BR        15$
13$:    MOV        (R4),R1
15$:    MOV        #TAERR,R3
        TRAP    20
        TRAP    10
        MOV        #12,R0
        TRAP    16
        BR        12$
11$:    MOV        #TRRSOK,R3
        TST        VALUE1
        BEQ        16$
        MOV        #TRRSER,R3
16$:    TRAP    20
        MOV        #TRRSTL,R3
        TRAP    20
        RETURN

RDRES:    MOV        #DTAA,R2
        BR        0RD
RDCRD:    MOV        #DTAB,R2
0RD:    MOV        #ADDRSS,R1
1:        MOV        (R1)+,R0
        BEQ        0
        MOV        (R0)+,(R2)+
        MOV        (R0)+,(R2)+
        BR        1
0:        RETURN

ADDRSS:    .WORD    100000,120000,140000,160000,0

MEMFIL:    CLR        R5
        MOV        #SYNCW,R4
        MOV        #TRST30,@#4
11$:    MOV        @#502,R2
        MOV        RAMCOD(R5),R0    ;берем очередной код
        BEQ        10$
        TST        PGEERR(R5)    ;если на странице были ошибки
        BNE        12$            ;то её пропустим
        TRAP    2            ;устанавливаем нужную страницу
        MOV        #123456,(R2)+
        MOV        R0,(R2)+
        MOV        #17776,R1
13$:    MOV        R4,(R2)+
        SOB        R1,13$
12$:    TST        (R5)+
        CMP        R5,TZCN
        BLO        11$
10$:    RETURN

;тест влияния бита 2
;код 4 блокирует регистры по чтению.
TSTBT2:    MOV        #T2INFO,R3
        TRAP    20
        MOV        #TR4T2,@#4
        MOV        #REZ,R5
1$:        MOVB    (R5)+,R0    ;проверим во всех режимах
        BMI        70$
        TRAP    4
        MOV        #4,@#177130 ;блокируем регистры по чтению
        CLR        VALUE1
        TST        @#177130
        TST        @#177132
        BR        1$

70$:        MOV        #T21,R5
        TST        VALUE1    ;блокируется?
        BEQ        03        ;нет
        MOV        #T2OK,R3    ;да, скажем что ОК
        TRAP    20
        MOV        R5,R3        ;регистры
        TRAP    20
        MOV        #T23,R3    ;блокируются
        TRAP    20
        RETURN
03:        MOV        #T2ERR,R3    ;нет, скажем что ошибка
        TRAP    20
        MOV        R5,R3        ;регистры
        TRAP    20
        MOV        #T22,R3    ;должны блокироваться
        TRAP    20
        RETURN

TR4T2:    INC        VALUE1
        RTI

TSTBT3:    MOV        #T3INFO,R3
        TRAP    20
        TST        @#500
        BPL        0OK
        MOV        #T3NONE,R3
        TRAP    20
        RETURN

0OK:    CALL    MEMFIL
        MOV        #VALUE1,R3
        CLR        (R3)
        MOV        #TR4T2,@#4
        MOV        #SYNCW,R4
        MOV        #120,R0
        TRAP    4
        MOV        #10,@#177130    ;подключаем бейсик, при этом ПЗУ накладывается на ОЗУ,
                                ; и при записи туда должен возникать trap to 4, но не факт.
                                ;ОЗУ может выдать RPLY и ничего не сработает.

        MOV        #120010,R5
        CMP        (R5),R4            ;на случай не срабатывания trap to 4
        BEQ        70$                ;просто провека на контрольное значение
        INC        (R3)
70$:        CLR        (R5)
        ADD        #40000,R5
        CMP        (R5),R4
        BEQ        1$
        INC        (R3)
1$:        CLR        (R5)
        ;теперь второй вариант.
        ;в режиме 140 по адресам 120000-160000 ничего нет.
        ;и если бейсик подключается, там должно работать чтение
        MOV        #AH,@#4
        MOV        #140,R0
        TRAP    4
        MOV        #10,@#177130
        MOV        #120020,R5
        TST        (R5)
        INC        (R3)    ;чтение произошло
        NOP                ;значит бейсик подключается
        ADD        #20000,R5    ;если чтения нет, halt сюда
        TST        (R5)
        INC        (R3)
        NOP
        CMP        TZCN,#C128-RAMCOD
        BLO        01        ;реакция в норме, должно накладываться
        ;не должно.
        TST        VALUE1
        BEQ        02
        MOV        #T2ERR,R3
        BR        05

02:        MOV        #T2OK,R3
        BR        04

01:        TST        VALUE1
        BEQ        03
        MOV        #T2OK,R3
05:        TRAP    20
        MOV        #T31+3,R3
        TRAP    20
        RETURN

03:        MOV        #T2ERR,R3
04:        TRAP    20
        MOV        #T31,R3
        TRAP    20
        RETURN

;-------константы--------------------------
NMTBL:    .WORD    NA16
        .WORD    NA16H
        .WORD    NA16M
        .WORD    NAUNK
        .WORD    NA64M
        .WORD    NA128M
        .WORD    NA256M
        .WORD    NA512M
        .WORD    NS64
        .WORD    NS128
        .WORD    NS256
        .WORD    NS512
CONST:    .WORD    10000.,1000.,100.,10.,1,0
FREQ:    .WORD    2561,2457,2252,177777    ;знач.таймера, последний < 0 !!!
TZCODS:    .WORD    CODS11
;коды ошибок теста режимов для SMK. по 8 байт на режим
CODS:    .BYTE    00,00,06,06,06,06,00,00    ;160
        .BYTE    00,00,06,06,06,06,00,10    ;60
        .BYTE    06,06,06,06,06,06,06,10    ;120
        .BYTE    06,06,06,06,06,06,06,04    ;20
        .BYTE    00,00,10,10,10,10,00,10    ;140
        .BYTE    00,00,10,10,06,06,06,10    ;40
        .BYTE    04,06,06,06,06,06,06,11    ;100
        .BYTE    10,10,10,10,06,06,06,11    ;0

CODS11:    .BYTE    10,10,06,06,06,06,00,00    ;160
        .BYTE    10,10,06,06,06,06,00,10    ;60
        .BYTE    06,06,06,06,06,06,06,10    ;120
        .BYTE    06,06,06,06,06,06,06,04    ;20
        .BYTE    02,02,02,02,00,00,00,10    ;140
        .BYTE    02,02,02,02,06,06,06,10    ;40
        .BYTE    05,06,06,06,06,06,06,11    ;100
        .BYTE    02,02,02,02,06,06,06,11    ;0
;для А16
CODA:    .BYTE    00,00,06,06,06,06,00,00    ;160
        .BYTE    00,00,06,06,06,06,00,10    ;60
        .BYTE    06,06,06,06,10,10,00,10    ;120
        .BYTE    04,06,10,10,10,10,10,10    ;20
        .BYTE    00,00,10,10,10,10,00,10    ;140
        .BYTE    00,00,10,10,06,06,06,10    ;40
        .BYTE    04,06,06,06,10,10,00,10    ;100
        .BYTE    10,10,10,10,06,06,06,11    ;0

CODA11:    .BYTE    10,10,06,06,01,01,00,00    ;160
        .BYTE    10,10,06,06,06,06,00,10    ;60
        .BYTE    06,06,06,06,00,00,00,10    ;120
        .BYTE    04,06,10,10,10,10,10,10    ;20
        .BYTE    02,02,02,02,00,00,00,10    ;140
        .BYTE    02,02,02,02,06,06,06,10    ;40
        .BYTE    05,06,06,06,00,00,00,10    ;100
        .BYTE    02,02,02,02,06,06,06,11    ;0

REZ:    .BYTE    160,60,120,20,140,40,100,0
SWREZ:    .BYTE    120,20,120,100,20,100,0,20,0,377

TZCN:    .WORD C512-RAMCOD
;коды для подключения страниц памяти
RAMCOD:    .WORD 160    ;0     (код 0)
C016:    .WORD 60
C032:    .WORD 2160    ;+32Кб (код 2000)
        .WORD 2060
C064:    .WORD 164    ;+64Кб (код 4)
        .WORD 64
        .WORD 2164    ;+96Кб (код 2004)(64+32)
        .WORD 2064
C128:    .WORD 170    ;+128Кб (код 10)
        .WORD 70
        .WORD 2170    ;+160Кб (код 2010)(128+32)
        .WORD 2070
        .WORD 174    ;+192Кб (код 14)(128+64)
        .WORD 74
        .WORD 2174    ;+224Кб (код 2014)(128+64+32)
        .WORD 2074
; это для 512Кб (вторая половина)
C256:    .WORD 161    ;+256Кб (код 1)
        .WORD 61
        .WORD 2161    ;+288Кб (код 2001)(256+32)
        .WORD 2061
        .WORD 165    ;+320Кб (код 5)(256+64)
        .WORD 65
        .WORD 2165    ;+352Кб (код 2005)(256+64+32)
        .WORD 2065
        .WORD 171    ;+384Кб (код 11)(256+128)
        .WORD 71
        .WORD 2171    ;+416Кб (код 2011)(256+128+32)
        .WORD 2071
        .WORD 175    ;+448Кб (код 15)(256+128+64)
        .WORD 75
        .WORD 2175    ;+480Кб (код 2015)(256+128+64+32)
        .WORD 2075
C512:    .WORD 0

TZCTB:    .WORD    C016-RAMCOD
        .WORD    C016-RAMCOD
        .WORD    C016-RAMCOD
        .WORD    C016-RAMCOD
        .WORD    C064-RAMCOD
        .WORD    C128-RAMCOD
        .WORD    C256-RAMCOD
        .WORD    C512-RAMCOD
        .WORD    C064-RAMCOD
        .WORD    C128-RAMCOD
        .WORD    C256-RAMCOD
        .WORD    C512-RAMCOD

;коды в ячейке 167777, определяющие тип контроллера
CODES:    .BYTE    370    ;A16
        .BYTE    371    ;A16+контроллера винта с дозу 4кб
        .BYTE    372    ;A16M
        .BYTE    373    ;не исп-ся
        .BYTE    374    ;SMK64 или A64M
        .BYTE    375    ;SMK128 или A128M
        .BYTE    376    ;SMK256 или A256M
        .BYTE    377    ;SMK512 или A512M
        .BYTE    0
;имена контроллеров
NA16:    .ASCIZ    "A16"
NA16H:    .ASCIZ    "A16HDD"
NA16M:    .ASCIZ    "A16M"
NAUNK:    .ASCIZ    "Несуществующий"
NA64M:    .ASCIZ    "A64M"
NA128M:    .ASCIZ    "A128M"
NA256M:    .ASCIZ    "A256M"
NA512M:    .ASCIZ    "A512M"
NS64:    .ASCIZ    "SMK64"
NS128:    .ASCIZ    "SMK128"
NS256:    .ASCIZ    "SMK256"
NS512:    .ASCIZ    "SMK512"
NOALTP:    .ASCIZ    "Не обнаружен контроллер АльтПро"<12>
FOUND:    .ASCIZ    "Обнаружен контроллер "
VERS:    .ASCIZ    " версия прошивки: "
VERRT:    .ASCIZ    "Версия прошивки 555РТ5: "
RTOK:    .ASCIZ    "новая"<12>
RTBAD:    .ASCII    "старая, не рекомендуется к использованию"
        .ASCII    "из-за неправильных режимов работы, тест будет показывать ошибки"<12>
        .ASCIZ    "синхронизации на БК11М"<12>
RTERR:    .ASCIZ    "повреждена."<12>

TTL:    .ASCII <220>/"/
        .ASCII <210>/ Тест контроллера "АльтПро" с ДОЗУ 64-512 Кб/<12>
        .ASCII <220>/"/
        .ASCIZ <211>" (c) АльтПро 1997, gid 2012, v4.74F"<12>

TERR:    .ASCIZ <7><7>" Error "
TZPREP:    .ASCIZ    "Подготовка"
TZDOZU:    .ASCIZ    <12>"ДОЗУ, Кбайт:"
TZ2ERC:    .ASCIZ    <12><213>" "
TZERRS:    .ASCII    <12>"Тест памяти на ошибки..."
TZEST1:    .ASCIZ    <12>"Этап 1"<12>
TZEST2:    .ASCIZ    <12>"Этап 2"<12>
TZ3WR:    .ASCIZ    "write-"
TZ3RD:    .ASCIZ    "read-"
TZ3HL:    .ASCIZ    "halt "
TZ3BY:    .ASCIZ    "byte-test fail"
TZ2US1:    .ASCIZ    "стр. с кодом "
TZ2US2:    .ASCIZ    " уже подключали с "
TZSYN1:    .ASCIZ    " - синхро           "
TZSYNF:    .ASCIZ    ":ошибка"
TRZINF:    .ASCIZ    <12>"Тест режимов..."<12>
TRSWPG:    .ASCIZ    <12>"Тест переключения страниц..."<12>
TROK:    .ASCIZ    " OK"
TRSKIP:    .ASCIZ    "пропуск."<12>
ERINFO:    .ASCII    "Код ошибки: Сегмент-Код(Код). Сегмент -"<12>
        .ASCII    "сегмент памяти по 10000 байтов, Код - код ошибки, в скобках"<12>
        .ASCII    "ожидаемый код. Расшифровка кодов:"<12>
        .ASCII    "6-ОЗУ, 4-ОЗУзз, 0-ПЗУ, 10-пусто, остальные коды"<12>
        .ASCIZ    "недокументированы: 11-ОЗУзч, 1-ОЗУ на ПЗУ, 2-чужое ОЗУ"<12>

CRCINF:    .ASCII <12><202>"* Для запуска непрерывного теста контрольной суммы ПЗУ"<12>
        .ASCII <203>" нажмите любую клавишу. Правильное значение уточните"<12>
        .ASCIZ <203>" по документации. Прервать тест - СТОП."<12>

        .ASCIZ    <12>"   Код К.С.= "

        .ASCIZ "1234 "

        .ASCIZ "."

TRINFO:    .ASCIZ    <12>"Тест влияния RESET..."<12>
TADDR:    .ASCIZ    "Адрес: "
TANRM:    .ASCIZ    " - без изменений"<12>
TAERR:    .ASCIZ    " - "
TRRSOK:    .ASCIZ    "Норма. RESET не"
TRRSER:    .ASCIZ    "ОШИБКА. RESET"
TRRSTL:    .ASCIZ    " влияет на режимы."<12>
THINFO:    .ASCIZ    <12>"Тест доступности регистров HDD..."<12>
THERR:    .ASCIZ    "Это не СМК, пропускаем тест."<12>
THRESL:    .ASCIZ    "недоступен"<12>
T2INFO:    .ASCIZ    <12>"Тест влияния бита 2..."<12>
THINF2:    .ASCIZ    <12>"Тест буфера ОЗУ HDD..."<12>
THROK:    .ASCIZ    "ОЗУ в норме."<12>
THRER:    .ASCIZ    "Внимание! ОЗУ повредилось!"<12>
THRERN:    .ASCIZ    "Внимание! ОЗУ недоступно!"<12>
T2ERR:    .ASCIZ    "ОШИБКА! "
T2OK:    .ASCIZ    "Норма. "
T21:    .ASCIZ    "Регистры 177130, 177132 "
T22:    .ASCIZ    "должны блокироваться!"<12>
T23:    .ASCIZ    "блокируются."<12>
T3INFO:    .ASCIZ    <12>"Тест влияния бита 3..."<12>
T31:    .ASCIZ    "не подключается ПЗУ Бейсика."<12>
T3NONE:    .ASCIZ    "На БК11(М) бит 3 влияния не имеет."<12>

ENDTST:    .ASCIZ <12><202>"* Тестирование окончено !"
PRANYK:    .ASCIZ    <216>" *** Нажмите любую клавишу. ***"
TZLNTS:    .ASCIZ    "Задайте длительность длинного теста (0 - без теста) ["
        .EVEN

;-------переменные--
TZADDR:    .WORD    0
TZMODE:    .WORD    0
TRCODE:    .WORD    0
VALUE1:    .WORD    0
ERCOD:    .WORD    0
ERT31:    .WORD    0
SMKHDD:    .WORD    0

;тут будут храниться флаги ошибок для каждой страницы
;возможные результаты:
;    0 - всё отлично
;иначе маски:
;    1 - нет записи (halt)
;    2 - Нет чтения (halt)
;    10 - провал байт-теста
;    100000 - страницу уже подключали
PGEERR:    .BLKW    40

DTAB:    .BLKW    10
DTAA:    .BLKW    10

SETLNT:    .ADDR    R1,TZLNTS
        CLR        R2
        EMT        20
        MOV        #32.,R1
        MOV        R1,@#LNGTST
        CALL    DECOU$
        MOV        #"]:,R0
        EMT        16
        SWAB    R0
        EMT        16
        CALL    DECIN        ;ввод десятичного числа
        BCS        1$
        MOV        R1,@#LNGTST
1$:        MOV        #12,R0
        EMT        16
        RETURN

;выход:  R1 - полученное число.
;переполнение не проверяется, так что сколько влезет в 16 бит, столько и будет
;если бит С - то выходной результат недостоверен и должен игнорироваться
DECIN:    CLR        R1        ;счетчик вводимых цифр
        MOV        #DECBUF,R2    ;буфер, куда сохранять цифры
2$:        EMT        6
        CMPB    #3,R0    ;если нажали КТ - то отмена
        BEQ        1CANS
        CMPB    #12,R0    ;конец ввода
        BEQ        10$
        CMPB    #30,R0    ;забой
        BNE        1$
        TST        R1        ;что-то вводили?
        BEQ        2$        ;нет, игнорируем
        EMT        16
        DEC        R1        ;да, отменим последнюю цифру
        DEC        R2
        BR        2$

1$:        CMPB    R0,#'0    ;если не цифры
        BLO    2$
        CMPB    R0,#'9
        BHI        2$        ;то тоже игнорируем
        CMP        R1,#5    ;больше 5 цифр не вводить
        BGE        2$
        EMT        16
        SUB        #'0,R0    ;получим число
        MOVB    R0,(R2)+    ;и сохраним его
        INC        R1        ;увеличим счётчик введённые чисел
        BR        2$

10$:    TST        R1        ;если нажали enter до ввода числа,
        BEQ        3$        ;то это означает просто согласие со значением по умолчанию
        ;а иначе интерпретируем введённое число
        MOV        #DECBUF,R2
        CLR        R3        ;тут накапливается результат
4$:        ASL        R3
        MOV        R3,R4
        ASL        R3
        ASL        R3
        ADD        R4,R3
        MOVB    (R2)+,R0
        ADD        R0,R3
        SOB        R1,4$
        MOV        R3,R1
        BR        5$

1CANS:    TST        R1    ;если нажали esc, когда вводили число
        BNE        3$    ;то это означает, просто отмену и согласие со значением по умолчанию
5$:        TST        (PC)+    ;а если нажали до ввода числа - значит отказ от теста
3$:        SEC
        RETURN
;вывод десятичного числа с подавлением ведущих нулей
;вход:  R1 - число
DECOU$: JSR        R5,PUSHA
        CLR        R5
        MOV        #CONST,R2
6$:        CLR        R0
        MOV        (R2)+,R4
        BEQ        2$
1$:        SUB        R4,R1
        BCS        70$
        INC        R0
        BR        1$
70$:        ADD        R4,R1
        BIS        R0,R5
        BNE        4$
        CMP        #1,R4
        BNE        6$
4$:        ADD        #'0,R0
        EMT        16
        BR        6$
2$:        RETURN

        .END
 