Subversion Repositories KoE_projects

Rev

Blame | Last modification | View Log | Download | RSS feed | ?url?

; контроллер PS2 клавиатуры/мыши для ZX-SPECTRUM
; BY KINGOFEVIL, год 2OO7 от р.х.
;
; Тактовая частота микроконтроллера 8 МГц
; Назначение выводов микроконтроллера:
;
;  PS2: PA4 - CLK
;       PA3 - DATA
;
;  PB7..PB0 - данные
;
;  PA0 - если 0, то подключить клавиатуру к PS2 интерфейсу
;        если 1, то подключена мышь
;  PA1 - сброс регистров в ПЛИС  
;  PA2 - строб для приема информации с PB7..PB0 (прием по переднему фронту
;        в сдедующей последовательности: клавиатура, мышь X, мышь Y, мышь кн.
;        Через PB7..PB0 будет передано 8 байтов, которые нужно принимать в ПЛИС
;        последовательно с каждым фронтом импульса на PA2)


; область векторов прерываний

        JMP START0 ;<0>  Начальный пуск программы
        NOP        ;<1>  Сторожевой таймер
        JMP STERR  ;<2>  выход за границу стека
        JMP SC_M   ;<3>  Таймер A
        NOP        ;<4>  не используется
        NOP        ;<5>  не используется
        JMP SC_KEY ;<6>  Порт A
        NOP        ;<7>  Порт B
        NOP        ;<8>  не используется
        NOP        ;<9>  не используется
        NOP        ;<10> не используется
        NOP        ;<11> не используется
        NOP        ;<12> не используется
        NOP        ;<13> не используется
        NOP        ;<14> не используется
        RST        ;<15> Завершение записи в флэш


START0: LDR #A,0   ; Сегмент A - рабочие регистры портов
        LDR #B,18H ; Сегмент B - регистры конфигурации портов
        LDR #C,64  ; Сегмент С - переменные
        LDR #D,80  ; Сегмент D - переменные

        MOVL %B1,00111011B ; Установка конфигурации порта A
        MOVL %B1,00000110B
        MOVL %B1,00011111B
        MOVL %B1,00000000B
        MOVL %B1,00000000B
        MOVL %B1,00000000B ; прерывание по отрицательному перепаду уровня
                                                                  
        JMP REST

START:  LDR #A,0   ; Сегмент A - рабочие регистры портов
        LDR #B,18H ; Сегмент B - регистры конфигурации портов
        LDR #C,64  ; Сегмент С - переменные
        LDR #D,80  ; Сегмент D - переменные

        JSR INIT           ; инициализируем порты
        JSR KEYINI         ; инициализируем матрицу ZX-клавиш
        JSR MOUSINI        ; инициализируем мышку
        JSR TIMER          ; инициализируем прерывания от таймера

        ;MOVL %D0,0
        JSR RDFLSH

MAIN:   BTTL %D5,0001B
        JNZ CLM
       
        JMP MAIN          ; и есчо разок ...

CLM:    CMPL %D4,255
        JZ MAIN            ; если мышь не была расползнана при инициализации
        MOVL %A4,0         ; тормозим счетчик и запрещаем прерывания от него
        JSR WAIT           ; ожидаем готовность мыши
        MOVL %C3,11101011B ; код команды запроса состояния
        JSR WR_SC          ; засылаем в мышь
        JSR MORE           ; принимаем ответ
        CMPL %C3,11111010B ; все о.к. ?
        JNZ EXI            ; видимо, нет
        JSR MORE           ; ну а если все о.к., то принимаем еще 3 байта
        LDR #B,72
        MOV %B7,%C3 ; ZZ
        JSR MORE
        JSR MASHTB      
        LDR #B,72
        ADD %B5,%C3 ; XX

        JSR MORE
        
        JSR MASHTB
        LDR #B,72
        ADD %B6,%C3 ; YY
        
        BISH %B7,1111B    ; обрабатываем данные о нажатых кнопках мыши
        BICL %B7,1000B
        BTGL %B7,1111B
                 
        BICL %D5,0001B    ; CLEAR MOUSE INTERRUPTION BIT
        
        JSR VYVOD         ; закачиваем данные в ПЛИС


        MOVL %A4,00000110B ; подключаем регистр интервала (HI) к адресу 5
        MOVL %A5,2         ; 


