Subversion Repositories KoE_projects

Rev

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

          Windows VERSION
    1                   ; контроллер PS2 клавиатуры/мыши для ZX-SPECTRUM
    2                   ; BY KINGOFEVIL, год 2OO7 от р.х.
    3                   ;
    4                   ; Тактовая частота микроконтроллера 8 МГц
    5                   ; Назначение выводов микроконтроллера:
    6                   ;
    7                   ;  PS2: PA4 - CLK
    8                   ;       PA3 - DATA
    9                   ;
   10                   ;  PB7..PB0 - данные
   11                   ;
   12                   ;  PA0 - если 0, то подключить клавиатуру к PS2 интерфейсу
   13                   ;        если 1, то подключена мышь
   14                   ;  PA1 - сброс регистров в ПЛИС  
   15                   ;  PA2 - строб для приема информации с PB7..PB0 (прием по переднему фронту
   16                   ;        в сдедующей последовательности: клавиатура, мышь X, мышь Y, мышь кн.
   17                   ;        Через PB7..PB0 будет передано 8 байтов, которые нужно принимать в ПЛИС
   18                   ;        последовательно с каждым фронтом импульса на PA2)
   19                   
   20                   
   21                   ; область векторов прерываний
   22                   
   23 0000 8010                 JMP START0 ;<0>  Начальный пуск программы
   24 0001 0000                 NOP        ;<1>  Сторожевой таймер
   25 0002 821A                 JMP STERR  ;<2>  выход за границу стека
   26 0003 807B                 JMP SC_M   ;<3>  Таймер A
   27 0004 0000                 NOP        ;<4>  не используется
   28 0005 0000                 NOP        ;<5>  не используется
   29 0006 8080                 JMP SC_KEY ;<6>  Порт A
   30 0007 0000                 NOP        ;<7>  Порт B
   31 0008 0000                 NOP        ;<8>  не используется
   32 0009 0000                 NOP        ;<9>  не используется
   33 000A 0000                 NOP        ;<10> не используется
   34 000B 0000                 NOP        ;<11> не используется
   35 000C 0000                 NOP        ;<12> не используется
   36 000D 0000                 NOP        ;<13> не используется
   37 000E 0000                 NOP        ;<14> не используется
   38 000F 0002                 RST        ;<15> Завершение записи в флэш
   39                   
   40                   
   41 0010 2000         START0: LDR #A,0   ; Сегмент A - рабочие регистры портов
   42 0011 2019                 LDR #B,18H ; Сегмент B - регистры конфигурации портов
   43 0012 2042                 LDR #C,64  ; Сегмент С - переменные
   44 0013 2053                 LDR #D,80  ; Сегмент D - переменные
   45                   
   46 0014 4769                 MOVL %B1,00111011B ; Установка конфигурации порта A
   47 0015 40C9                 MOVL %B1,00000110B
   48 0016 43E9                 MOVL %B1,00011111B
   49 0017 4009                 MOVL %B1,00000000B
   50 0018 4009                 MOVL %B1,00000000B
   51 0019 4009                 MOVL %B1,00000000B ; прерывание по отрицательному перепаду уровня
   52                                                                                     
   53 001A 8207                 JMP REST
   54                   
   55 001B 2000         START:  LDR #A,0   ; Сегмент A - рабочие регистры портов
   56 001C 2019                 LDR #B,18H ; Сегмент B - регистры конфигурации портов
   57 001D 2042                 LDR #C,64  ; Сегмент С - переменные
   58 001E 2053                 LDR #D,80  ; Сегмент D - переменные
   59                   
   60 001F 91CF                 JSR INIT           ; инициализируем порты
   61 0020 91E0                 JSR KEYINI         ; инициализируем матрицу ZX-клавиш
   62 0021 91E9                 JSR MOUSINI        ; инициализируем мышку
   63 0022 91FE                 JSR TIMER          ; инициализируем прерывания от таймера
   64                   
   65                           ;MOVL %D0,0
   66 0023 91C7                 JSR RDFLSH
   67                   
   68 0024 343D         MAIN:   BTTL %D5,0001B
   69 0025 B027                 JNZ CLM
   70                          
   71 0026 8024                 JMP MAIN          ; и есчо разок ...
   72                   
   73 0027 7FFC         CLM:    CMPL %D4,255
   74 0028 A024                 JZ MAIN            ; если мышь не была расползнана при инициализации
   75 0029 4004                 MOVL %A4,0         ; тормозим счетчик и запрещаем прерывания от него
   76 002A 91AE                 JSR WAIT           ; ожидаем готовность мыши
   77 002B 5D73                 MOVL %C3,11101011B ; код команды запроса состояния
   78 002C 9155                 JSR WR_SC          ; засылаем в мышь
   79 002D 9116                 JSR MORE           ; принимаем ответ
   80 002E 7F53                 CMPL %C3,11111010B ; все о.к. ?
   81 002F B042                 JNZ EXI            ; видимо, нет
   82 0030 9116                 JSR MORE           ; ну а если все о.к., то принимаем еще 3 байта
   83 0031 2049                 LDR #B,72
   84 0032 066F                 MOV %B7,%C3 ; ZZ
   85 0033 9116                 JSR MORE
   86 0034 9044                 JSR MASHTB      
   87 0035 2049                 LDR #B,72
   88 0036 126D                 ADD %B5,%C3 ; XX
   89                   
   90 0037 9116                 JSR MORE
   91                           
   92 0038 9044                 JSR MASHTB
   93 0039 2049                 LDR #B,72
   94 003A 126E                 ADD %B6,%C3 ; YY
   95                           
   96 003B 3BEF                 BISH %B7,1111B    ; обрабатываем данные о нажатых кнопках мыши
   97 003C 290F                 BICL %B7,1000B
   98 003D 3DEF                 BTGL %B7,1111B
   99                                    
  100 003E 283D                 BICL %D5,0001B    ; CLEAR MOUSE INTERRUPTION BIT
  101                           
  102 003F 905B                 JSR VYVOD         ; закачиваем данные в ПЛИС
  103                   
  104                   
  105 0040 40C4                 MOVL %A4,00000110B ; подключаем регистр интервала (HI) к адресу 5
  106 0041 4045                 MOVL %A5,2         ; 
  107                   
  108                   
  109 0042 4064         EXI:    MOVL %A4,00000011B; запускаем счетчик и разрешаем прерывания от него
  110 0043 8024                 JMP MAIN
  111                   
  112 0044 0719         MASHTB: MOV %D1,D0      ; грузим в D1 коэффициент замедления мышки
  113 0045 6019                 CMPL %D1,0
  114 0046 A05A                 JZ VJOPU
  115 0047 6013                 CMPL %C3,0
  116 0048 A05A                 JZ VJOPU        
  117                   
  118 0049 7013                 CMPL %C3,128
  119 004A D053                 JS MSH1 ; если меньше 128
  120 004B 501A                 MOVL %D2,10000000B;
  121                   
  122 004C 00B3         MSH0:   SHR %C3
  123 004D 00DA                 SHRA %D2
  124 004E 2C39                 DEC %D1
  125 004F B04C                 JNZ MSH0
  126                   
  127 0050 009A                 SHL %D2         ; нужно установить столько старших разрядов, сколько
  128                                           ; сдвигов было проделано (иначе стрелка будет 
  129                                           ; дергаться из-за того, что вместо уменьшения координат
  130                                           ; произойдет их увеличение). В D2 теперь как раз и будет
  131                                           ; установлено нужное количество старших разрядов.
  132                   
  133 0051 1B53                 OR %C3,%D2
  134                           
  135 0052 000C                 RTS
  136                   
  137 0053 0719         MSH1:   MOV %D1,%D0
  138 0054 00B3         MSH2:   SHR %C3
  139 0055 2C39                 DEC %D1
  140 0056 B054                 JNZ MSH2
  141                           
  142 0057 6013                 CMPL %C3,0
  143 0058 B05A                 JNZ VJOPU
  144 0059 4033                 MOVL %C3,1
  145                   
  146 005A 000C         VJOPU:  RTS
  147                   
  148                   
  149                   VYVOD:                     ; закачка данных в ПЛИС
  150 005B 2841                 BICL %A1,0010B     ; сбрасываем регистры в ПЛИС
  151 005C 0000                 NOP
  152 005D 0000                 NOP
  153 005E 3841                 BISL %A1,0010B     ; снимаем сигнал сброса
  154 005F 2049                 LDR #B,72   
  155 0060 0502                 MOV %A2,%B0        ; понеслась :-)
  156 0061 9076                 JSR STROBE
  157 0062 0522                 MOV %A2,%B1
  158 0063 9076                 JSR STROBE
  159 0064 0542                 MOV %A2,%B2
  160 0065 9076                 JSR STROBE
  161 0066 0562                 MOV %A2,%B3
  162 0067 9076                 JSR STROBE
  163 0068 0582                 MOV %A2,%B4
  164 0069 9076                 JSR STROBE
  165 006A 1B8D                 OR %B5,%D4
  166 006B 05A2                 MOV %A2,%B5
  167 006C 9076                 JSR STROBE
  168 006D 1B8E                 OR %B6,%D4
  169 006E 05C2                 MOV %A2,%B6
  170 006F 9076                 JSR STROBE
  171 0070 1B8F                 OR %B7,%D4
  172 0071 05E2                 MOV %A2,%B7
  173 0072 9076                 JSR STROBE
  174 0073 4002                 MOVL %A2,0
  175 0074 2019                 LDR #B,18H
  176 0075 000C                 RTS
  177                   
  178 0076 3881         STROBE: BISL %A1,0100B ; даем строб
  179 0077 0000                 NOP
  180 0078 0000                 NOP
  181 0079 2881                 BICL %A1,0100B ; снимаем строб
  182 007A 000C                 RTS
  183                   
  184 007B 01C8         SC_M:   CLIE
  185 007C 0493                 MOV %C3,%A4
  186 007D 383D                 BISL %D5,0001B
  187 007E 0188                 STIE
  188 007F 000D                 RTI
  189                   
  190                   
  191                   
  192 0080 01C8         SC_KEY: CLIE               ; запрещаем прерывания
  193 0081 0433                 MOV %C3,%A1        ; снимаеи сигнал запроса прерывания                                                      +
  194 0082 4004                 MOVL %A4,00000000B ; тормозим счетчик и запрещаем прерывания от него
  195 0083 0011                 PUSH #B
  196 0084 2019                 LDR #B,18H
  197 0085 4569                 MOVL %B1,00101011B
  198 0086 40E9                 MOVL %B1,00000111B ; разрешаем запись в PA0
  199 0087 2821                 BICL %A1,0001B     ; захватываем сигнал переключения на клавиатуру
  200 0088 385D                 BISL %D5,0010B     ; устанавливаем флаг прерывания от клавиатуры
  201                          
  202 0089 9094                 JSR KEY
  203 008A 905B                 JSR VYVOD
  204                   
  205 008B 2019                 LDR #B,18H
  206 008C 4569                 MOVL %B1,00101011B
  207 008D 40C9                 MOVL %B1,00000110B ; запрещаем запись в PA0
  208                   
  209 008E 40C4                 MOVL %A4,00000110B ; подключаем регистр интервала (HI) к адресу 5
  210 008F 52C5                 MOVL %A5,150         ; итак, получили полный коэффициент
  211 0090 4064                 MOVL %A4,00000011B ; запускаем счетчик и разрешаем прерывания от него
  212 0091 0019                 POP #B
  213                   
  214 0092 0188                 STIE
  215 0093 000D                 RTI
  216                   
  217                   ; ****
  218                   
  219 0094 4014         KEY:    MOVL %C4,0
  220 0095 4015                 MOVL %C5,0
  221 0096 9140                 JSR RD_SC               ; Ура! Начинаем принимать скан-код! 
  222 0097 0674                 MOV %C4,%C3
  223 0098 7C14                 CMPL %C4,11100000B      ; принимать второй байт скан-кода?
  224 0099 A09D                 JZ KEY1
  225 009A 7C34                 CMPL %C4,11100001B
  226 009B A09D                 JZ KEY1
  227 009C 80A0                 JMP CONTTT
  228 009D 3855         KEY1:   BISL %C5,0010B          ; устанавливаем флажок          
  229 009E 9116                 JSR MORE
  230 009F 0674                 MOV %C4,%C3    
  231                   
  232 00A0 60F4         CONTTT: CMPL %C4,7              ; если нажата кнопка F12, то даем RESET
  233 00A1 A207                 JZ REST
  234 00A2 6F14                 CMPL %C4,078H
  235 00A3 B0A5                 JNZ CONTTZ
  236 00A4 9137                 JSR NMI
  237 00A5 6014         CONTTZ: CMPL %C4,0              ; если была ошибка, то считаем, что был
  238                                                   ; принят код отжатия. Понимаю, что лажа, но
  239                                                   ; почему-то в 99% случаев ошибки происходят
  240                                                   ; именно при приеме кода отжатия. Уж не знаю,
  241                                                   ; почему. Спишем на ламерство изобретателей
  242                                                   ; PS2 интерфейса (ну не признавать же свою
  243                                                   ; криворукость 
  244 00A6 A0AC                 JZ PODGON
  245 00A7 7E14                 CMPL %C4,11110000B      ; это был код отжатой клавиши?
  246 00A8 A0AC                 JZ PODGON
  247 00A9 7E34                 CMPL %C4,11110001B
  248 00AA A0AC                 JZ PODGON
  249 00AB 80AF                 JMP CONTT0
  250 00AC 3835         PODGON: BISL %C5,0001B          ; устанавливаем флажок
  251 00AD 9116                 JSR MORE                ; принимаем еще один скан-код - код отжатой 
  252 00AE 0674                 MOV %C4,%C3             ; клавиши 
  253                   
  254 00AF 3455         CONTT0: BTTL %C5,0010B
  255 00B0 A0C7                 JZ CONTTA
  256                   
  257 00B1 6234         CONTT1: CMPL %C4,00010001B ; правый ALT = левый ALT = SYMBOL SHIFT
  258 00B2 A0F5                 JZ CONTT2
  259                   
  260 00B3 6E94         EX5:    CMPL %C4,74H
  261 00B4 B0B7                 JNZ EX6
  262 00B5 9125                 JSR SHIFT
  263 00B6 47D4                 MOVL %C4,3EH
  264                   
  265 00B7 6D74         EX6:    CMPL %C4,6BH
  266 00B8 B0BB                 JNZ EX7
  267 00B9 9125                 JSR SHIFT
  268 00BA 45D4                 MOVL %C4,2EH
  269                   
  270 00BB 6EB4         EX7:    CMPL %C4,75H       ; UP
  271 00BC B0BF                 JNZ EX8
  272 00BD 9125                 JSR SHIFT
  273 00BE 47B4                 MOVL %C4,3DH
  274                           
  275 00BF 6E54         EX8:    CMPL %C4,72H       ; DOWN
  276 00C0 B0C3                 JNZ EX9
  277 00C1 9125                 JSR SHIFT
  278 00C2 46D4                 MOVL %C4,36H
  279                   
  280 00C3 6E34         EX9:    CMPL %C4,71H       ; BACKSPACE = DEL
  281 00C4 B0F5                 JNZ CONTT2
  282 00C5 9122                 JSR BACKSP 
  283 00C6 80F5                 JMP CONTT2
  284                   
  285 00C7 6CD4         CONTTA: CMPL %C4,66H            ; это клавиша BACKSPACE?
  286 00C8 B0CA                 JNZ CONTTD
  287 00C9 9122                 JSR BACKSP              ; если да, то ставим в соответсвие CAPS+0
  288                   
  289 00CA 6B34         CONTTD: CMPL %C4,59H            ; правый SHIFT = левый SHIFT = CAPS SHIFT
  290 00CB B0CD                 JNZ CONTTW
  291 00CC 4254                 MOVL %C4,12H
  292                   
  293 00CD 61B4         CONTTW: CMPL %C4,0DH            ; TAB = EDIT = CAPS + 0
  294 00CE B0D1                 JNZ CONTE
  295 00CF 9125                 JSR SHIFT
  296 00D0 42D4                 MOVL %C4,16H
  297                   
  298 00D1 6B14         CONTE:  CMPL %C4,58H            ; CAPS LOCK = CAPS + 2
  299 00D2 B0D5                 JNZ CONTE1
  300 00D3 9125                 JSR SHIFT
  301 00D4 43D4                 MOVL %C4,1EH
  302                   
  303 00D5 6934         CONTE1: CMPL %C4,049H ; точка
  304 00D6 B0D9                 JNZ CONTE2
  305 00D7 912E                 JSR SSHIFT
  306 00D8 4754                 MOVL %C4,03AH
  307                   
  308 00D9 6834         CONTE2: CMPL %C4,041H ; запятая
  309 00DA B0DD                 JNZ CONTE3
  310 00DB 912E                 JSR SSHIFT
  311 00DC 4634                 MOVL %C4,031H
  312                   
  313 00DD 6AB4         CONTE3: CMPL %C4,055H  ; =
  314 00DE B0E1                 JNZ CONTE4
  315 00DF 912E                 JSR SSHIFT
  316 00E0 4974                 MOVL %C4,004BH
  317                   
  318 00E1 69D4         CONTE4: CMPL %C4,04EH  ; -
  319 00E2 B0E5                 JNZ CONTE5
  320 00E3 912E                 JSR SSHIFT
  321 00E4 4774                 MOVL %C4,03BH
  322                   
  323 00E5 60D4         CONTE5: CMPL %C4,6
  324 00E6 B0EA                 JNZ CONTE6
  325 00E7 3435                 BTTL %C5,0001B
  326 00E8 B0EA                 JNZ CONTE6
  327 00E9 3038                 INC %D0   ; F2 - увеличения коэффициента замедления мышки
  328                           
  329 00EA 6094         CONTE6: CMPL %C4,4
  330 00EB B0F2                 JNZ CONTE7
  331 00EC 3435                 BTTL %C5,0001B
  332 00ED B0F2                 JNZ CONTE7
  333 00EE 2C38                 DEC %D0 ; F3 - уменьшение коэффициента замедления мышки
  334 00EF 7FF8                 CMPL %D0,255
  335 00F0 B0F2                 JNZ CONTE7
  336 00F1 4018                 MOVL %D0,0
  337                   
  338 00F2 60B4         CONTE7: CMPL %C4,5
  339 00F3 B0F5                 JNZ CONTT2
  340 00F4 91BF                 JSR WRFLSH ; - F1 - сохранение коэффициента замедления во FLASH - память
  341                   
  342 00F5 4711         CONTT2: MDAL %C1,SCODE
  343 00F6 4092                 MDAH %C2,SCODE      ; Грузим в регистр косвенной адресации адрес
  344 00F7 02D1                 MTPR #6,%C1         ; таблицы скан-кодов в памяти команд
  345 00F8 02F2                 MTPR #7,%C2         ; (вся хрень с автоинкрементом, доступ через D7) 
  346                                   
  347 00F9 4911         CCD:    MOVL %C1,72
  348 00FA 4116         CYCK0:  MOVL %C6,8         ; 8 бит
  349 00FB 5FD2                 MOVL %C2,11111110B ; стартовое значение
  350 00FC 07F3         CYCK1:  MOV %C3,D7         ; берем скан-код из таблицы
  351 00FD 0A93                 CMP %C3,%C4        ; совпал с прочитанным?
  352 00FE A10A                 JZ SKEY            ; если совпал то идем на SKEY
  353 00FF 0181                 SST 0001B          ; устанавливаем флаг C
  354 0100 00F2                 RLC %C2            ; смотрим следующий вариант
  355 0101 2C36                 DEC %C6
  356 0102 B0FC                 JNZ CYCK1
  357 0103 3031                 INC %C1
  358 0104 69B1                 CMPL %C1,77        ; проверили все 5 наборов по 8 клавиш
  359 0105 B0FA                 JNZ CYCK0
  360 0106 4014                 MOVL %C4,0
  361 0107 000C                 RTS
  362                   
  363 0108 91E0         PPODGON:JSR KEYINI
  364 0109 80AC                 JMP PODGON
  365                   
  366                            
  367 010A 0291         SKEY:   MTPR #4,%C1
  368 010B 4811                 MOVL %C1,01000000B
  369 010C 02B1                 MTPR #5,%C1
  370 010D 3435                 BTTL %C5,0001B
  371 010E B112                 JNZ RESKEY 
  372 010F 165E                 AND %D6,%C2        ; фиксируем нажатие клавиши
  373 0110 4014                 MOVL %C4,0
  374 0111 000C                 RTS
  375 0112 0072         RESKEY: NOT %C2
  376 0113 1A5E                 OR %D6,%C2         ; фиксируем отжатие клавиши
  377 0114 4014                 MOVL %C4,0
  378 0115 000C                 RTS ; Усё       
  379                   
  380 0116 5BD0         MORE:   MOVL %C0,222       ; будем ждать (3*45+3)*222 команд 
  381 0117 45B1         WT0:    MOVL %C1,45       ; если за это время не поступит новый байт
  382 0118 0432         WT1:    MOV %C2,%A1        ; данных, то выходим по ошибке
  383 0119 3632                 BTTH %C2,0001B;
  384 011A A120                 JZ WT2
  385 011B 2C31                 DEC %C1
  386 011C B118                 JNZ WT1
  387 011D 2C30                 DEC %C0
  388 011E B117                 JNZ WT0;
  389 011F 000C                 RTS     
  390 0120 9140         WT2:    JSR RD_SC
  391 0121 000C                 RTS
  392                   
  393 0122 9125         BACKSP: JSR SHIFT       ; DEL = SHIFT+0 обрабатываем SHIFT
  394 0123 48B4                 MOVL %C4,45H    ; подсовываем скан-код нуля
  395 0124 000C                 RTS
  396                   
  397 0125 2049         SHIFT:  LDR #B,72
  398 0126 3435                 BTTL %C5,0001B
  399 0127 B12B                 JNZ RSHIFT 
  400 0128 2828                 BICL %B0,0001B       ; фиксируем нажатие клавиши
  401 0129 2019                 LDR #B,18H
  402 012A 000C                 RTS
  403 012B 3828         RSHIFT: BISL %B0,0001B       ; фиксируем отжатие клавиши
  404 012C 2019                 LDR #B,18H
  405 012D 000C                 RTS      
  406                   
  407 012E 2049         SSHIFT: LDR #B,72
  408 012F 3435                 BTTL %C5,0001B
  409 0130 B134                 JNZ RSSHIFT 
  410 0131 2B09                 BICH %B1,1000B       ; фиксируем нажатие клавиши
  411 0132 2019                 LDR #B,18H
  412 0133 000C                 RTS
  413 0134 3B09         RSSHIFT:BISH %B1,1000B       ; фиксируем отжатие клавиши
  414 0135 2019                 LDR #B,18H
  415 0136 000C                 RTS      
  416                   
  417 0137 2841         NMI:    BICL %A1,0010B     ; даем сигнал сброса
  418 0138 4022                 MOVL %A2,1         ; даем DATA0 = 1 (теперь на выходе NMI ПЛИС
  419                                              ; появится 0)
  420 0139 0000                 NOP
  421 013A 0000                 NOP
  422 013B 0000                 NOP
  423 013C 0000                 NOP
  424 013D 4002                 MOVL %A2,0         ; убираем 1 на DATA0
  425 013E 3841                 BISL %A1,0010B     ; снимаем сигнал сброса
  426 013F 000C                 RTS             
  427                   
  428                   ; **************************************************************
  429                   
  430                   RD_SC:  ; Процедура чтения байта скан-кода
  431                   
  432 0140 4013                 MOVL %C3,0 ; Будем читать в C3. Начальное значение 0
  433 0141 0431                 MOV %C1,%A1
  434 0142 3511                 BTTL %C1,1000B ; проверяем стартовый бит
  435                   ;       JNZ ERROR 
  436                                     ; скан-код
  437                   
  438 0143 4112                 MOVL %C2,8 ; будем читать 8 бит
  439 0144 91AE         SCAN1:  JSR WAIT
  440 0145 91B2                 JSR WAIT1 ; идем на процедуру ожидания следующего такта 
  441 0146 00B3                 SHR %C3
  442 0147 0431                 MOV %C1,%A1
  443 0148 3511                 BTTL %C1,1000B
  444 0149 A14B                 JZ SCAN2
  445 014A 3B13                 BISH %C3,1000B ; если DATA=1, то ставим эту 1 в C3
  446 014B 2C32         SCAN2:  DEC %C2
  447 014C B144                 JNZ SCAN1
  448 014D 91AE                 JSR WAIT ; Байт скан-кода вроде бы прочитали, теперь надо принять бит
  449                                    ; четности и затем стоповый бит.
  450 014E 91B2                 JSR WAIT1; На бит четности сразу же кладем, ибо нафиг он не нужен
  451                           
  452 014F 91AE                 JSR WAIT
  453 0150 91B2                 JSR WAIT1
  454 0151 0431                 MOV %C1,A1
  455 0152 3511                 BTTL %C1,1000B ; Проверяем стоповый бит
  456                   
  457                   ;       JZ ERROR 
  458 0153 91AE                 JSR WAIT ; ждем прихода в исходное состояние
  459 0154 000C                 RTS        
  460                   
  461                   ; ******************************************************************
  462                   
  463                   WR_SC:  ; Процедура передачи байта скан-кода
  464                           ; Чтобы перейти в режим передачи данных, нужно удерживать 0 на линии
  465                           ; CLK не менее 60 мкс. На всякий случай будем держать 0 80 мкс.
  466                           ; 80 это 320 команд (640 тактов) при F=8 МГц
  467                   
  468 0155 4569                 MOVL %B1,00101011B ; будем писать в подрегистр типа вывода порта A
  469 0156 43C9                 MOVL %B1,00011110B
  470 0157 2901                 BICL %A1,1000B
  471 0158 2A21                 BICH %A1,0001B     ; выдаем 0 в CLK и DATA
  472                   
  473 0159 4810                 MOVL %C0,64 ; Ждем 64*5=320 команд 
  474 015A 0000         REPL:   NOP        
  475 015B 0000                 NOP
  476 015C 0000                 NOP
  477 015D 2C30                 DEC %C0
  478 015E B15A                 JNZ REPL;
  479                           
  480 015F 3A21                 BISH %A1,0001B ; снимаем 0 CLK
  481 0160 4569                 MOVL %B1,00101011B ; будем писать в подрегистр типа вывода порта A
  482 0161 41C9                 MOVL %B1,00001110B ; переводим CLK на чтение
  483 0162 2901                 BICL %A1,1000B
  484 0163 4010                 MOVL %C0,0 ; это будет счетчик единичных битов для формирования
  485                                      ; бита четности
  486                                   
  487 0164 5FF7         W1:     MOVL %C7,255   ; ждем 0, т.е. начала тактирования процесса
  488 0165 3621         W2:     BTTH %A1,0001B
  489 0166 A16E                 JZ E1
  490 0167 0000                 NOP
  491 0168 0000                 NOP
  492 0169 0000                 NOP
  493 016A 0000                 NOP
  494 016B 0000                 NOP
  495 016C 2C37                 DEC %C7
  496 016D B165                 JNZ W2
  497                   E1:
  498                                      ; передачи данных девайсом
  499 016E 4112                 MOVL %C2,8 ; будем передавать 8 бит
  500                   WR_0:              ; передаем бит
  501                   
  502 016F 00B3         WR1:    SHR %C3
  503 0170 F173                 JC WR2
  504 0171 2901                 BICL %A1,1000B
  505 0172 8175                 JMP WR3
  506                   
  507 0173 3901         WR2:    BISL %A1,1000B
  508 0174 3030                 INC %C0         ; добавляем 1 к счетчику
  509 0175 3621         WR3:    BTTH %A1,0001B  ; ждем 1 на CLK
  510 0176 A175                 JZ WR3;
  511                   
  512                            ; ожидаем защелкивания бита данных девайсом и его
  513                            ; готовности к приему следующего бита (0 на CLK)
  514                   
  515 0177 5FF7                 MOVL %C7,255
  516 0178 3621         WW2:    BTTH %A1,0001B
  517 0179 A181                 JZ EE1
  518 017A 0000                 NOP
  519 017B 0000                 NOP
  520 017C 0000                 NOP
  521 017D 0000                 NOP
  522 017E 0000                 NOP
  523 017F 2C37                 DEC %C7
  524 0180 B178                 JNZ WW2
  525                   
  526 0181 2C32         EE1:    DEC %C2
  527 0182 B16F                 JNZ WR_0 
  528                           
  529                                    ; Байт скан-кода вроде бы передали, теперь надо передать бит
  530                                    ; четности и затем принять стоповый бит. Мля, ну какие же
  531                                    ; ламеры придумали этот PS2 интерфейс :-E
  532                   
  533 0183 4013                 MOVL %C3,0
  534 0184 00B0                 SHR %C0  ; Значение бита четности берем из 0-го разряда %C0
  535 0185 E187                 JNC BCNZ ; Если бит четности =0
  536 0186 3833                 BISL %C3,1 ; если бит четности =1
  537                   
  538                   BCNZ:   ; передаем 
  539                   
  540 0187 00B3                 SHR %C3
  541 0188 F18B                 JC WRR2
  542 0189 2901                 BICL %A1,1000B
  543 018A 818D                 JMP WRR3
  544                   
  545 018B 3901         WRR2:   BISL %A1,1000B
  546 018C 3030                 INC %C0   ; добавляем 1 к счетчику
  547                   
  548                   WRR3:   ; ждем 1
  549 018D 3621                 BTTH %A1,0001B
  550 018E A18D                 JZ WRR3;
  551                   
  552                           ; ожидаем защелкивания бита данных девайсом и его
  553                           ; готовности к приему следующего бита
  554                   
  555 018F 5FF7                 MOVL %C7,255   ; ждем 0
  556 0190 3621         WWA1:   BTTH %A1,0001B
  557 0191 A199                 JZ EEX
  558 0192 0000                 NOP
  559 0193 0000                 NOP
  560 0194 0000                 NOP
  561 0195 0000                 NOP
  562 0196 0000                 NOP
  563 0197 2C37                 DEC %C7
  564 0198 B190                 JNZ WWA1
  565                   
  566 0199 4569         EEX:    MOVL %B1,00101011B ; будем писать в подрегистр типа вывода порта A
  567 019A 40C9                 MOVL %B1,00000110B ; переводим DATA на чтение
  568                           
  569                   IT:     ; ждем 1
  570 019B 3621                 BTTH %A1,0001B
  571 019C A19B                 JZ IT;
  572                           
  573 019D 91B2                 JSR WAIT1 ; ожидаем приход стопового бита
  574                   
  575                   
  576 019E 5FF7                 MOVL %C7,255   ; ждем 0
  577 019F 3621         AWA1:   BTTH %A1,0001B
  578 01A0 A1A8                 JZ WEX
  579 01A1 0000                 NOP
  580 01A2 0000                 NOP
  581 01A3 0000                 NOP
  582 01A4 0000                 NOP
  583 01A5 0000                 NOP
  584 01A6 2C37                 DEC %C7
  585 01A7 B19F                 JNZ AWA1
  586                   
  587 01A8 0431         WEX:    MOV %C1,%A1
  588 01A9 3511                 BTTL %C1,1000B ; проверяем стоповый бит
  589                                          ; только непонятно, зачем 
  590                   
  591                   HT:     ; ждем 1
  592 01AA 3621                 BTTH %A1,0001B
  593 01AB A1AA                 JZ HT;
  594 01AC 000C                 RTS        
  595                   
  596 01AD 4013         ERROR:  MOVL %C3,0
  597                   
  598 01AE 0431         WAIT:   MOV %C1,%A1    ; ждем 1
  599 01AF 3631                 BTTH %C1,0001B
  600 01B0 A1AE                 JZ WAIT;
  601 01B1 000C                 RTS
  602 01B2 5FF7         WAIT1:  MOVL %C7,255   ; ждем 0
  603 01B3 0431         WAI1:   MOV %C1,%A1
  604 01B4 3631                 BTTH %C1,0001B
  605 01B5 A1BE                 JZ EXIT1
  606 01B6 0000                 NOP
  607 01B7 0000                 NOP
  608 01B8 0000                 NOP
  609 01B9 0000                 NOP
  610 01BA 0000                 NOP
  611 01BB 2C37                 DEC %C7
  612 01BC B1B3                 JNZ WAI1
  613 01BD 81AD                 JMP ERROR
  614 01BE 000C         EXIT1:  RTS
  615                   
  616                   ; ********************
  617                   
  618 01BF 2039         WRFLSH: LDR #B,56  ; адрес регистра управления блока ЭСППЗУ данных
  619 01C0 4009                 MOVL %B1,0 ; адрес ячейки = 0 (используем только один байт)
  620 01C1 070F                 MOV %B7,%D0
  621 01C2 4028                 MOVL %B0,00000001B
  622 01C3 3428         WRF1:   BTTL %B0,0001B
  623 01C4 B1C3                 JNZ WRF1 ; ждем, пока происходит запись
  624 01C5 2019                 LDR #B,18H
  625 01C6 000C                 RTS
  626                   
  627                   ; ********************
  628                   
  629 01C7 2039         RDFLSH: LDR #B,56  ; адрес регистра управления блока ЭСППЗУ данных
  630 01C8 4009                 MOVL %B1,0 ; адрес ячейки = 0 (используем только один байт)
  631 01C9 4048                 MOVL %B0,00000010B
  632 01CA 3448         RDF1:   BTTL %B0,0010B
  633 01CB B1CA                 JNZ RDF1 ; ждем, пока происходит чтение
  634 01CC 05F8                 MOV %D0,%B7
  635 01CD 2019                 LDR #B,18H
  636 01CE 000C                 RTS
  637                   
  638                   ; ********************
  639 01CF 4769         INIT:   MOVL %B1,00111011B ; Установка конфигурации порта A
  640 01D0 40C9                 MOVL %B1,00000110B
  641 01D1 43E9                 MOVL %B1,00011111B
  642 01D2 4009                 MOVL %B1,00000000B
  643 01D3 4009                 MOVL %B1,00000000B
  644 01D4 4029                 MOVL %B1,00000001B ; прерывание по отрицательному перепаду уровня
  645                                              ; на линии CLK_KEY  для опроса клавиатуры
  646                   
  647 01D5 0188                 STIE
  648                   
  649 01D6 436A                 MOVL %B2,00011011B ; Установка конфигурации порта B
  650 01D7 5FEA                 MOVL %B2,11111111B
  651 01D8 5FEA                 MOVL %B2,11111111B
  652 01D9 400A                 MOVL %B2,0
  653 01DA 400A                 MOVL %B2,0
  654 01DB 400A                 MOVL %B2,0
  655                   
  656 01DC 3841                 BISL %A1,0010B     ; выдаем 1 на линию сброса регистров в ПЛИС
  657 01DD 2881                 BICL %A1,0100B     ; выдаем 0 на линию STROBE
  658                   
  659 01DE 401D                 MOVL %D5,0         ; флажок (потом пригодится)
  660 01DF 000C                 RTS
  661                   
  662                   KEYINI:                   ; инициализация матрицы клавиатуры
  663 01E0 2049                 LDR #B,72         ; весь буфер из 5-и байтов заполняем
  664 01E1 5FE8                 MOVL %B0,11111111B ; значениями 255
  665 01E2 5FE9                 MOVL %B1,11111111B
  666 01E3 5FEA                 MOVL %B2,11111111B
  667 01E4 5FEB                 MOVL %B3,11111111B
  668 01E5 5FEC                 MOVL %B4,11111111B
  669 01E6 2019                 LDR #B,18H
  670 01E7 905B                 JSR VYVOD
  671 01E8 000C                 RTS
  672                   
  673                   ; здесь надо бы отключать клавиатуру - потом поправлю
  674                   
  675 01E9 401C         MOUSINI:MOVL %D4,0
  676 01EA 2049                 LDR #B,72
  677 01EB 4FAD                 MOVL %B5,125
  678 01EC 4FAE                 MOVL %B6,125
  679 01ED 5FEF                 MOVL %B7,255
  680 01EE 2019                 LDR #B,18H
  681 01EF 91AE                 JSR WAIT           ; мышь подключили. Теперь ожидаем ее готовность
  682                                              ; Теперь нужно передать в мышь команду запроса
  683                                              ; ее состояния (здесь неудобно использовать
  684                                              ; потоковый режим, хотя, в принципе, можно)
  685 01F0 5E13                 MOVL %C3,11110000B ; код команды перехода в REMOTE MODE
  686 01F1 9155                 JSR WR_SC
  687 01F2 9116                 JSR MORE           ; принимаем код подтверждения 
  688 01F3 7F53                 CMPL %C3,11111010B 
  689 01F4 B1FC                 JNZ MOUSOFF       ; ERROR 
  690 01F5 5E73                 MOVL %C3,11110011B
  691 01F6 9155                 JSR WR_SC
  692 01F7 9116                 JSR MORE
  693 01F8 4513                 MOVL %C3,40
  694 01F9 9155                 JSR WR_SC
  695 01FA 9116                 JSR MORE        
  696 01FB 000C                 RTS
  697                   
  698 01FC 5FFC         MOUSOFF:MOVL %D4,255
  699 01FD 000C                 RTS
  700                   
  701                   TIMER:                     ; мышку будем опрашивать по прерываниям от таймера
  702 01FE 4244                 MOVL %A4,00010010B ; подключаем регистр конфигурации к адресу 5 
  703 01FF 49C5                 MOVL %A5,01001110B ; задаем коэффициент деления тактовой частоты 1/128
  704 0200 4044                 MOVL %A4,00000010B ; подключаем регистр интервала (LOW) к адресу 5
  705 0201 4E25                 MOVL %A5,113
  706 0202 40C4                 MOVL %A4,00000110B ; подключаем регистр интервала (HI) к адресу 5
  707 0203 4045                 MOVL %A5,2         ; итак, получили полный коэффициент
  708                                              ; деления 128*(2?4?*256+113)=80000, прерывания от
  709                                              ; таймера будут идти с частотой Fтакт/80000=100 Гц
  710 0204 4064                 MOVL %A4,00000011B ; пускаем таймер на счет
  711 0205 0188                 STIE               ; разрешаем прерывания
  712 0206 000C                 RTS
  713                   
  714                   
  715 0207 2841         REST:   BICL %A1,0010B   
  716 0208 0000                 NOP
  717 0209 0000                 NOP
  718 020A 3881                 BISL %A1,0100B 
  719 020B 5FF3                 MOVL %C3,255
  720 020C 5FF4         TRMZ0:  MOVL %C4,255
  721 020D 43D5         TRMZ1:  MOVL %C5,30
  722 020E 2C35         TRMZ2:  DEC %C5
  723 020F B20E                 JNZ TRMZ2
  724 0210 2C34                 DEC %C4
  725 0211 B20D                 JNZ TRMZ1
  726 0212 2C33                 DEC %C3
  727 0213 B20C                 JNZ TRMZ0
  728 0214 2881                 BICL %A1,0100B 
  729 0215 0000                 NOP
  730 0216 0000                 NOP
  731 0217 3841                 BISL %A1,0010B
  732 0218 0002                 RST
  733 0219 801B                 JMP START
  734                   
  735 021A 0002         STERR:  RST
  736 021B 801B                 JMP START
  737                              
  738 021C              SCODE:  .BYTE 12H,1CH,15H,16H,45H,4DH,5AH,29H
  739                           .EVEN; байт 0: CS,A,Q,1,0,P,ENT,SPACE
  740                   
  741 0220                      .BYTE 1AH,1BH,1DH,1EH,46H,44H,4BH,11H
  742                           .EVEN; байт 1: Z,S,W,2,9,O,L,SS
  743                   
  744 0224                      .BYTE 22H,23H,24H,26H,3EH,43H,42H,3AH
  745                           .EVEN; байт 2: X,D,E,3,8,I,K,M
  746                   
  747 0228                      .BYTE 21H,2BH,2DH,25H,3DH,3CH,3BH,31H
  748                           .EVEN; байт 3: C,F,R,4,7,U,J,N
  749                   
  750 022C                      .BYTE 2AH,34H,2CH,2EH,36H,35H,33H,32H
  751                           .EVEN; байт 4: V,G,T,5,6,Y,H,B
  752                   
  753                   .END;