EXI:    MOVL %A4,00000011B; запускаем счетчик и разрешаем прерывания от него
        JMP MAIN

MASHTB: MOV %D1,D0      ; грузим в D1 коэффициент замедления мышки
        CMPL %D1,0
        JZ VJOPU
        CMPL %C3,0
        JZ VJOPU        

        CMPL %C3,128
        JS MSH1 ; если меньше 128
        MOVL %D2,10000000B;

MSH0:   SHR %C3
        SHRA %D2
        DEC %D1
        JNZ MSH0

        SHL %D2         ; нужно установить столько старших разрядов, сколько
                        ; сдвигов было проделано (иначе стрелка будет 
                        ; дергаться из-за того, что вместо уменьшения координат
                        ; произойдет их увеличение). В D2 теперь как раз и будет
                        ; установлено нужное количество старших разрядов.

        OR %C3,%D2
        
        RTS

MSH1:   MOV %D1,%D0
MSH2:   SHR %C3
        DEC %D1
        JNZ MSH2
        
        CMPL %C3,0
        JNZ VJOPU
        MOVL %C3,1

VJOPU:  RTS


VYVOD:                     ; закачка данных в ПЛИС
        BICL %A1,0010B     ; сбрасываем регистры в ПЛИС
        NOP
        NOP
        BISL %A1,0010B     ; снимаем сигнал сброса
        LDR #B,72   
        MOV %A2,%B0        ; понеслась :-)
        JSR STROBE
        MOV %A2,%B1
        JSR STROBE
        MOV %A2,%B2
        JSR STROBE
        MOV %A2,%B3
        JSR STROBE
        MOV %A2,%B4
        JSR STROBE
        OR %B5,%D4
        MOV %A2,%B5
        JSR STROBE
        OR %B6,%D4
        MOV %A2,%B6
        JSR STROBE
        OR %B7,%D4
        MOV %A2,%B7
        JSR STROBE
        MOVL %A2,0
        LDR #B,18H
        RTS

STROBE: BISL %A1,0100B ; даем строб
        NOP
        NOP
        BICL %A1,0100B ; снимаем строб
        RTS

SC_M:   CLIE
        MOV %C3,%A4
        BISL %D5,0001B
        STIE
        RTI



SC_KEY: CLIE               ; запрещаем прерывания
        MOV %C3,%A1        ; снимаеи сигнал запроса прерывания                                                      +
        MOVL %A4,00000000B ; тормозим счетчик и запрещаем прерывания от него
        PUSH #B
        LDR #B,18H
        MOVL %B1,00101011B
        MOVL %B1,00000111B ; разрешаем запись в PA0
        BICL %A1,0001B     ; захватываем сигнал переключения на клавиатуру
        BISL %D5,0010B     ; устанавливаем флаг прерывания от клавиатуры
       
        JSR KEY
        JSR VYVOD

        LDR #B,18H
        MOVL %B1,00101011B
        MOVL %B1,00000110B ; запрещаем запись в PA0

        MOVL %A4,00000110B ; подключаем регистр интервала (HI) к адресу 5
        MOVL %A5,150         ; итак, получили полный коэффициент
        MOVL %A4,00000011B ; запускаем счетчик и разрешаем прерывания от него
        POP #B

        STIE
        RTI

; ****

KEY:    MOVL %C4,0
        MOVL %C5,0
        JSR RD_SC               ; Ура! Начинаем принимать скан-код! 
        MOV %C4,%C3
        CMPL %C4,11100000B      ; принимать второй байт скан-кода?
        JZ KEY1
        CMPL %C4,11100001B
        JZ KEY1
        JMP CONTTT
KEY1:   BISL %C5,0010B          ; устанавливаем флажок          
        JSR MORE
        MOV %C4,%C3    

CONTTT: CMPL %C4,7              ; если нажата кнопка F12, то даем RESET
        JZ REST
        CMPL %C4,078H
        JNZ CONTTZ
        JSR NMI
CONTTZ: CMPL %C4,0              ; если была ошибка, то считаем, что был
                                ; принят код отжатия. Понимаю, что лажа, но
                                ; почему-то в 99% случаев ошибки происходят
                                ; именно при приеме кода отжатия. Уж не знаю,
                                ; почему. Спишем на ламерство изобретателей
                                ; PS2 интерфейса (ну не признавать же свою
                                ; криворукость 
        JZ PODGON
        CMPL %C4,11110000B      ; это был код отжатой клавиши?
        JZ PODGON
        CMPL %C4,11110001B
        JZ PODGON
        JMP CONTT0
PODGON: BISL %C5,0001B          ; устанавливаем флажок
        JSR MORE                ; принимаем еще один скан-код - код отжатой 
        MOV %C4,%C3             ; клавиши 

CONTT0: BTTL %C5,0010B
        JZ CONTTA

CONTT1: CMPL %C4,00010001B ; правый ALT = левый ALT = SYMBOL SHIFT
        JZ CONTT2

EX5:    CMPL %C4,74H
        JNZ EX6
        JSR SHIFT
        MOVL %C4,3EH

EX6:    CMPL %C4,6BH
        JNZ EX7
        JSR SHIFT
        MOVL %C4,2EH

EX7:    CMPL %C4,75H       ; UP
        JNZ EX8
        JSR SHIFT
        MOVL %C4,3DH
        
EX8:    CMPL %C4,72H       ; DOWN
        JNZ EX9
        JSR SHIFT
        MOVL %C4,36H

EX9:    CMPL %C4,71H       ; BACKSPACE = DEL
        JNZ CONTT2
        JSR BACKSP 
        JMP CONTT2

CONTTA: CMPL %C4,66H            ; это клавиша BACKSPACE?
        JNZ CONTTD
        JSR BACKSP              ; если да, то ставим в соответсвие CAPS+0

CONTTD: CMPL %C4,59H            ; правый SHIFT = левый SHIFT = CAPS SHIFT
        JNZ CONTTW
        MOVL %C4,12H

CONTTW: CMPL %C4,0DH            ; TAB = EDIT = CAPS + 0
        JNZ CONTE
        JSR SHIFT
        MOVL %C4,16H

CONTE:  CMPL %C4,58H            ; CAPS LOCK = CAPS + 2
        JNZ CONTE1
        JSR SHIFT
        MOVL %C4,1EH

CONTE1: CMPL %C4,049H ; точка
        JNZ CONTE2
        JSR SSHIFT
        MOVL %C4,03AH

CONTE2: CMPL %C4,041H ; запятая
        JNZ CONTE3
        JSR SSHIFT
        MOVL %C4,031H

CONTE3: CMPL %C4,055H  ; =
        JNZ CONTE4
        JSR SSHIFT
        MOVL %C4,004BH

CONTE4: CMPL %C4,04EH  ; -
        JNZ CONTE5
        JSR SSHIFT
        MOVL %C4,03BH

CONTE5: CMPL %C4,6
        JNZ CONTE6
        BTTL %C5,0001B
        JNZ CONTE6
        INC %D0   ; F2 - увеличения коэффициента замедления мышки
        
CONTE6: CMPL %C4,4
        JNZ CONTE7
        BTTL %C5,0001B
        JNZ CONTE7
        DEC %D0 ; F3 - уменьшение коэффициента замедления мышки
        CMPL %D0,255
        JNZ CONTE7
        MOVL %D0,0

CONTE7: CMPL %C4,5
        JNZ CONTT2
        JSR WRFLSH ; - F1 - сохранение коэффициента замедления во FLASH - память

CONTT2: MDAL %C1,SCODE
        MDAH %C2,SCODE      ; Грузим в регистр косвенной адресации адрес
        MTPR #6,%C1         ; таблицы скан-кодов в памяти команд
        MTPR #7,%C2         ; (вся хрень с автоинкрементом, доступ через D7) 
                
CCD:    MOVL %C1,72
CYCK0:  MOVL %C6,8         ; 8 бит
        MOVL %C2,11111110B ; стартовое значение
CYCK1:  MOV %C3,D7         ; берем скан-код из таблицы
        CMP %C3,%C4        ; совпал с прочитанным?
        JZ SKEY            ; если совпал то идем на SKEY
        SST 0001B          ; устанавливаем флаг C
        RLC %C2            ; смотрим следующий вариант
        DEC %C6
        JNZ CYCK1
        INC %C1
        CMPL %C1,77        ; проверили все 5 наборов по 8 клавиш
        JNZ CYCK0
        MOVL %C4,0
        RTS

PPODGON:JSR KEYINI
        JMP PODGON

         
SKEY:   MTPR #4,%C1
        MOVL %C1,01000000B
        MTPR #5,%C1
        BTTL %C5,0001B
        JNZ RESKEY 
        AND %D6,%C2        ; фиксируем нажатие клавиши
        MOVL %C4,0
        RTS
RESKEY: NOT %C2
        OR %D6,%C2         ; фиксируем отжатие клавиши
        MOVL %C4,0
        RTS ; Усё       

MORE:   MOVL %C0,222       ; будем ждать (3*45+3)*222 команд 
WT0:    MOVL %C1,45       ; если за это время не поступит новый байт
WT1:    MOV %C2,%A1        ; данных, то выходим по ошибке
        BTTH %C2,0001B;
        JZ WT2
        DEC %C1
        JNZ WT1
        DEC %C0
        JNZ WT0;
        RTS     
WT2:    JSR RD_SC
        RTS

BACKSP: JSR SHIFT       ; DEL = SHIFT+0 обрабатываем SHIFT
        MOVL %C4,45H    ; подсовываем скан-код нуля
        RTS

SHIFT:  LDR #B,72
        BTTL %C5,0001B
        JNZ RSHIFT 
        BICL %B0,0001B       ; фиксируем нажатие клавиши
        LDR #B,18H
        RTS
RSHIFT: BISL %B0,0001B       ; фиксируем отжатие клавиши
        LDR #B,18H
        RTS      

SSHIFT: LDR #B,72
        BTTL %C5,0001B
        JNZ RSSHIFT 
        BICH %B1,1000B       ; фиксируем нажатие клавиши
        LDR #B,18H
        RTS
RSSHIFT:BISH %B1,1000B       ; фиксируем отжатие клавиши
        LDR #B,18H
        RTS      

NMI:    BICL %A1,0010B     ; даем сигнал сброса
        MOVL %A2,1         ; даем DATA0 = 1 (теперь на выходе NMI ПЛИС
                           ; появится 0)
        NOP
        NOP
        NOP
        NOP
        MOVL %A2,0         ; убираем 1 на DATA0
        BISL %A1,0010B     ; снимаем сигнал сброса
        RTS             

; **************************************************************

RD_SC:  ; Процедура чтения байта скан-кода

        MOVL %C3,0 ; Будем читать в C3. Начальное значение 0
        MOV %C1,%A1
        BTTL %C1,1000B ; проверяем стартовый бит
;       JNZ ERROR 
                  ; скан-код

        MOVL %C2,8 ; будем читать 8 бит
SCAN1:  JSR WAIT
        JSR WAIT1 ; идем на процедуру ожидания следующего такта 
        SHR %C3
        MOV %C1,%A1
        BTTL %C1,1000B
        JZ SCAN2
        BISH %C3,1000B ; если DATA=1, то ставим эту 1 в C3
SCAN2:  DEC %C2
        JNZ SCAN1
        JSR WAIT ; Байт скан-кода вроде бы прочитали, теперь надо принять бит
                 ; четности и затем стоповый бит.
        JSR WAIT1; На бит четности сразу же кладем, ибо нафиг он не нужен
        
        JSR WAIT
        JSR WAIT1
        MOV %C1,A1
        BTTL %C1,1000B ; Проверяем стоповый бит

;       JZ ERROR 
        JSR WAIT ; ждем прихода в исходное состояние
        RTS        

; ******************************************************************

WR_SC:  ; Процедура передачи байта скан-кода
        ; Чтобы перейти в режим передачи данных, нужно удерживать 0 на линии
        ; CLK не менее 60 мкс. На всякий случай будем держать 0 80 мкс.
        ; 80 это 320 команд (640 тактов) при F=8 МГц

        MOVL %B1,00101011B ; будем писать в подрегистр типа вывода порта A
        MOVL %B1,00011110B
        BICL %A1,1000B
        BICH %A1,0001B     ; выдаем 0 в CLK и DATA

        MOVL %C0,64 ; Ждем 64*5=320 команд 
REPL:   NOP        
        NOP
        NOP
        DEC %C0
        JNZ REPL;
        
        BISH %A1,0001B ; снимаем 0 CLK
        MOVL %B1,00101011B ; будем писать в подрегистр типа вывода порта A
        MOVL %B1,00001110B ; переводим CLK на чтение
        BICL %A1,1000B
        MOVL %C0,0 ; это будет счетчик единичных битов для формирования
                   ; бита четности
                
W1:     MOVL %C7,255   ; ждем 0, т.е. начала тактирования процесса
W2:     BTTH %A1,0001B
        JZ E1
        NOP
        NOP
        NOP
        NOP
        NOP
        DEC %C7
        JNZ W2
E1:
                   ; передачи данных девайсом
        MOVL %C2,8 ; будем передавать 8 бит
WR_0:              ; передаем бит

WR1:    SHR %C3
        JC WR2
        BICL %A1,1000B
        JMP WR3

WR2:    BISL %A1,1000B
        INC %C0         ; добавляем 1 к счетчику
WR3:    BTTH %A1,0001B  ; ждем 1 на CLK
        JZ WR3;

         ; ожидаем защелкивания бита данных девайсом и его
         ; готовности к приему следующего бита (0 на CLK)

        MOVL %C7,255
WW2:    BTTH %A1,0001B
        JZ EE1
        NOP
        NOP
        NOP
        NOP
        NOP
        DEC %C7
        JNZ WW2

EE1:    DEC %C2
        JNZ WR_0 
        
                 ; Байт скан-кода вроде бы передали, теперь надо передать бит
                 ; четности и затем принять стоповый бит. Мля, ну какие же
                 ; ламеры придумали этот PS2 интерфейс :-E

        MOVL %C3,0
        SHR %C0  ; Значение бита четности берем из 0-го разряда %C0
        JNC BCNZ ; Если бит четности =0
        BISL %C3,1 ; если бит четности =1

BCNZ:   ; передаем 

        SHR %C3
        JC WRR2
        BICL %A1,1000B
        JMP WRR3

WRR2:   BISL %A1,1000B
        INC %C0   ; добавляем 1 к счетчику

WRR3:   ; ждем 1
        BTTH %A1,0001B
        JZ WRR3;

        ; ожидаем защелкивания бита данных девайсом и его
        ; готовности к приему следующего бита

        MOVL %C7,255   ; ждем 0
WWA1:   BTTH %A1,0001B
        JZ EEX
        NOP
        NOP
        NOP
        NOP
        NOP
        DEC %C7
        JNZ WWA1

EEX:    MOVL %B1,00101011B ; будем писать в подрегистр типа вывода порта A
        MOVL %B1,00000110B ; переводим DATA на чтение
        
IT:     ; ждем 1
        BTTH %A1,0001B
        JZ IT;
        
        JSR WAIT1 ; ожидаем приход стопового бита


        MOVL %C7,255   ; ждем 0
AWA1:   BTTH %A1,0001B
        JZ WEX
        NOP
        NOP
        NOP
        NOP
        NOP
        DEC %C7
        JNZ AWA1

WEX:    MOV %C1,%A1
        BTTL %C1,1000B ; проверяем стоповый бит
                       ; только непонятно, зачем 

HT:     ; ждем 1
        BTTH %A1,0001B
        JZ HT;
        RTS        

ERROR:  MOVL %C3,0

WAIT:   MOV %C1,%A1    ; ждем 1
        BTTH %C1,0001B
        JZ WAIT;
        RTS
WAIT1:  MOVL %C7,255   ; ждем 0
WAI1:   MOV %C1,%A1
        BTTH %C1,0001B
        JZ EXIT1
        NOP
        NOP
        NOP
        NOP
        NOP
        DEC %C7
        JNZ WAI1
        JMP ERROR
EXIT1:  RTS

; ********************

WRFLSH: LDR #B,56  ; адрес регистра управления блока ЭСППЗУ данных
        MOVL %B1,0 ; адрес ячейки = 0 (используем только один байт)
        MOV %B7,%D0
        MOVL %B0,00000001B
WRF1:   BTTL %B0,0001B
        JNZ WRF1 ; ждем, пока происходит запись
        LDR #B,18H
        RTS

; ********************

RDFLSH: LDR #B,56  ; адрес регистра управления блока ЭСППЗУ данных
        MOVL %B1,0 ; адрес ячейки = 0 (используем только один байт)
        MOVL %B0,00000010B
RDF1:   BTTL %B0,0010B
        JNZ RDF1 ; ждем, пока происходит чтение
        MOV %D0,%B7
        LDR #B,18H
        RTS

; ********************
INIT:   MOVL %B1,00111011B ; Установка конфигурации порта A
        MOVL %B1,00000110B
        MOVL %B1,00011111B
        MOVL %B1,00000000B
        MOVL %B1,00000000B
        MOVL %B1,00000001B ; прерывание по отрицательному перепаду уровня
                           ; на линии CLK_KEY  для опроса клавиатуры

        STIE

        MOVL %B2,00011011B ; Установка конфигурации порта B
        MOVL %B2,11111111B
        MOVL %B2,11111111B
        MOVL %B2,0
        MOVL %B2,0
        MOVL %B2,0

        BISL %A1,0010B     ; выдаем 1 на линию сброса регистров в ПЛИС
        BICL %A1,0100B     ; выдаем 0 на линию STROBE

        MOVL %D5,0         ; флажок (потом пригодится)
        RTS

KEYINI:                   ; инициализация матрицы клавиатуры
        LDR #B,72         ; весь буфер из 5-и байтов заполняем
        MOVL %B0,11111111B ; значениями 255
        MOVL %B1,11111111B
        MOVL %B2,11111111B
        MOVL %B3,11111111B
        MOVL %B4,11111111B
        LDR #B,18H
        JSR VYVOD
        RTS

; здесь надо бы отключать клавиатуру - потом поправлю

MOUSINI:MOVL %D4,0
        LDR #B,72
        MOVL %B5,125
        MOVL %B6,125
        MOVL %B7,255
        LDR #B,18H
        JSR WAIT           ; мышь подключили. Теперь ожидаем ее готовность
                           ; Теперь нужно передать в мышь команду запроса
                           ; ее состояния (здесь неудобно использовать
                           ; потоковый режим, хотя, в принципе, можно)
        MOVL %C3,11110000B ; код команды перехода в REMOTE MODE
        JSR WR_SC
        JSR MORE           ; принимаем код подтверждения 
        CMPL %C3,11111010B 
        JNZ MOUSOFF       ; ERROR 
        MOVL %C3,11110011B
        JSR WR_SC
        JSR MORE
        MOVL %C3,40
        JSR WR_SC
        JSR MORE        
        RTS

MOUSOFF:MOVL %D4,255
        RTS

TIMER:                     ; мышку будем опрашивать по прерываниям от таймера
        MOVL %A4,00010010B ; подключаем регистр конфигурации к адресу 5 
        MOVL %A5,01001110B ; задаем коэффициент деления тактовой частоты 1/128
        MOVL %A4,00000010B ; подключаем регистр интервала (LOW) к адресу 5
        MOVL %A5,113
        MOVL %A4,00000110B ; подключаем регистр интервала (HI) к адресу 5
        MOVL %A5,2         ; итак, получили полный коэффициент
                           ; деления 128*(2?4?*256+113)=80000, прерывания от
                           ; таймера будут идти с частотой Fтакт/80000=100 Гц
        MOVL %A4,00000011B ; пускаем таймер на счет
        STIE               ; разрешаем прерывания
        RTS


REST:   BICL %A1,0010B   
        NOP
        NOP
        BISL %A1,0100B 
        MOVL %C3,255
TRMZ0:  MOVL %C4,255
TRMZ1:  MOVL %C5,30
TRMZ2:  DEC %C5
        JNZ TRMZ2
        DEC %C4
        JNZ TRMZ1
        DEC %C3
        JNZ TRMZ0
        BICL %A1,0100B 
        NOP
        NOP
        BISL %A1,0010B
        RST
        JMP START

STERR:  RST
        JMP START
           
SCODE:  .BYTE 12H,1CH,15H,16H,45H,4DH,5AH,29H
        .EVEN; байт 0: CS,A,Q,1,0,P,ENT,SPACE

        .BYTE 1AH,1BH,1DH,1EH,46H,44H,4BH,11H
        .EVEN; байт 1: Z,S,W,2,9,O,L,SS

        .BYTE 22H,23H,24H,26H,3EH,43H,42H,3AH
        .EVEN; байт 2: X,D,E,3,8,I,K,M

        .BYTE 21H,2BH,2DH,25H,3DH,3CH,3BH,31H
        .EVEN; байт 3: C,F,R,4,7,U,J,N

        .BYTE 2AH,34H,2CH,2EH,36H,35H,33H,32H
        .EVEN; байт 4: V,G,T,5,6,Y,H,B

.END;