Subversion Repositories atmturbo

Rev

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

  1. ;************************************************
  2. ; Контроллер AT-клавиатуры на 51-ом контроллере *
  3. ;************************************************
  4. $mod52
  5. debug   equ     1
  6. ;================================================
  7. ; Длительность сигнала /WR на выводе контроллера
  8. ; по команде movx равна 6 тактам генератора.
  9. ; При высокой тактовой частоте этой длительности
  10. ; не хватает для надежного чтения кода с шины Z80.
  11. ; Если использовать прямое управление битом /WR,
  12. ; то длительность сигнала будет равна 12 тактам.
  13. en_movx equ     0       ;1 - разрешена movx
  14.                         ;0 - прямое управление
  15. ; разрешение работы с прерыванием
  16. en_int  equ     0       ;0 - не разрешен
  17. ; Флаги тактовой частоты микроконтроллера
  18. ft_07   equ     0       ;7 Мгц
  19. ft_11   equ     1       ;11.0592 Мгц
  20. ft_12   equ     0       ;12 Мгц
  21. ft_24   equ     0       ;24 Мгц
  22. ;------------------------------------------
  23. ; R1 - предыдущий code key
  24. ; R2 - текущий code key
  25. ; R3 - flags
  26. ;       d0 - Left Shift
  27. ;       d1 - Ctrl
  28. ;       d2 - ALT
  29. ;       d3
  30. ;       d4 - Caps Lock trigger
  31. ;       d5 - Num Lock trigger
  32. ;       d6 - Scroll Lock trigger
  33. ;       d7 - RUS(1)/LAT(0)
  34. ; R4 -  d0 - Right Shift
  35. ;-------------------------------------------
  36. ; ПОРТЫ
  37. ; порт P1(A)
  38. RS_CD   equ     P1.0    ; PA0 - CD     input
  39. RS_CTS  equ     P1.1    ; PA1 - CTS    input
  40. RS_RI   equ     P1.2    ; PA2 - RI     input
  41. RS_DTR  equ     P1.3    ; PA3 - DTR    out
  42. RS_RTS  equ     P1.4    ; PA4 - RTS    out
  43. SP_INT  equ     P1.5    ; PA5 - INT_T  out
  44. SP_RES  equ     P1.6    ; PA6 - /RES  -out
  45. SP_WT   equ     P1.7    ; PA7 - W_ON  -out
  46. ; порт P3
  47. RS_RX   equ     P3.0    ; P30 - RX     input
  48. RS_TX   equ     P3.1    ; P31 - TX    -output
  49. KB_CLK  equ     P3.2    ; P32 - CLK_K  input    INT0
  50. SP_KBD  equ     P3.3    ; P33 - /KEYRD inpit    INT1
  51. SP_VE1  equ     P3.4    ; P34 - VE1    input
  52. KB_DAT  equ     P3.5    ; P35 - DATA_K input
  53. VWR     equ     P3.6    ; P36 - /VWR  -output
  54. VRD     equ     P3.7    ; P37 - /VRD  -output
  55. ;-----------------------------------------
  56.         dseg
  57.         org     00h
  58. ; PAGE 00 - главная страница
  59. R0_00:  ds 1            ;R0
  60. R1_00:  ds 1            ;R1 запомненный spec-cod
  61. R2_00:  ds 1            ;R2 текущий spec-cod
  62. R3_00:  ds 1            ;R3 флаги 1 служ.клавиш
  63. R4_00:  ds 1            ;R4 флаги 2 служ.клавиш
  64. R5_00:  ds 1            ;R5 текущий скан-код
  65. R6_00:  ds 1            ;R6 флаг префикса
  66. R7_00:  ds 1            ;R7
  67. ;---------------------------
  68. ; PAGE 08 - страница /RDKBD
  69.         ds 8            ;R0..R7
  70. ;---------------------------
  71. ; PAGE 10 - страница /CLK_K
  72. R0_10:  ds 1            ;R0
  73. R1_10:  ds 1            ;R1
  74.         ds 5            ;R2..R6
  75. R7_10:  ds 1            ;R7
  76. ;---------------------------
  77. ; PAGE 18 - страница RTC и Serial
  78. adr_rt: ds 1            ;R0 - указатель RTC
  79. adr_rs: ds 1            ;R1 - указатель приема RS232
  80.         ds 1            ;R2 - RTC
  81.         ds 1            ;R3 - RTC
  82. adr_rd: ds 1            ;R4 - указатель буфера приема
  83. cnt_rd: ds 1            ;R5 - счетчик приема
  84. cnt_wr: ds 1            ;R6 - счетчик передачи
  85. rtc_to: ds 1            ;R7 - RTC time-out
  86. ;--------------------------------------------
  87.         org     20h
  88. b_sadr: ds 1            ;буфер скан-адреса
  89. mode:   ds 1            ;режим контроллера
  90. ;--------------------------------
  91. flags:          ds 1
  92. f_wait    equ   flags.0 ;флаг ПАУЗА
  93. f_unpres  equ   flags.1 ;флаг отжатия клавиши
  94. f_pref    equ   flags.2 ;флаг префикса E0h
  95. f_press   equ   flags.3 ;
  96. f_decod   equ   flags.5 ;
  97. ;
  98. stat_md:        ds 1    ;текущий статус модема
  99. stat_rs:        ds 1    ;текущий статус RS232
  100. f_int     equ   stat_rs.7
  101. ;--------------------------------
  102. adr_wr: ds 1            ;текущий адрес в буфере передатчика
  103. adr_ws: ds 1            ;текущий адрес для записи в буф.
  104. ;
  105. t_res:  ds 3            ;адрес контрольной строки
  106. ;
  107. len_bwr equ     8
  108. buf_wr:         ds len_bwr      ;буфер передачи
  109. ;
  110. len_brd equ     54              ;Длина буфера приема
  111. len_ird equ     50              ;длина буфера для INT (если разрешен)
  112. buf_rd:         ds len_brd      ;буфер приема
  113.                 ds 0
  114. ;--------------------------------
  115.         org     128-8-16
  116. ; Bufer KBD
  117. buf_kbd:        ds 8            ;Буфер клавиатуры
  118. ; Буфер часов
  119. tics:           ds 1            ;50 тиков в секунду
  120. b_time:         ds 3            ;секунды,минуты,часы
  121. b_date:         ds 4            ;день,месяц,год,столетие
  122. b_stek:         ds 8            ;стек -> вверх
  123. ;_________________________________________
  124. ; Часы реального времени
  125. f_tic   equ     50      ;Частота тиков Ч.Р.В  (Гц)
  126. ;f_proc equ     7000    ;Частота тактирования (КГц)
  127. ; Коэфф.деления таймера 0 равен
  128. ;KF_T0  equ     -f_proc*1000/12/f_tic
  129.  if ft_07
  130. KF_T0   equ     0D26Eh  ; 7.0000 Мгц
  131.  endif
  132.  if ft_11
  133. KF_T0   equ     0B800h  ;11.0592 МГц
  134.  endif
  135.  if ft_12
  136. KF_T0   equ     0B1E0h  ;12.0000 МГц
  137.  endif
  138.  if ft_24
  139. KF_T0   equ     063C0h  ;24.0000 МГц
  140.  endif
  141. ;*****************************************
  142. ;**     НАЧАЛО КОДОВОГО СЕГМЕНТА        **
  143. ;*****************************************
  144. CSEG
  145.         ORG     000h
  146. ;-----------------------------------------
  147. ; Стартовый адрес
  148. start:  ljmp    prog    ;-> запуск программы
  149. ; ========================================
  150.         ORG     003h
  151. ; External interrupt 0 ~\_
  152. extint0:
  153.         push    PSW
  154.         push    ACC
  155.         ajmp    L_23C   ; int /CLK_K
  156. ; ========================================
  157.         ORG     00Bh
  158. ; Timer interrupt 0 (Часы реального времени)
  159. timint0:
  160.         push    PSW
  161.         push    ACC
  162.         ajmp    int_rtc ;
  163. ; ========================================
  164.         ORG     013h
  165. ; External interrupt 1 ~\_ (Чтение порта KBD)
  166. extint1:                ;2
  167.         push    PSW     ;2
  168.         push    ACC     ;2
  169.         push    DPH     ;2
  170.         ajmp    RD_KBD  ;2  int /RDKEY
  171. ; ========================================
  172.         ORG     01Bh
  173. ; Timer interrupt 1
  174. timint1:reti
  175. ; ========================================
  176.         ORG     023h
  177. ; Serial port interrupt (SERIAL)
  178. serint: push    PSW
  179.         push    ACC
  180.         mov     PSW,#18h        ;PAGE 18
  181.         ajmp    ser_int
  182. ; ========================================
  183.         ORG     02Ch
  184. ; Ver 3.1xx
  185. VERS:   db      3,1             ;3.1
  186.  if ft_07
  187.         db      0,7     ;Тактовая Частота в МГц
  188.  endif
  189.  if ft_11
  190.         db      1,1     ;Тактовая Частота в МГц
  191.  endif
  192.  if ft_12
  193.         db      1,2     ;Тактовая Частота в МГц
  194.  endif
  195.  if ft_24
  196.         db      2,4     ;Тактовая Частота в МГц
  197.  endif
  198. ;**********************************************
  199. t_10    equ     10*4    ;10 мсек (40*0.25 мсек)
  200. ; Константа для 250 мксек зависит от такт. частоты
  201.  if ft_07
  202. t_025   equ     73      ;Ft=7 Мгц
  203.  endif
  204.  if ft_11
  205. t_025   equ     115     ;Ft=11.0592 Мгц
  206.  endif
  207.  if ft_12
  208. t_025   equ     125     ;Ft=12 Мгц
  209.  endif
  210.  if ft_24
  211. t_025   equ     250     ;Ft=24 Мгц
  212.  endif
  213. ;
  214. ;*********************************************
  215. ;******* START PROGRAMM **********************
  216. ;*********************************************
  217. ; Сброс при первом включении
  218. reset:  mov     R0,#t_res       ;Буфер контр.строки
  219.         mov     @R0,#'A'
  220.         inc     R0
  221.         mov     @R0,#'T'
  222.         inc     R0
  223.         mov     @R0,#'M'
  224.         mov     P1, #0BFh       ;/RESET=0 (PA6=0)
  225.         ajmp    $               ; ждем СБРОСА
  226. ;=============================================
  227. ; Вход по включению питания
  228. prog:   mov     P1, #0FFh       ;/RESET=1;W_ON=1
  229.         mov     SP, #b_stek     ;Указатель стека
  230.         mov     PSW,#00h
  231. ;       call    del_10ms        ; Пауза 10 мсек
  232. del_10ms:
  233.         mov     R1,#t_10        ;Константа для 10 мсек
  234. c_del:  mov     R0,#t_025       ;Константа для 250 мксек
  235.         djnz    R0,$            ;t_05*2*12/Ft
  236.         djnz    R1,c_del
  237. ; При первом включении выдать /RESET
  238.         mov     R0,#t_res       ;буфер контрольной строки
  239.         cjne    @R0,#'A',reset  ;
  240.         inc     R0
  241.         cjne    @R0,#'T',reset  ;
  242.         inc     R0
  243.         cjne    @R0,#'M',reset  ;
  244. ;--------------------------------
  245. ; ИНИЦИАЛИЗАЦИЯ УЗЛОВ КОНТРОЛЛЕРА
  246.         mov     SCON, #50h      ; Serial Port Control
  247.                                 ;UART 8-бит, REN=1
  248.         mov     TMOD, #21h      ;Timer1=mode2  8-бит
  249.                                 ;Timer0=mode1 16-бит
  250. ; Set Timer 0 (50 Герц)
  251.         call    set_T0          ;
  252.         mov     TCON, #55h      ;Timer0,1-On/INT0,1 -Impuls
  253. ; Init MEM; 00h -> RAM 02h..38h
  254.         mov     R0, #02h        ;от 02h
  255.         mov     R1, #36h        ; до 38h
  256.         clr     A               ;
  257. c_clr:  mov     @R0, A          ; обнулить
  258.         inc     R0
  259.         djnz    R1,c_clr        ;
  260. ;-----------------------------------------------
  261. ; Установка скорости работы RS232
  262.         mov     R6,#6           ;19200 бод
  263.         acall   set_speed
  264. ;
  265.         mov     IP,#01h         ; Interrupt Priority
  266.         mov     IE,#97h         ; Interrupt Enable INT0,1,T0,USART
  267.         mov     P1,#7Fh         ; P1.7 -> Разрешить /WAIT (W_ON=0)
  268.  if debug
  269.         mov     P2,#00h
  270.  endif  
  271.         clr     VWR
  272.         setb    VWR
  273. ;/======================================================\
  274. c0main: acall   clr_buf         ; Clear buf KBD
  275. ;/-------------------------------
  276. ; Main Cikl Wait press key
  277. c_main:
  278.  if en_int      ;проверка разрешения работы по прерываниям
  279. ; проверить флаг включения INT по RS232
  280.         jnb     f_int,no_int    ;INT не разрешен
  281. ; если флаг установлен, проверить превышение счетчика
  282.         setb    SP_INT          ;P1.5   INT_T=1
  283.         mov     A,cnt_rd        ;счетчик приема RS232
  284.         cjne    A,#len_ird,no_int
  285. ; включить прерывание если в буфере слишком много данных
  286.         clr     SP_INT          ;P1.5   INT_T=0
  287. ;------
  288. no_int:
  289.  endif
  290.         mov     R6, #0          ; Флаг Префикса E0h
  291.         acall   L_102           ; Wait Code KBD
  292.         cjne    R5, #0E1h, L_66 ; Pause/Break ?
  293. ; Принят первый скан-код клавиши PAUSE
  294. ; Press Pause/Break [E1,14,77,E1,F0,14,F0,77]
  295.         mov     R0, #7-2        ; Count Code (-2 кода F0)
  296. ;//---
  297. L_5C:   acall   L_102           ; Wait Code KBD
  298.         djnz    R0, L_5C        ; ждать 5 кодов + 2 префикса
  299. ;\\---
  300. ; Переключиться в режим <ПАУЗА> для чего надо
  301. ; запретить прерывание по /RDKBD (INT1)
  302.         clr     EX1             ; Запретить INT1
  303.         setb    f_wait          ; Flag Wait = 1
  304.         sjmp    c_main          ; Ждать нажатий
  305. ;\---------------------------------------------
  306. ; Проверить на допустимость скан-кода
  307. L_66:   clr     C
  308.         mov     A, R5
  309.         subb    A, #84h         ; Scan-Code >= 84h
  310.         jnc     c0main          ;       err code kbd
  311. ; Scan-code normal 0..83h
  312.         jnb     f_wait, L_7D    ; Нет Pause
  313. ; Если был включен режим Pause - сбросить
  314.         clr     f_press         ; Clear Flag Press
  315.         clr     f_wait          ; Clear Flag Wait
  316.         mov     DPTR, #0        ;
  317.         movx    @DPTR, A        ; /VWR=0 (сброс /WAIT)
  318.         setb    EX1             ; Разрешить INT1
  319.         sjmp    c0main          ; Ждать еще нажатия
  320. ;\==================================================
  321. ; Press new key
  322. L_7D:   mov     A, R5           ; =Scan-code AT IBM
  323.         mov     DPTR, #at2xt    ; Таблица перекодировки
  324.         movc    A, @A+DPTR      ;code set2(AT) -> set1(XT)
  325.         jz      c_main          ; если 00h -> non code
  326. ;\-------------------------------
  327. ; Yes normal scan-code set1
  328.         mov     R7, A           ; R7 = scan code set1(XT)
  329.         jnb     f_unpres,no_unpres ;клавиша нажата
  330. ; клавиша отпущена
  331.         orl     R7_00,#80h      ;установить бит отжатия
  332. no_unpres:
  333.         mov     R7_10,R7        ;запомнить скан-код set1
  334.         dec     A
  335.         mov     R5, A           ; R5 = scan code - 1
  336. ;
  337.         mov     A, mode         ;Mode
  338.         jnz     L_AC            ;не 00h
  339. ; Mode = 00 (Spectrum KBD)
  340.         mov     A, R5           ;(Number key-1) (0..
  341.         mov     DPTR, #L_527    ;Code XT -> Code Spec
  342.         movc    A, @A+DPTR      ; -> Code key
  343.         mov     R1, A
  344.         acall   L_134           ;code key -> bufer KBD
  345. ;/---- проверить буфер на предмет нажатых клавиш
  346.         mov     R0, #buf_kbd
  347.         mov     R1, #8
  348.         mov     A, #0FFh
  349. L_9D:   anl     A, @R0
  350.         inc     R0
  351.         djnz    R1, L_9D
  352. ;\----
  353.         xrl     A, #1Fh
  354.         anl     A, #1Fh
  355. ; No press key если код = 00h
  356.         clr     f_press         ;=0
  357.         jz      L_B6            ; No press KBD
  358. ; Yes press key
  359. L_AC:   setb    f_press         ;=1
  360. ;==============================================
  361. ; mode non Spectrum KBD
  362. L_B6:   mov     A, R2
  363.         mov     R1, A           ;R1=R2 - предыдущий код клавиши
  364.         setb    f_decod         ;
  365. ; Началось декодирование скан-кода клавиатуры IBM
  366.         mov     A, R5           ;
  367.         rl      A               ;
  368.         mov     R5, A           ;R5=Scan-code*2
  369.         mov     DPTR, #L_471
  370.         jb      f_unpres, L_C9  ;Клавиша отжата
  371. ;----
  372. ; new code key press
  373.         movc    A, @A+DPTR      ;Scan-code -> Sym Code
  374.         jz      L_C9
  375. ;
  376.         mov     R2, A           ;R2_00=Sym-code 1
  377. ;----
  378. ; code key unpress
  379. L_C9:   mov     A, R5           ;
  380.         inc     A
  381.         movc    A, @A+DPTR
  382.         mov     R5, A           ;R5=Sym-code 2
  383.         acall   L_16A           ;Decode
  384.         clr     f_decod
  385. ;
  386.         ajmp    c_main          ;Wait next key
  387. ;\--------------
  388. ;****************************************************
  389. ; Процедура приема скан-кода нажатой клавиши ********
  390. L_100:  acall   clr_buf         ; Clear Buf KBD
  391. ;/-----
  392. ;       Wait Code KBD
  393. L_102:  clr     f_unpres        ; Flag unpress = 0
  394. ;//----
  395. ; wait code after prefix 0E0h или 0F0h
  396. L_104:  mov     A, R0_10        ; R0 page 10 # 0?
  397.         jnz     L_11E           ; yes new code
  398. ; Bufer code KBD empty
  399. L_108:  mov     A, R1_10        ; R1 page 10 = 0?
  400.         jz      L_108           ; Wait begin resive
  401. ;\----
  402.         mov     rtc_to, #3      ; R7 page 18=3
  403. ;//----
  404. L_10F:  mov     A, R0_10        ; R0 page 10
  405.         jnz     L_11E           ; yes code key
  406. ;
  407.         mov     A, rtc_to       ;
  408.         jnz     L_10F           ; wait code
  409. ;\\---- истек тайм-аут приема скан-кода -----
  410.         mov     R0_10, A        ; 00h -> R0 page 10
  411.         mov     R1_10, A        ; 00h -> R1 page 10
  412.         mov     R6, A           ; 00h -> R6
  413.         sjmp    L_102           ; wait new code
  414. ;\------
  415. ; принят скан-код клавиатуры
  416. L_11E:  mov     R5, A           ; Get code KBD
  417.         mov     R0_10, #0       ; 00h -> R0 Page 10
  418.         cjne    A, #0E0h, L_129
  419. ; Пнринят префикс 0E0h - запомнить и принять след.
  420.         mov     R6, #1          ; flag prefix key
  421.         sjmp    L_104           ; Get Second code
  422. ;\-------------------------------
  423. ; NO prefix = 0E0h
  424. L_129:  cjne    A, #0F0h, L_130
  425. ; Resive ptefix 0F0h (unpress)
  426.         setb    f_unpres        ; Flag unpress=1
  427.         sjmp    L_104           ;Get second code
  428. ;\-------------------------------
  429. ; No prefix 0E0h & 0F0h
  430. L_130:  inc     A               ;если = 0FFh
  431.         jz      L_100           ;err code
  432.         ret
  433. ; Конец процедуры приема скан-кода клавиатуры ***
  434. ;************************************************
  435. ; R1 (code key) -> bufer Spectrum KBD
  436. ; f_unpress = 1 - clear code from bufer
  437. L_134:  mov     A, R1           ;
  438.         jnb     ACC.3, L_13E    ;Флаг Caps Shift = 0
  439. ; ACC.3 = 1 -> Caps Shift
  440.         mov     A, #1           ;D0
  441.         mov     R0, #0          ;A8
  442.         acall   L_15D           ;Добавить Caps Shift
  443. ; ACC.3 = 0
  444. L_13E:  mov     A, R1
  445.         jnb     ACC.7, L_148    ;Флаг Symbol Shift = 0
  446. ; ACC.7 = 1 -> Symbol Shift
  447.         mov     A, #2           ;D1
  448.         mov     R0, #7          ;A15
  449.         acall   L_15D           ;Добавить Symbol Shift
  450. ; ACC.7 = 0
  451. L_148:  mov     A, R1
  452.         anl     A, #7           ;Номер бита шины данных
  453.         jnz     L_14E           ;1..5
  454. ; d2..d0 = 000
  455.         ret                     ;
  456. ; d2..d0 <> 000 (биты шины данных 1-> D0)
  457. L_14E:  mov     R0, A           ;1..
  458.         clr     A
  459.         setb    C               ;CY=1
  460. L_151:  rlc     A               ;
  461.         djnz    R0, L_151       ;
  462. ; в ACC 1 записана в бит с номером [(d2..d0)-1]
  463.         push    ACC
  464.         mov     A, R1
  465.         swap    A
  466.         anl     A, #7           ;
  467.         mov     R0, A           ;Adress
  468.         pop     ACC             ;Date
  469. ;-----
  470. L_15D:  orl     R0_00, #buf_kbd ;R0=адресная шина
  471.         jnb     f_unpres, L_166 ;клавиша отжата
  472. ; Press key  - set code
  473.         orl     A, @R0          ;добавить бит клавиши
  474.         mov     @R0, A
  475.         ret
  476. ; Unpress key - clear code from bufer
  477. L_166:  cpl     A
  478.         anl     A, @R0
  479.         mov     @R0, A
  480.         ret
  481. ; end mode Spectrum KBD
  482. ; ========================================
  483. ; DECODE Second byte in Tab
  484. ; R5 -> ctrl code (mode CP/M)
  485. ; R6=1 prefix 0E0h
  486. ;
  487. L_16A:  mov     A, R5           ;
  488.         jnz     L_16E
  489. ; 00h -> exit
  490. L_16D:  ret
  491. ;
  492. L_16E:  anl     A, #3           ;d1,d0
  493.         jnz     L_1A6           ;ALT,Ctrl,Shift
  494. ; d1,d0=00
  495.         jb      f_unpres, L_16D ;exit
  496. ;--------------
  497. ; press new key
  498.         mov     A, R5
  499.         anl     A, #0Ch         ;d3,d2
  500.         jnz     L_1D2
  501. ;d3,d2=00
  502.         mov     A, R5
  503.         anl     A, #30h         ;d5,d4
  504.         jnz     L_1E4           ;
  505. ;d5,d4=00
  506. L_17F:  mov     A, R5
  507.         jb      ACC.6, L_19F    ;*40h
  508. ;d6=0
  509.         jnb     ACC.7, L_16D    ;d7,d6=0 Exit
  510. ;d6=0,d7=1 (80h)
  511.         mov     A, R3
  512.         orl     A, R4
  513.         anl     A, #6
  514.         cjne    A, #6, L_192    ;bits Ctrl,Alt
  515. ; Ctrl+Alt
  516.         cjne    R2, #2Eh, L_16D ;Нажата [./Del]?
  517. ; + [./Del]
  518.         ajmp    reset           ;Reset COMP
  519. ;-------
  520. ; no Ctrl+Alt
  521. L_192:  cjne    R6, #1, L_1A2   ;set D7
  522. ; R6=1 (prefix 0E0h)
  523.         mov     A, R7           ;Scan code set1
  524.         clr     C
  525.         subb    A, #47h         ;-47h Код [dig.7]
  526.         mov     DPTR, #L_582    ;Таблица кодов упр.клавиш
  527.         movc    A, @A+DPTR
  528.         mov     R2, A           ;new code
  529.         ret
  530. ;-------
  531. ;^ D6=1
  532. L_19F:  mov     A, R6           ; R6=0?
  533.         jz      L_16D           ; exit
  534. ; R6=1 (prefix 0E0h)
  535. L_1A2:  orl     R2_00, #80h     ;set D7(R2)
  536.         ret
  537. ;----------
  538. ; d1,d0 <>0
  539. L_1A6:  anl     R7_00, #7Fh     ;R7(7)=0
  540.         cjne    A, #3, L_1FC
  541. ; R5=03h (Left Shift & Right Shift)
  542.         mov     A, #1           ;bit0 (Flag Shift)
  543.         mov     R6, #0
  544.         cjne    R7, #36h, L_1B5 ;Code set1 Right Shift ?
  545. ; press Right Shift
  546.         mov     R6, #1          ;Flag Right Shift=1
  547. L_1B5:  jnb     f_unpres, L_1C2
  548. ; key unpress
  549.         cpl     A
  550.         cjne    R6, #1, L_1BF
  551. ; R6=1 (Right Shift)
  552.         anl     R4_00,A ;R4(d0)=0
  553.         ret
  554. ; R6=0 (Left Shift)
  555. L_1BF:  anl     R3_00, A        ;R3(d0)=0
  556.         ret
  557. ; key press
  558. L_1C2:  cjne    R6, #1, L_1D4
  559. ; Right Shift
  560.         cjne    A, #1, L_1CE
  561. ; нажат Right Shift
  562.         mov     A, R3           ;Проверить Left Shift
  563.         anl     A,#1
  564.         jnz     L_1DC
  565. ; Left Shift еще не нажат
  566.         inc     A               ;A=1
  567. L_1CE:  orl     R4_00, A        ;R4 bit 0=1
  568.         sjmp    L_1EC
  569. ;------
  570. ;^ d3,d2<>0
  571. L_1D2:  sjmp    L_203
  572. ;--------------------------------
  573. ;
  574. L_1D4:  cjne    A, #1, L_1EA
  575. ; нажат Left Shift
  576.         mov     A,R4            ;проверить Right Shift
  577.         anl     A,#1
  578.         jz      L_1E8           ;еще не нажат
  579. ; был нажат
  580. L_1DC:  mov     R2, #7Ah        ;'z' (в XT R2) было R0
  581.         cpl     A
  582.         anl     R3_00, A        ;
  583.         anl     R4_00, A        ;
  584.         ret
  585. ;-------
  586. ;^ d5,d4<>0
  587. L_1E4:  sjmp    L_21A           ;test 20,30
  588. ;-------
  589. ;v non Ctrl+Alt
  590. L_1E6:  sjmp    L_17F
  591. ;--------------------------------
  592. ; Нажат Left Shift без Right Shift
  593. L_1E8:  mov     A, #1
  594. L_1EA:  orl     R3_00, A        ;R3(d0)=1
  595. ;
  596. L_1EC:  mov     A, R3
  597.         orl     A, R4
  598.         anl     A, #6
  599.         cjne    A, #6, L_1E6
  600. ; press Ctrl(d1)+Alt(d2)
  601.         cjne    R7, #53h, L_219 ;Scan-cod1 DEL =53h
  602. ; Ctrl+Alt+Del
  603.         ajmp    reset           ;Сброс Speccy
  604. ;-----
  605. L_1FC:  cjne    A, #1, L_1B5
  606. ; Code ALT = 1
  607.         mov     A, #4           ;bit2 (flag ALT)
  608.         sjmp    L_1B5
  609. ;------
  610. ;^ d3,d2<>0
  611. L_203:  jb      f_unpres, L_1E6 ;
  612. ; key press
  613.         cjne    A, #0Ch, L_20F  ;d3,d2=11
  614. ; A=0Ch (Scroll Lock)
  615.         cjne    R6, #1, L_20F
  616. ; R6=1 (prefix 0E0h)
  617.         mov     R2, #6Fh        ;'o'
  618.         ret
  619. ;-----
  620. L_20F:  rr      A               ;/2
  621.         rr      A               ;/4
  622.         mov     R5, A
  623.         mov     A, #8           ;bit3=1
  624. L_214:  rl      A
  625.         djnz    R5, L_214
  626. ; trigger bit
  627.         xrl     R3_00, A        ;R3
  628. L_219:  ret
  629. ;------
  630. ; второй код = 20h/30h
  631. L_21A:  cjne    A, #20h, L_21F
  632. ; A=20h
  633.         sjmp    L_1EC
  634. L_21F:  cjne    A, #30h, L_219  ;ret
  635. ; A=30h
  636. ; ========================================
  637. ; Clear buf KBD
  638. clr_buf:
  639.         mov     A, #0FFh
  640.         mov     R0, #buf_kbd
  641.         mov     R1, #8          ;8 байт
  642. L_228:  mov     @R0, A
  643.         inc     R0
  644.         djnz    R1, L_228
  645. ;\----
  646.         clr     A
  647.         clr     f_press
  648.         mov     R1_10, A        ;R1 page10=0
  649.         mov     R0_10, A        ;R0 page10=0
  650.         mov     R2, A
  651.         mov     R3, A
  652.         mov     R4, A
  653.         mov     R6, A
  654.         ret
  655. ; ==========================================
  656. ; Прием скан кода нажатой или отжатой клавиши
  657. ; CLK_KBD = ~\_
  658. L_23C:                  ; int0
  659.  if debug
  660.         mov     P2,#70h
  661.  endif
  662.         mov     PSW, #10h
  663. ;-----
  664.         mov     C, P3.5 ; P3.5 <- DAT_KBD
  665.         mov     A, R1
  666.         jz      L_257   ;R1=0 START
  667. ;-----
  668.         dec     A
  669.         jz      L_25B   ;R1=1 Прием данных
  670. ;-----
  671.         dec     A
  672.         jz      L_266   ;R1=2 Паритет
  673. ;-----                  ;R1=3 STOP
  674.         mov     R1, #0  ;00h -> R1_10
  675.         mov     A, R5   ;Результат приема
  676.         mov     R0, A   ;code -> R0_10
  677. ;-----
  678.         pop     ACC
  679.         pop     PSW
  680.         reti
  681. ;-----
  682. ; Принят стартовый бит данных
  683. L_257:  mov     R6, #8  ;Resive 8 bit
  684.         sjmp    L_260
  685. ; -------------------------
  686. ; Прием битов данных
  687. L_25B:  mov     A, R5
  688.         rrc     A
  689.         mov     R5, A
  690.         djnz    R6, L_261
  691. ; Принято 8 бит данных
  692. L_260:  inc     R1
  693. L_261:  pop     ACC
  694.         pop     PSW
  695.         reti
  696. ;-----
  697. ; Прием бита паритета
  698. L_266:  mov     A, R5           ;Принятый байт
  699.         jc      L_270           ;Бит паритета = 1
  700. ;
  701.         jb      PSW.0, L_260    ; PSW.0 - ACCUMULATOR PARITY FLAG
  702. L_26C:  mov     R5, #0FFh       ; результат при ошибке паритета
  703.         sjmp    L_260
  704. ; -------------------------
  705. L_270:  jnb     PSW.0, L_260    ; PSW.0 - ACCUMULATOR PARITY FLAG
  706.         sjmp    L_26C
  707. ; =============================================
  708. ; Вход запроса кода Клавиатуры от Spectruma
  709. ; =============================================
  710. ;int1:  push    PSW             ;2
  711. ;       push    ACC             ;2
  712. ;       push    DPH             ;2
  713. ;       ajmp    RD_KBD          ;2
  714. ; Int /RDKBD
  715. RD_KBD:                         ; extint1
  716.  if debug
  717.         mov     P2,#01h
  718.  endif
  719.         mov     PSW, #08h       ;2  PAGE 01
  720.         jnb     SP_VE1, L_2AF   ;2 VE1=0
  721. ; Работа контроллера запрещена
  722.         mov     A, #0FFh        ;1
  723.         mov     DPH, #01h       ;1  DPTR=#01xx
  724.         movx    @DPTR, A        ;2  /VWR=0 -> Сбросить /WAIT
  725.         setb    SP_WT           ;1 P1.7  W_ON=1 Запрет прерываний
  726. ; Спектрум работает без /WAIT с механической клавиатурой
  727.         jb      SP_VE1,$        ;2  Ждем VE1=0
  728. ; дождались разрешения работы с AT клавиатурой
  729.         clr     SP_WT           ;1 P1.7  W_ON=0 Разрешить прерывания
  730.         clr     A               ;1
  731.         clr     f_press         ;1
  732.         mov     R6_00, A        ;1 R6 PAGE 00
  733.         mov     R0_10, A        ;1 R0 PAGE 10
  734.         mov     R1_10, A        ;1 R1 PAGE 10
  735.         mov     R7, A           ;1 флаг команды=0
  736.         mov     R1, A           ;1 Z код клавиатуры = 0
  737.         sjmp    ex_kbd          ;2
  738. ;************************************************
  739. ; Принят код сканирования не 55h (не команда)
  740. no_comm:
  741.         mov     b_sadr,A        ;Скан-адрес -> бит-регистр
  742.         inc     DPH             ;DPTR=#01xx
  743.         mov     A, mode         ;Текущий режим ?
  744.         jnz     no_m00          ;mode>00h
  745. ;================================================
  746. ; mode = 00 -> Spectrum KBD
  747.         jb      f_press,kbd_ve  ;есть нажатие
  748. ; если нет нажатия, то
  749.         movx    A,@DPTR         ;Порт принтера Speccy
  750.  if en_movx
  751.         movx    @DPTR,A         ; Снять /WAIT
  752.  else
  753.         mov     P0,A            ; Выдать код клавиатуры
  754.         clr     VWR             ;имитация /WR
  755.         setb    VWR
  756.  endif
  757. ex_kbd:
  758.         pop     DPH
  759.         pop     ACC
  760.         pop     PSW
  761.         reti
  762. ; ================================================
  763. ; mode = 00 -> Spectrum KBD (есть нажатие)
  764. kbd_ve:
  765. ; РАзвернутый цикл сканирования матрицы
  766.         dec     A               ;A=#0FFh
  767.         jb      b_sadr.0,A08_1
  768.         anl     A,buf_kbd       ;
  769. A08_1:  jb      b_sadr.1,A09_1
  770.         anl     A,buf_kbd+1
  771. A09_1:  jb      b_sadr.2,A10_1
  772.         anl     A,buf_kbd+2
  773. A10_1:  jb      b_sadr.3,A11_1
  774.         anl     A,buf_kbd+3
  775. A11_1:  jb      b_sadr.4,A12_1
  776.         anl     A,buf_kbd+4
  777. A12_1:  jb      b_sadr.5,A13_1
  778.         anl     A,buf_kbd+5
  779. A13_1:  jb      b_sadr.6,A14_1
  780.         anl     A,buf_kbd+6
  781. A14_1:  jb      b_sadr.7,A15_1
  782.         anl     A,buf_kbd+7
  783. A15_1:  mov     R4,A            ;Код контроллера
  784. ;\----
  785.         movx    A,@DPTR         ;Порт Spec KBD
  786.         anl     A,R4            ;+ код контроллера
  787. ; -------------------------
  788.  if en_movx
  789.         movx    @DPTR,A         ; Снять /WAIT
  790.  else
  791.         mov     P0,A            ; Выдать код клавиатуры
  792.         clr     VWR             ;имитация /WR
  793.         setb    VWR
  794.  endif
  795.         pop     DPH
  796.         pop     ACC
  797.         pop     PSW
  798.         reti
  799. ;=========================================
  800. ; VE1=0 разрешена работа контроллера
  801. L_2AF:  mov     DPH, #00h       ;2  DPTR=#00xx
  802.         movx    A, @DPTR        ;2  A=Adress A15..A8
  803. ; проверить признак приема команды (R7)
  804.         cjne    R7,#0,L_31B     ;2  Анализ параметров команды
  805. ;--------------------------------
  806. ; Test COMM=055h
  807.         cjne    A,#55h,no_comm  ;2  если не 55h, то не команда
  808. ;--------------------------------
  809. ; Ответить на прием кода 55h
  810.  if debug
  811.         mov     P2,#02h
  812.  endif
  813.         inc     R7              ;1  R7=1 (принят код команды)
  814.         mov     A,#0AAh         ;1  Request = 0AAh
  815.         inc     DPH             ;1  DPH=#01h Передать и
  816.  if en_movx
  817.         movx    @DPTR,A         ; Снять /WAIT
  818.  else
  819.         mov     P0,A            ; Выдать код клавиатуры
  820.         clr     VWR             ;имитация /WR
  821.         setb    VWR
  822.  endif
  823.         pop     DPH             ;2
  824.         pop     ACC             ;2
  825.         pop     PSW             ;2
  826.         reti                    ;2
  827. ;*****************************************
  828. ; mode = 01,02,03
  829. no_m00: cjne    A,#01h,no_m01   ;01h ?
  830. ;========================================
  831. ; Mode = 01h - RD code KBD
  832. ; читается код клавиатуры (R2) или (R1)
  833. L_2EB:  mov     A,R1_00 ;R1 page 00
  834.         jb      f_decod, L_2F2  ;
  835. ; no decode
  836.         mov     A,R2_00 ;R2 page 00
  837.         mov     R2_00,#0        ;00h -> R2
  838. L_2F2:
  839.  if en_movx
  840.         movx    @DPTR,A         ; Снять /WAIT
  841.  else
  842.         mov     P0,A            ; Выдать код клавиатуры
  843.         clr     VWR             ;имитация /WR
  844.         setb    VWR
  845.  endif
  846.         pop     DPH
  847.         pop     ACC
  848.         pop     PSW
  849.         reti
  850. ;============================================
  851. no_m01: cjne    A,#02h,no_m02   ;02h ?
  852. ; ===========================================
  853. ; Mode =02h - CP/M
  854. ; Читаются регистры R2(или R1),(R3),(R4)
  855. ; в зависимости от состояния битов A15,A14
  856.         mov     A,b_sadr        ; Adress сканирования Axx
  857.         rl      A
  858.         rl      A
  859.         anl     A, #3           ; A15.A14 ?
  860.         jz      L_2EB           ; A15,A14=00
  861. ; -------------------------------
  862.         add     A,#R2_00        ;1..3 + #R2_00
  863.         mov     R1,A            ;
  864.         mov     A,@R1           ;(R3)..(R5)
  865.  if en_movx
  866.         movx    @DPTR,A         ; Снять /WAIT
  867.  else
  868.         mov     P0,A            ; Выдать код клавиатуры
  869.         clr     VWR             ;имитация /WR
  870.         setb    VWR
  871.  endif
  872.         pop     DPH
  873.         pop     ACC
  874.         pop     PSW
  875.         reti
  876. ;=========================================
  877. ; Mode = 03h - Direct RD
  878. no_m02: mov     A,R7_10         ;R7 Page10
  879.         mov     R7_10,#0        ;
  880.  if en_movx
  881.         movx    @DPTR,A         ; Снять /WAIT
  882.  else
  883.         mov     P0,A            ; Выдать код клавиатуры
  884.         clr     VWR             ;имитация /WR
  885.         setb    VWR
  886.  endif
  887.         pop     DPH
  888.         pop     ACC
  889.         pop     PSW
  890.         reti
  891. ;************************************************
  892. ;****** Прием параметров команды ****************
  893. ;************************************************
  894. L_31B: 
  895.  if debug
  896.         mov     P2,#03h
  897.  endif
  898.         mov     R6,A            ;Скан-адрес -> R6
  899.         cjne    R7,#1,L_344     ;R7=2 (второй параметр)
  900. ; первый параметр - код команды и префикс
  901.         rl      A
  902.         rl      A
  903.         anl     A, #3
  904.         mov     R5, A           ;R5 - Префикс команды
  905. ;
  906.         mov     A, R6           ;A15..A8
  907.         anl     A, #3Fh
  908.         jnz     ex1cmd          ;если не 0 - выполнить
  909.         ajmp    L_33E           ;это NOP
  910. ex1cmd: mov     R3, A           ;R3 - Код команды
  911. ;*************************************************
  912. ;********** TEST CODE COMM  **********************
  913. ;*************************************************
  914. ; R3 - код команды
  915. ; R5 - префикс команды
  916. ; R6 - параметр команды
  917. ; R7 - флаг команды
  918. L_344:  cjne    R3, #02h, no_c02
  919. ; COMM = 02h Чтение регистров порта RS232
  920.         cjne    R5,#0,no_c02_0
  921. ;--------------------------------
  922. ; COMM = 02h - прочитать регистр данных RS232 (прием)
  923.         mov     A, cnt_rd       ; если счетчик = 0
  924.         jz      ex_A            ; то выход с 00h
  925. ; в буфере есть данные
  926.         dec     A               ;
  927.         mov     cnt_rd, A       ;счетчик - 1
  928.         mov     R0, adr_rd      ;текущий адрес приема
  929.         mov     A,@R0           ;байт из буфера
  930.         inc     R0
  931.         cjne    R0, #buf_rd+len_brd, no_e_brd
  932. ; дошли до конца буфера приема, вернутся в начало
  933.         mov     R0, #buf_rd     ;
  934. no_e_brd:
  935.         mov     adr_rd, R0      ;Новый адрес в буфере
  936. ex_A:   ajmp    L_340           ;выход с байтом приема
  937. ;--------------------------------
  938. no_c02_0:
  939.         cjne    R5,#01h,no_c02_1
  940. ; COMM = 42h - чтение регистра статуса RS232
  941. ; d0 - готовность приемника   RD
  942. ; d1..d4=0
  943. ; d5 - готовность передатчика TD
  944. ; d6 - буфер передатчика пуст TE
  945. ; d7 - работа с прерываниями FINT
  946.         mov     A,stat_rs       ;теущий статус RS232
  947.         anl     A,#9Eh          ;TD,TE,RD=0
  948.         mov     stat_rs,A
  949.         mov     A,cnt_rd        ;если = 0
  950.         jz      no_rd           ; нет данных
  951. ; в буфере есть принятые данные
  952.         setb    stat_rs.0       ; RD=1
  953. no_rd:  mov     A,cnt_wr        ;если = len_bwr
  954.         cjne    A,#len_bwr,no_wr
  955. ; буфер передачи заполнен - выход с TD,TE=0
  956.         mov     A,stat_rs       ;текущий статус
  957.         ajmp    L_340           ;выход
  958. no_wr:  mov     A,stat_rs       ;текущий статус
  959.         orl     A,#60h          ;TD,TE=1
  960.         ajmp    L_340           ;выход
  961. ;--------------------------------
  962. no_c02_1:
  963.         cjne    R5,#2,no_c02_2
  964. ; COMM = 82h - чтение регистра модема
  965. ; d7 - DCD (Data Carrier Detect)
  966. ; d6 - RI  (Ring Indicator)
  967. ; d5 - DSR (Data Set Ready)
  968. ; d4 - CTS (Clear To Send)
  969. ; d3..d0 = 0
  970. ; Линии порта P1
  971. ; PA2 - /RI     input -> d6
  972. ; PA1 - /CTS    input -> d4,d5
  973. ; PA0 - /CD     input -> d7
  974.         mov     R5,#00h         ;пока все 0
  975.         mov     A, P1           ;порт модема
  976.         jb      ACC.1,no_cts    ;/CTS ?
  977. ; CTS=1 (сигнал инверсный)
  978.         mov     R5,#30h         ;CTS,DSR=1
  979. no_cts: mov     stat_md,R5      ;
  980.         jb      ACC.0,no_dcd    ;/DCD ?
  981. ; DCD=1 (сигнал инверсный)
  982.         setb    stat_md.7       ;DCD=1
  983. no_dcd: jb      ACC.2,no_ri     ;/RI ?
  984. ; RI=1  (сигнал инверсный)
  985.         setb    stat_md.6       ;RI=1
  986. no_ri:  mov     A,stat_md       ;текущий статус модема
  987.         ajmp    L_340           ;выход
  988. ;--------------------------------
  989. no_c02_2:
  990. ; COMM = 0C2h - чтение счетчика буфера приема
  991.         mov     A, cnt_rd       ;
  992.         ajmp    L_340           ;выход
  993. ; Конец работы команды xx02h - Чтение регистров RS232
  994. ;=============================================
  995. no_c02: cjne    R3, #3, no_c03
  996. ; COMM = 03h|43h|83h|C3h Запись регистров порта RS232
  997.         cjne    R7,#1, no_1c03  ; R7=2 - выполнить запись
  998. ; установить признак приема следующего байта
  999.         inc     R7              ;Принять еще один байт
  1000.         mov     A,#0FFh
  1001.         ajmp    L_2F3           ;пока выйти
  1002. ;=============================================
  1003. no_1c03:
  1004. ; принят байт (R6) для записи в регистр RS232
  1005.         cjne    R5,#0,no_c03_0
  1006. ;---------------------------------------------
  1007. ; COMM=03h,<data> - запись <data> в регистр данных RS232
  1008. ; проверить заполненность буфера передатчика
  1009.         mov     A,cnt_wr        ;счетчик буфера передатчика
  1010.         jz      clr_bwr         ;если пустой, то передать
  1011. ; в буфере передатчика уже что-то есть
  1012.         jb      ACC.3,no_inc    ;cnt_wr от 0 до 7
  1013.         inc     A               ;cnt_wr+1
  1014.         mov     cnt_wr,A        ;новый счетчик
  1015. no_inc:
  1016. ; записать текущий байт в буфер передатчика
  1017.         mov     R0,adr_ws       ;текущий адрес записи
  1018.         mov     A,R6            ;<data>
  1019.         mov     @R0,A           ;-> в буфер
  1020.         inc     R0
  1021.         cjne    R0,#buf_wr+len_bwr,no_ebwr
  1022.         mov     R0,#buf_wr      ;в начало буфера
  1023. no_ebwr:
  1024.         mov     adr_ws,R0       ;новый адрес
  1025. ex_cmd: ajmp    L_33E           ;выйти
  1026. ;
  1027. clr_bwr:
  1028.         mov     SBUF,R6         ;сразу передать
  1029.         inc     A
  1030.         mov     cnt_wr,A        ;cnt_wr+1
  1031.         mov     A,#buf_wr
  1032.         mov     adr_wr,A
  1033.         mov     adr_ws,A
  1034.         ajmp    L_33E           ;выход
  1035. ;---------------------------------------------
  1036. no_c03_0:
  1037.         cjne    R5,#01h,no_c03_1
  1038. ; COMM= 43h,<data> - регистр управления битами модема
  1039. ; d0 - DTR Data Terminal Ready
  1040. ; d1 - RTS Request To Send
  1041. ; d2..d7 - не используются
  1042. ; Порт P1
  1043. ; PA0 - CD     input
  1044. ; PA1 - CTS    input
  1045. ; PA2 - RI     input
  1046. ; PA3 - DTR    out      <- d0
  1047. ; PA4 - RTS    out      <- d1
  1048. ; PA5 - INT_T  out
  1049. ; PA6 - /RES  -out
  1050. ; PA7 - W_ON  -out
  1051.         mov     A,R6            ;<data>
  1052.         rl      A
  1053.         rl      A
  1054.         rl      A
  1055.         cpl     A               ;Инверсия битов
  1056.         anl     A,#18h          ;RTS(4),DTR(3)
  1057.         orl     A,#67h          ;W_ON(7)=0
  1058.         mov     P1,A            ;Установить биты
  1059.         ajmp    L_33E           ;выход
  1060. ;--------------------------------------
  1061. no_c03_1:
  1062.         cjne    R5,#02h,no_c03_2
  1063. ; COMM 83h,<data> - записать байт управления модемом
  1064.         mov     stat_rs,R6      ;
  1065.         ajmp    L_33E           ;
  1066. ;--------------------------------------
  1067. no_c03_2:
  1068. ; COMM 0C3h,<data> - записать скорость RS232
  1069.         call    set_speed       ;R6 -> скорость
  1070.         ajmp    L_33E           ;выход
  1071. ;***** Конец выполнения команд xx03h  *************
  1072. ;**************************************************
  1073. no_c03: cjne    R3, #1, L_34E   ;Код команды # 01h ?
  1074. ; COMM = 01h|41h|81h|0C1h Get Vers.
  1075.         push    DPL
  1076.         mov     DPTR, #vers     ;Buf Ver.
  1077.         mov     A, R5           ;0..3 (Adress Param)
  1078.         movc    A, @A+DPTR      ;
  1079.         pop     DPL
  1080.         sjmp    L_340           ;
  1081. ;=================================================
  1082. L_34E:  cjne    R3, #7, L_35C
  1083. ; COMM = 07h (Очистка буфера клавиатуры)
  1084.         mov     R0,#buf_kbd     ;Буфер клавиатуры
  1085.         mov     R1,#8
  1086. L_355:  mov     @R0, #0FFh      ;все <1>
  1087.         inc     R0
  1088.         djnz    R1, L_355
  1089. ;-----
  1090.         sjmp    L_33E
  1091. ;=================================================
  1092. L_35C:  cjne    R3, #8, L_376
  1093. ; COMM = 08h,<mode> (Установка режима работы контроллера)
  1094.         cjne    R7, #2, L_3C5   ;
  1095. ; Second param =<mode>
  1096.         mov     A, R6           ;Второй параметр команды
  1097.         anl     A,#03h          ;младшие 2 бита
  1098.         mov     mode, A         ; Mode
  1099.         mov     R2_00,#0        ;Сброс текущего скан-кода
  1100. ; Завершение команды - выход с кодом 0FFh
  1101. L_33E:  mov     A, #0FFh        ;выход с A=0FFh
  1102. L_340:  mov     R7, #0          ;
  1103. L_2F3:  mov     DPH,#01h        ;DPTR=#01xx
  1104.  if en_movx
  1105.         movx    @DPTR,A         ; Снять /WAIT
  1106.  else
  1107.         mov     P0,A            ; Выдать код клавиатуры
  1108.         clr     VWR             ;имитация /WR
  1109.         setb    VWR
  1110.  endif
  1111.         pop     DPH
  1112.         pop     ACC
  1113.         pop     PSW
  1114.         reti
  1115. ;=================================================
  1116. L_376:  cjne    R3, #9, L_37F
  1117. ; COMM = 09h,49h,89h,C9h Прочитать регистры клавиатуры
  1118.         mov     A, R5           ;0..3
  1119.         inc     A               ;1..4
  1120.         mov     R0, A
  1121.         mov     A, @R0          ;A=(R1)..(R4)
  1122.         sjmp    L_340
  1123. ;=================================================
  1124. L_37F:  cjne    R3, #0Ah, L_387
  1125. ; COMM=0Ah Set RUS
  1126.         orl     R3_00, #80h     ; Set RUS (было R1_00)
  1127.         sjmp    L_33E           ;выход с A=0FFh
  1128. ;=================================================
  1129. L_387:  cjne    R3, #0Bh, L_38F
  1130. ; COMM=0Bh Set LAT
  1131.         anl     R3_00, #7Fh     ; Set LAT (было R1_00)
  1132.         sjmp    L_33E           ;выход с A=0FFh
  1133. ;=================================================
  1134. L_38F:  cjne    R3, #0Ch, L_396
  1135. ; COMM=0Ch  Установить режим ожидания
  1136.         setb    f_wait          ; Set Wait ON
  1137.         sjmp    L_33E           ;выход с A=0FFh
  1138. ;=================================================
  1139. L_396:  cjne    R3, #0Dh, L_39B
  1140. ; COMM=0Dh   Программный сброс компьютера
  1141.         ajmp    reset           ; Reset Computer
  1142. ;=================================================
  1143. L_39B:  cjne    R3, #10h, L_3A4
  1144. ; COMM=10h..0D0h (запрос текущего времени)
  1145.         mov     A, #b_time      ;секунды
  1146.         acall   L_3E7           ; Get Time
  1147.         ajmp    L_2F3           ;
  1148. ;=================================================
  1149. L_3A4:  cjne    R3, #11h, L_3AD
  1150. ; COMM=11h..0D1h (установка текущего времени)
  1151.         mov     A, #b_time
  1152.         acall   L_3ED           ; Set Time
  1153.         ajmp    L_2F3
  1154. ;=================================================
  1155. L_3AD:  cjne    R3, #12h, L_3B6
  1156. ; COMM=12h..0D2h (запрос текущей даты)
  1157.         mov     A, #b_date      ; Буфер даты
  1158.         acall   L_3E7           ; Get DATA
  1159.         ajmp    L_2F3
  1160. ;=================================================
  1161. L_3B6:  cjne    R3, #13h, L_3BF
  1162. ; COMM=13h..0D3h (установка текущей даты)
  1163.         mov     A, #b_date      ; Буфер даты
  1164.         acall   L_3ED           ; Set DATA
  1165.         ajmp    L_2F3
  1166. ;=================================================
  1167. L_3BF:  cjne    R3, #14h, L_3CD ;
  1168. ; COMM=14h,<data> (установка битов порта P1)
  1169.         cjne    R7, #1, L_3C8
  1170. ; R7=1
  1171. L_3C5:  inc     R7              ; R7=2
  1172.         mov     A,#0FFh
  1173.         ajmp    L_2F3
  1174. ; ---
  1175. ; R7=2
  1176. L_3C8:  mov     A, R6           ;<data>
  1177.         orl     P1, A           ;
  1178.         ajmp    L_33E           ;Выход с A=0FFh
  1179. ;=================================================
  1180. L_3CD:  cjne    R3, #15h, L_3D9
  1181. ; COMM=15h,<data> (сброс битов порта P1)
  1182.         cjne    R7, #2, L_3C5   ;R7=1
  1183. ; R7=2
  1184.         mov     A, R6           ;<data>
  1185.         cpl     A
  1186.         anl     P1, A
  1187. L_3D7:  ajmp    L_33E           ;выход с A=0FFh
  1188. ;=================================================
  1189. L_3D9:  cjne    R3, #16h, L_3E0
  1190. ; COMM=16h (чтение порта P3)
  1191.         mov     A, P3           ;
  1192.         ajmp    L_340           ;выход с A=P3
  1193. ;=================================================
  1194. L_3E0:  cjne    R3, #17h, L_3D7 ;выход с A=0FFh
  1195. ; COMM=17h (чтение порта P1)
  1196.         mov     A, P1           ;
  1197.         ajmp    L_340           ;выход с A=P1
  1198. ; End Decode Command
  1199. ;*************************************************
  1200. ; Get data
  1201. L_3E7:  add     A, R5
  1202.         mov     R0, A
  1203.         mov     A, @R0
  1204.         mov     R7, #0
  1205.         ret
  1206. ;=================================================
  1207. L_3ED:  cjne    R7, #2, L_3F9
  1208. ; Set <data>
  1209.         add     A, R5
  1210.         mov     R0, A
  1211.         mov     A, R6           ;<data>
  1212.         mov     @R0, A
  1213.         mov     R7, #0FFh       ;-1
  1214. ; First Param = adress param -> R5
  1215. L_3F9:  mov     A, #0FFh
  1216.         inc     R7              ; R7=2
  1217.         ret
  1218. ;*********************************************
  1219. ;------ Настройка RS-232 (по таблице констант)
  1220. ; R6 - коэффициент деления 1,2,3,6,12,24,48
  1221. set_speed:
  1222.         mov     A,R6            ;
  1223.         jz      no_set_spd      ;0 - нельзя
  1224. ;
  1225.         clr     C
  1226.         subb    A,#4            ;1,2,3 -> CY=1
  1227.         mov     A,R6
  1228.         jc      set_spd         ;1,2,3
  1229. ; R6>3
  1230.         cjne    A,#6,no_spd_6
  1231. ; 19200 бод
  1232.         mov     A,#4
  1233.         sjmp    set_spd         ;установить
  1234. no_spd_6:
  1235.         cjne    A,#12,no_spd_12
  1236. ; 9600 бод
  1237.         mov     A,#5
  1238.         sjmp    set_spd         ;установить
  1239. no_spd_12:
  1240.         cjne    A,#24,no_spd_24
  1241. ; 4800 бод
  1242.         mov     A,#6
  1243.         sjmp    set_spd         ;установить
  1244. no_spd_24:
  1245.         cjne    A,#48,no_spd_48
  1246. ; 2400 бод
  1247.         mov     A,#7
  1248.         sjmp    set_spd         ;установить
  1249. no_spd_48:
  1250.         cjne    A,#96,no_set_spd
  1251. ; 1200 бод
  1252.         mov     A,#8
  1253. set_spd:
  1254.         push    DPL
  1255.         mov     DPTR,#tab_spd-1
  1256.         movc    A,@A+DPTR       ;Код делителя
  1257.         mov     PCON,#80h       ;Удвоенная скорость
  1258.         jbc     ACC.7,yes_smod  ;
  1259.         mov     PCON,#00h       ;одинарная скорость
  1260. yes_smod:
  1261.         cpl     A
  1262.         mov     TH1,A           ; Новая скорость
  1263.         pop     DPL
  1264. no_set_spd:
  1265.         mov     A,#buf_wr       ;буфер передатчика
  1266.         mov     adr_wr,A        ;
  1267.         mov     adr_ws,A
  1268.         mov     A,#buf_rd       ;буфер приема
  1269.         mov     adr_rd,A        ;адрес приема для Speccy
  1270.         mov     adr_rs,A        ;адрес приема для контроллера
  1271.         clr     A
  1272.         mov     cnt_rd,A        ;счетчик чтения
  1273.         mov     cnt_wr,A        ;счетчик записи
  1274.         ret
  1275. ;****************************************
  1276. ; Прием по Rs232                        *
  1277. ;****************************************
  1278. ;serint:
  1279. ;       push    PSW
  1280. ;       push    ACC
  1281. ;       mov     PSW, #18h       ;PAGE 18
  1282. ;       ajmp    ser_int
  1283. ser_int:
  1284.  if debug
  1285.         mov     P2,#10h
  1286.  endif
  1287.         jbc     RI,ser_rx       ;готовность приемника
  1288. ; готовность передатчика RS232
  1289.         clr     TI              ;сброс готовности ПРД.
  1290. ; если в буфере передатчика есть данные - передать
  1291.         mov     A,R6            ;cnt_wr ? (сч.прд)
  1292.         jz      no2end_buf      ;ничего нет
  1293. ; передать байт из буфера передатчика
  1294.         dec     R6              ;счетчик - 1
  1295.         mov     A,R6            ; если cnt_wr=1
  1296.         jz      no2end_buf      ;это признак передачи байта
  1297. ; в буфере есть еще байты для передачи
  1298.         clr     EA              ;запретить прерывания
  1299.         mov     R0,adr_wr       ;адрес буфера передачи
  1300.         mov     A,@R0           ;текущий байт
  1301.         mov     SBUF,A          ; передать
  1302.         inc     R0              ;к следующему байту
  1303.         cjne    R0,#buf_wr+len_bwr,no_ewr
  1304.         mov     R0,#buf_wr      ;начать с начала буфера
  1305. no_ewr:
  1306.         mov     adr_wr,R0       ;новый адрес в буфере
  1307.         setb    EA              ;разрешить прерывания
  1308.         sjmp    no2end_buf      ;выход
  1309. ;------------------------------------------
  1310. ; принят байт по RS232
  1311. ser_rx:
  1312. ; R5 = cnt_rd - счетчик приема
  1313.         cjne    R5,#len_brd,no_end_buf ;еще не конец буфера
  1314. ; иначе из начала буфера удалить старый символ
  1315.         dec     R5              ;cnt_rd-1
  1316.         inc     R4              ;указатель приема вперед
  1317.         cjne    R4,#buf_rd+len_brd,no_end_buf
  1318.         mov     R4,#buf_rd      ;adr_rd в начало буфера
  1319. no_end_buf:
  1320.         mov     A,SBUF          ;Байт приема
  1321.         mov     @R1,A           ;в буфер (R1 - адрес буфера приема)
  1322.         inc     R5              ;cnt_rd+1
  1323.         inc     R1              ;указатель вперед
  1324.         cjne    R1,#buf_rd+len_brd,no2end_buf
  1325.         mov     R1,#buf_rd      ;указатель приема в начало буфера
  1326. no2end_buf:
  1327.         pop     ACC
  1328.         pop     PSW
  1329.         reti
  1330. ;****************************************
  1331. ; Timer 0 (часы реального времени)      *
  1332. ;****************************************
  1333. int_rtc:                        ; timint0
  1334.  if debug
  1335.         mov     P2,#30h
  1336.  endif
  1337.         mov     PSW, #18h       ;PAGE 11
  1338. ; Счетчик тайм-аута клавиатуры
  1339.         mov     A, R7           ; rtc_to
  1340.         jz      L_408           ;
  1341.         dec     R7              ; -1
  1342. L_408:
  1343. ;--------------------------------
  1344.         djnz    tics,L_45A      ;
  1345. ;
  1346.         mov     tics, #f_tic    ;50 тиков в секунду
  1347.         mov     R0, #b_time     ;Буфер времени
  1348.         inc     @R0
  1349.         cjne    @R0, #60, L_45A ;<60 секунд
  1350. ;
  1351.         mov     @R0, #0         ;
  1352.         inc     R0
  1353.         inc     @R0
  1354.         cjne    @R0, #60, L_45A ;<60 минут
  1355. ;
  1356.         mov     @R0, #0
  1357.         inc     R0
  1358.         inc     @R0
  1359.         cjne    @R0, #24, L_45A ;<24 часов
  1360. ;
  1361.         mov     @R0, #0
  1362. ;
  1363.         inc     R0
  1364.         inc     @R0             ;след.день
  1365.         mov     A, @R0
  1366.         mov     R2, A
  1367.         inc     R0
  1368.         mov     A, @R0          ;Номер месяца
  1369.         push    DPL
  1370.         push    DPH
  1371.         mov     DPTR, #L_465-1  ;Таблица дней
  1372.         movc    A, @A+DPTR
  1373.         pop     DPH
  1374.         pop     DPL
  1375.         cjne    @R0, #2, L_445
  1376. ;
  1377.         inc     R0
  1378.         mov     R3, A
  1379.         mov     A, @R0
  1380.         dec     R0
  1381.         rrc     A
  1382.         jc      L_444
  1383.         rrc     A
  1384.         jc      L_444
  1385.         inc     R3
  1386. L_444:  mov     A, R3
  1387. ;
  1388. L_445:  clr     C
  1389.         subb    A, R2
  1390.         jnc     L_45A
  1391. ;
  1392.         dec     R0
  1393.         mov     @R0, #1
  1394.         inc     R0
  1395.         inc     @R0
  1396.         cjne    @R0, #13, L_45A ;<13
  1397. ;
  1398.         mov     @R0, #1
  1399.         inc     R0
  1400.         inc     @R0
  1401.         cjne    @R0, #100, L_45A ;<100
  1402. ;
  1403.         mov     @R0, #0
  1404. ;
  1405. L_45A:  call    set_T0          ;T0 = 50 герц
  1406.  if debug
  1407.         mov     P2,#00h
  1408.  endif
  1409.         pop     ACC
  1410.         pop     PSW
  1411.         reti
  1412. ; -------------------------
  1413. ;
  1414.         ORG     600h
  1415. ;----------------------------------------
  1416. ; Число дней в месяцах
  1417. L_465:  db  31  ;Январь
  1418.         db  28  ;Февраль
  1419.         db  31  ;Март
  1420.         db  30  ;Апрель
  1421.         db  31  ;Май
  1422.         db  30  ;Июнь
  1423.         db  31  ;Июль
  1424.         db  31  ;Август
  1425.         db  30  ;Сентябрь
  1426.         db  31  ;Октябрь
  1427.         db  30  ;Ноябрь
  1428.         db  31  ;Декабрь
  1429. ;----------------------------------------
  1430. ; Таблица CP/M - кодов клавиатуры
  1431. L_471:  db  1Bh ; ESC
  1432.         db    0 ;
  1433. ;
  1434.         db  31h ; 1
  1435.         db    0 ;
  1436. ;
  1437.         db  32h ; 2
  1438.         db    0 ;
  1439. ;
  1440.         db  33h ; 3
  1441.         db    0 ;
  1442. ;
  1443.         db  34h ; 4
  1444.         db    0 ;
  1445. ;
  1446.         db  35h ; 5
  1447.         db    0 ;
  1448. ;
  1449.         db  36h ; 6
  1450.         db    0 ;
  1451. ;
  1452.         db  37h ; 7
  1453.         db    0 ;
  1454. ;
  1455.         db  38h ; 8
  1456.         db    0 ;
  1457. ;
  1458.         db  39h ; 9
  1459.         db    0 ;
  1460. ;
  1461.         db  30h ; 0
  1462.         db    0 ;
  1463. ;
  1464.         db  2Dh ; -/_
  1465.         db    0 ;
  1466. ;
  1467.         db  3Dh ; =/+
  1468.         db    0 ;
  1469. ;
  1470.         db    8 ; BS
  1471.         db    0 ;
  1472. ;
  1473.         db    9 ; TAB
  1474.         db    0 ;
  1475. ;
  1476.         db  51h ; Q
  1477.         db    0 ;
  1478. ;
  1479.         db  57h ; W
  1480.         db    0 ;
  1481. ;
  1482.         db  45h ; E
  1483.         db    0 ;
  1484. ;
  1485.         db  52h ; R
  1486.         db    0 ;
  1487. ;
  1488.         db  54h ; T
  1489.         db    0 ;
  1490. ;
  1491.         db  59h ; Y
  1492.         db    0 ;
  1493. ;
  1494.         db  55h ; U
  1495.         db    0 ;
  1496. ;
  1497.         db  49h ; I
  1498.         db    0 ;
  1499. ;
  1500.         db  4Fh ; O
  1501.         db    0 ;
  1502. ;
  1503.         db  50h ; P
  1504.         db    0 ;
  1505. ;
  1506.         db  5Bh ; [
  1507.         db    0 ;
  1508. ;
  1509.         db  5Dh ; ]
  1510.         db    0 ;
  1511. ;
  1512.         db  0Dh ; Enter
  1513.         db 0C0h ;
  1514. ;
  1515.         db    0 ; Ctrl
  1516.         db    2 ; bit 1 (R3)
  1517. ;
  1518.         db  41h ; A
  1519.         db    0 ;
  1520. ;
  1521.         db  53h ; S
  1522.         db    0 ;
  1523. ;
  1524.         db  44h ; D
  1525.         db    0 ;
  1526. ;
  1527.         db  46h ; F
  1528.         db    0 ;
  1529. ;
  1530.         db  47h ; G
  1531.         db    0 ;
  1532. ;
  1533.         db  48h ; H
  1534.         db    0 ;
  1535. ;
  1536.         db  4Ah ; J
  1537.         db    0 ;
  1538. ;
  1539.         db  4Bh ; K
  1540.         db    0 ;
  1541. ;
  1542.         db  4Ch ; L
  1543.         db    0 ;
  1544. ;
  1545.         db  3Bh ; ;
  1546.         db    0 ;
  1547. ;
  1548.         db  27h ; '
  1549.         db    0 ;
  1550. ;
  1551.         db  60h ; `
  1552.         db    0 ;
  1553. ;
  1554.         db    0 ; Left Shift
  1555.         db    3 ; bit0 R3
  1556. ;
  1557.         db  5Ch ; \
  1558.         db    0 ;
  1559. ;
  1560.         db  5Ah ; Z
  1561.         db    0 ;
  1562. ;
  1563.         db  58h ; X
  1564.         db    0 ;
  1565. ;
  1566.         db  43h ; C
  1567.         db    0 ;
  1568. ;
  1569.         db  56h ; V
  1570.         db    0 ;
  1571. ;
  1572.         db  42h ; B
  1573.         db    0 ;
  1574. ;
  1575.         db  4Eh ; N
  1576.         db    0 ;
  1577. ;
  1578.         db  4Dh ; M
  1579.         db    0 ;
  1580. ;
  1581.         db  2Ch ; ,
  1582.         db    0 ;
  1583. ;
  1584.         db  2Eh ; .
  1585.         db    0 ;
  1586. ;
  1587.         db  2Fh ; /
  1588.         db  40h ;
  1589. ;
  1590.         db    0 ; Rght Shift
  1591.         db    3 ; bit0 R4
  1592. ;
  1593.         db 0AAh ; \/|
  1594.         db    0 ;
  1595. ;
  1596.         db    0 ; ALT
  1597.         db    1 ; bit2 R3
  1598. ;
  1599.         db  20h ; SPACE
  1600.         db    0 ;
  1601. ;
  1602.         db    0 ; CapS LOck
  1603.         db    4 ; bit4 R3 (trigger)
  1604. ;----
  1605.         db  61h ; F1
  1606.         db    0 ;
  1607. ;
  1608.         db  62h ; F2
  1609.         db    0 ;
  1610. ;
  1611.         db  63h ; F3
  1612.         db    0 ;
  1613. ;
  1614.         db  64h ; F4
  1615.         db    0 ;
  1616. ;
  1617.         db  65h ; F5
  1618.         db    0 ;
  1619. ;
  1620.         db  66h ; F6
  1621.         db    0 ;
  1622. ;
  1623.         db  67h ; F7
  1624.         db    0 ;
  1625. ;
  1626.         db  68h ; F8
  1627.         db    0 ;
  1628. ;
  1629.         db  69h ; F9
  1630.         db    0 ;
  1631. ;
  1632.         db  6Ah ; F10
  1633.         db    0 ;
  1634. ;
  1635.         db    0 ; Num Lock
  1636.         db    8 ; bit5 R3 (trigger)
  1637. ;
  1638.         db    0 ; Scroll Lock
  1639.         db  0Ch ; bit6 R3 (trigger)
  1640. ;----------------------------------
  1641. ; Num keyboard scan code set1 > 47h
  1642.         db  37h ;47h [7]
  1643.         db  80h ;set bit7 R2
  1644. ;
  1645.         db  38h ;48h [8]
  1646.         db  80h ;
  1647. ;
  1648.         db  39h ;49h [9]
  1649.         db  80h ;
  1650. ;
  1651.         db  2Dh ;4Ah [-]
  1652.         db  80h ;
  1653. ;
  1654.         db  34h ;4Bh [4]
  1655.         db  80h ;
  1656. ;
  1657.         db  35h ;4Ch [5]
  1658.         db  80h ;
  1659. ;
  1660.         db  36h ;4Dh [6]
  1661.         db  80h ;
  1662. ;
  1663.         db  2Bh ;4Eh [+]
  1664.         db  80h ;
  1665. ;
  1666.         db  31h ;4Fh [1]
  1667.         db  80h ;
  1668. ;
  1669.         db  32h ;50h [2]
  1670.         db  80h ;
  1671. ;
  1672.         db  33h ;51h [3]
  1673.         db  80h ;
  1674. ;
  1675.         db  30h ;52h [0]
  1676.         db  80h ;
  1677. ;
  1678.         db  2Eh ;53h [.]
  1679.         db  80h ;
  1680. ;
  1681.         db    0 ;54h
  1682.         db    0 ;
  1683. ;
  1684.         db    0 ;55h
  1685.         db    0 ;
  1686. ;
  1687.         db    0 ;56h
  1688.         db  30h ;
  1689. ;
  1690.         db  6Bh ;57h F11
  1691.         db    0 ;
  1692. ;
  1693.         db  6Ch ;58h F12
  1694.         db    0 ;
  1695. ;
  1696.         db    0 ;59h
  1697.         db    0 ;
  1698. ;
  1699.         db    0 ;5Ah
  1700.         db    0 ;
  1701. ;
  1702.         db    0 ;5Bh
  1703.         db    0 ;
  1704. ;
  1705. ;----------------------------------------
  1706. ; Scan-code IBM(1) -> code Spectrum
  1707. ; D7 - Symbol Shift
  1708. ; D6..D4 - Number bit Adress (A8=000..A15=111)
  1709. ; D3 - Caps Shift
  1710. ; D2..D0 - Number bit Data (D0=001..D4=101)
  1711. L_527:  db  39h ;01 ESC         CapSh + Kl_1
  1712. ;
  1713.         db  31h ;02 1/!         Kl_1
  1714.         db  32h ;03 2/@         Kl_2
  1715.         db  33h ;04 3/#         Kl_3
  1716.         db  34h ;05 4/$         Kl_4
  1717.         db  35h ;06 5/%         Kl_5
  1718. ;
  1719.         db  45h ;07 6/^         Kl_6
  1720.         db  44h ;08 7/&         Kl_7
  1721.         db  43h ;09 8/*         Kl_8
  1722.         db  42h ;0A 9/(         Kl_9
  1723.         db  41h ;0B 0/)         Kl_0
  1724. ;
  1725.         db 0E4h ;0C -/_         SymSh+Kl_J
  1726.         db 0E2h ;0D =/+         SymSh+Kl_L
  1727.         db  49h ;0E BS          CapSh+Kl_0
  1728.         db  3Bh ;0F TAB         CapSh+Kl_3
  1729. ;
  1730.         db  21h ;10 Q           Kl_Q
  1731.         db  22h ;11 W           Kl_W
  1732.         db  23h ;12 E           Kl_E
  1733.         db  24h ;13 R           Kl_R
  1734.         db  25h ;14 T           Kl_T
  1735. ;
  1736.         db  55h ;15 Y           Kl_Y
  1737.         db  54h ;16 U           Kl_U
  1738.         db  53h ;17 I           Kl_I
  1739.         db  52h ;18 O           Kl_O
  1740.         db  51h ;19 P           Kl_P
  1741. ;
  1742.         db 0D5h ;1A [/{         SymSh+Kl_Y
  1743.         db 0D4h ;1B ]/}         SymSh+Kl_U
  1744.         db  61h ;1C ENTER
  1745.         db  88h ;1D Ctrl        CapSh+SymSh
  1746. ;
  1747.         db  11h ;1E A           Kl_A
  1748.         db  12h ;1F S           Kl_S
  1749.         db  13h ;20 D           Kl_D
  1750.         db  14h ;21 F           Kl_F
  1751.         db  15h ;22 G           Kl_G
  1752. ;
  1753.         db  65h ;23 H           Kl_H
  1754.         db  64h ;24 J           Kl_J
  1755.         db  63h ;25 K           Kl_K
  1756.         db  62h ;26 L           Kl_L
  1757. ;
  1758.         db 0D2h ;27 ;/:         SymSh+Kl_O
  1759.         db 0D1h ;28 '/"         SymSh+Kl_P
  1760.         db  91h ;29 `/~         CapSh+Kl_A
  1761. ;
  1762.         db  08h ;2A Left Shift  CapSh
  1763.         db  92h ;2B \/|         CapSh+Kl_S
  1764. ;
  1765.         db  02h ;2C Z           Kl_Z
  1766.         db  03h ;2D X           Kl_X
  1767.         db  04h ;2E C           Kl_C
  1768.         db  05h ;2F V           Kl_V
  1769. ;
  1770.         db  75h ;30 B           Kl_B
  1771.         db  74h ;31 N           Kl_N
  1772.         db  73h ;32 M           Kl_M
  1773. ;
  1774.         db 0F4h ;33 ,/<         SymSh+Kl_N
  1775.         db 0F3h ;34 ./>         SymSh+Kl_M
  1776.         db  85h ;35 //?         SymSh+Kl_V
  1777.         db  80h ;36 Rght Shift  SymSh
  1778.         db 0F5h ;37 [*]         SymSh+Kl_B
  1779.         db  3Ch ;38 Alt         CapSh+Kl_4
  1780. ;
  1781.         db  71h ;39 SPACE       Kl_SP
  1782. ;
  1783.         db  3Ah ;3A CapsLock    CapSh+Kl_2
  1784. ;
  1785.         db 0B1h ;3B F1          SymSh+Kl_1
  1786.         db 0B2h ;3C F2          SymSh+Kl_2
  1787.         db 0B3h ;3D F3          SymSh+Kl_3
  1788.         db 0B4h ;3E F4          SymSh+Kl_4
  1789.         db 0B5h ;3F F5          SymSh+Kl_5
  1790.         db 0C5h ;40 F6          SymSh+Kl_6
  1791.         db 0C4h ;41 F7          SymSh+Kl_7
  1792.         db 0C3h ;42 F8          SymSh+Kl_8
  1793.         db 0C2h ;43 F9          SymSh+Kl_9
  1794.         db 0C1h ;44 F10         SymSh+Kl_0
  1795. ;
  1796.         db    0 ;45 NumLock
  1797.         db    0 ;46 ScrollLock
  1798. ; Клавиши цифрового блока клавиатуры
  1799.         db  3Ch ;47 [7]         CapSh+Kl_4
  1800.         db  4Ch ;48 [8] [Up]    CapSh+Kl_7
  1801.         db  3Dh ;49 [9]         CapSh+Kl_5
  1802.         db 0E4h ;4A [-]         SymSh+Kl_J
  1803.         db  3Dh ;4B [4]         CapSh+Kl_5
  1804.         db  35h ;4C [5]         5
  1805.         db  4Bh ;4D [6]         CapSh+Kl_8
  1806.         db 0E3h ;4E [+]         SymSh+Kl_K
  1807.         db  4Ah ;4F [1]         CapSh+Kl_9
  1808.         db  4Dh ;50 [2]         CapSh+Kl_6
  1809.         db  4Bh ;51 [3]         CapSh+Kl_8
  1810.         db  84h ;52 [Insert]    SymSh+Kl_C
  1811.         db  49h ;53 [Delete]    CapSh+Kl_0
  1812.         db    0 ;54
  1813.         db    0 ;55
  1814.         db    0 ;56
  1815.         db 0E5h ;57 F11         SymSh+Kl_H
  1816.         db  94h ;58 F12         SymSh+Kl_F
  1817.         db    0 ;59
  1818.         db    0 ;5A
  1819.         db    0 ;5B
  1820. ;-----------------------------------------
  1821. ; Таблица для клавиш управления курсором
  1822. ; Признаком этих клавиш является префикс E0
  1823. L_582:  db  76h ;47h Home
  1824.         db  70h ;48h Cur Up
  1825.         db  74h ;49h Page Up
  1826.         db 0ADh ;4Ah [-]
  1827.         db  72h ;4Bh Cur Left
  1828.         db 0B5h ;4Ch [5]
  1829.         db  73h ;4Dh Cur Right
  1830.         db 0ABh ;4Eh [+]
  1831.         db  77h ;4Fh End
  1832.         db  71h ;50h Cur Down
  1833.         db  75h ;51h Page Down
  1834.         db  78h ;52h Insert
  1835.         db  79h ;53h Del
  1836. ;=========================================
  1837. ; Tab Scan-code Set 2(AT) -> Set 1(XT)
  1838. ; знак + в скан коде означает наличие префикса 0E0h
  1839. ;           XT   AT   N_Kl
  1840. at2xt:  db    0 ;00h
  1841.         db  43h ;01h  120    F9
  1842.         db    0 ;02h
  1843.         db  3Fh ;03h  116    F5
  1844.         db  3Dh ;04h  114    F3
  1845.         db  3Bh ;05h  112    F1
  1846.         db  3Ch ;06h  113    F2
  1847.         db  58h ;07h  123    F12
  1848.         db    0 ;08h
  1849.         db  44h ;09h  121    F10
  1850.         db  42h ;0Ah  119    F8
  1851.         db  40h ;0Bh  117    F6
  1852.         db  3Eh ;0Ch  115    F4
  1853.         db  0Fh ;0Dh   16    [Tab]
  1854.         db  29h ;0Eh    1    ~/`
  1855.         db    0 ;0Fh
  1856.         db    0 ;10h
  1857.         db  38h ;11h   60    [ALT Left]
  1858. ;+              ;11h+  62    [ALT Right]
  1859.         db  2Ah ;12h   44    [Shift Left]
  1860.         db    0 ;13h
  1861.         db  1Dh ;14h   58    [Ctrl Left]
  1862.         db  10h ;15h   17    Q
  1863.         db  02h ;16h    2    1/!
  1864.         db    0 ;17h
  1865.         db    0 ;18h
  1866.         db    0 ;19h
  1867.         db  2Ch ;1Ah   46    Z
  1868.         db  1Fh ;1Bh   32    S
  1869.         db  1Eh ;1Ch   31    A
  1870.         db  11h ;1Dh   18    W
  1871.         db  03h ;1Eh    3    2/@
  1872.         db    0 ;1Fh+ ---   [Left Fly Win]
  1873.         db    0 ;20h
  1874.         db  2Eh ;21h   48    C
  1875.         db  2Dh ;22h   47    X
  1876.         db  20h ;23h   33    D
  1877.         db  12h ;24h   19    E
  1878.         db  05h ;25h    5    4/$
  1879.         db  04h ;26h    4    3/#
  1880.         db    0 ;27h+ ---    [Right Fly Win]
  1881.         db    0 ;28h
  1882.         db  39h ;29h   61    [Space]
  1883.         db  2Fh ;2Ah   49    V
  1884.         db  21h ;2Bh   34    F
  1885.         db  14h ;2Ch   21    T
  1886.         db  13h ;2Dh   20    R
  1887.         db  06h ;2Eh    6    5/%
  1888.         db    0 ;2Fh+ ---    [Win Menu]
  1889.         db    0 ;30h
  1890.         db  31h ;31h   51    N
  1891.         db  30h ;32h   50    B
  1892.         db  23h ;33h   36    H
  1893.         db  22h ;34h   35    G
  1894.         db  15h ;35h   22    Y
  1895.         db  07h ;36h    7    6/^
  1896.         db    0 ;37h+  ---   [Power]
  1897.         db    0 ;38h
  1898.         db    0 ;39h
  1899.         db  32h ;3Ah   52    M
  1900.         db  24h ;3Bh   37    J
  1901.         db  16h ;3Ch   23    U
  1902.         db  08h ;3Dh    8    7/&
  1903.         db  09h ;3Eh    9    8/*
  1904.         db    0 ;3Fh+ ---    [Sleep]
  1905.         db    0 ;40h
  1906.         db  33h ;41h   53    ,/<
  1907.         db  25h ;42h   38    K
  1908.         db  17h ;43h   24    I
  1909.         db  18h ;44h   25    O
  1910.         db  0Bh ;45h   11    0/)
  1911.         db  0Ah ;46h   10    9/(
  1912.         db    0 ;47h
  1913.         db    0 ;48h
  1914.         db  34h ;49h   54    ./>
  1915.         db  35h ;4Ah   55    //?
  1916. ;+              ;4Ah+  95    [/]
  1917.         db  26h ;4Bh   39    L
  1918.         db  27h ;4Ch   40    ;/:
  1919.         db  19h ;4Dh   26    P
  1920.         db  0Ch ;4Eh   12    -/_
  1921.         db    0 ;4Fh
  1922.         db    0 ;50h
  1923.         db    0 ;51h
  1924.         db  28h ;52h   41    '/"
  1925.         db    0 ;53h
  1926.         db  1Ah ;54h   27    [/{
  1927.         db  0Dh ;55h   13    =/+
  1928.         db    0 ;56h
  1929.         db    0 ;57h
  1930.         db  3Ah ;58h   39    [Caps Lock]
  1931.         db  36h ;59h   57    [Shift Right]
  1932.         db  1Ch ;5Ah   43    [Enter]
  1933. ;+              ;5Ah+ 108    [+Enter]
  1934.         db  1Bh ;5Bh   28    ]/}
  1935.         db    0 ;5Ch
  1936.         db  2Bh ;5Dh   29    \/|
  1937.         db    0 ;5Eh+ ---    [Wake]
  1938.         db    0 ;5Fh
  1939.         db    0 ;60h
  1940.         db    0 ;61h
  1941.         db    0 ;62h
  1942.         db    0 ;63h
  1943.         db    0 ;64h
  1944.         db    0 ;65h
  1945.         db  0Eh ;66h   15    [BS]
  1946.         db    0 ;67h
  1947.         db    0 ;68h
  1948.         db  4Fh ;69h   93    [1/End]
  1949. ;+              ;69h+  81    [End]
  1950.         db    0 ;6Ah
  1951.         db  4Bh ;6Bh   92    [4/Left]
  1952. ;+              ;6Bh+  79    [<-]
  1953.         db  47h ;6Ch   91    [7/Home]
  1954. ;+              ;6Ch+  80    [Home]
  1955.         db    0 ;6Dh
  1956.         db    0 ;6Eh
  1957.         db    0 ;6Fh
  1958.         db  52h ;70h   99    [0/Ins]
  1959. ;+              ;70h+  75    [Insert]
  1960.         db  53h ;71h  104    [./Del]
  1961. ;+              ;71h+  76    [Delete]
  1962.         db  50h ;72h   98    [2/Down]
  1963. ;+              ;72h+  84    [Down]
  1964.         db  4Ch ;73h   97    [5]
  1965.         db  4Dh ;74h  102    [6/Right]
  1966. ;+              ;74h+  89    [->]
  1967.         db  48h ;75h   96    [8/Up]
  1968. ;+              ;75h+  83    [Up]
  1969.         db  01h ;76h  110    [Esc]
  1970.         db  45h ;77h   90    [Num Lock]
  1971.         db  57h ;78h  122    F11
  1972.         db  4Eh ;79h  106    [+]
  1973.         db  51h ;7Ah  103    [3/Pg Dn]
  1974. ;+              ;7Ah+  86    [Page Down]
  1975.         db  4Ah ;7Bh  105    [-]
  1976.         db  37h ;7Ch  100    [*]
  1977.         db  49h ;7Dh  101    [9/Pg Up]
  1978. ;+              ;7Dh+  85    [Page Up]
  1979.         db  46h ;7Eh  125    [Scroll Lock]
  1980.         db    0 ;7Fh
  1981.         db    0 ;80h
  1982.         db    0 ;81h
  1983.         db    0 ;82h
  1984.         db  41h ;83h  118    F7
  1985. ;===================================================
  1986.         org     7B0h
  1987. ; Установка параметров Таймера 0 (50 герц)
  1988. set_T0: mov     TH0,#HIGH KF_T0 ; Timer0 - High Byte
  1989.         mov     TL0,#LOW  KF_T0 ; Timer0 - Low Byte
  1990.         ret
  1991. ;===================================================
  1992.         org     7B8h
  1993. ; таблица настройки скорости RS232
  1994. tab_spd:
  1995.  if ft_07
  1996. ; Под кварц 7 Мгц
  1997.         db      1-1+80h ;1      115200 SMOD=1
  1998.         db      1-1+80h ;2      57600  SMOD=1
  1999.         db      1-1+80h ;3      38400  SMOD=1
  2000.         db      1-1+80h ;4(6)   19200  SMOD=1
  2001.         db      4-1+80h ;5(12)  9600   SMOD=0
  2002.         db      4-1     ;6(24)  4800
  2003.         db      15-1+80h;7(48)  2400   SMOD=1
  2004.         db      15-1    ;8(98)  1200
  2005.  endif
  2006.  if ft_11
  2007. ; Под кварц 11.0592
  2008.         db      1-1+80h ;1      115200
  2009.         db      1-1+80h ;2      57600  SMOD=1
  2010.         db      1-1     ;3      38400  SMOD=0
  2011.         db      3-1+80h ;4(6)   19200  SMOD=1
  2012.         db      3-1     ;5(12)  9600   SMOD=0
  2013.         db      6-1     ;6(24)  4800
  2014.         db      12-1    ;7(48)  2400
  2015.         db      24-1    ;8(98)  1200
  2016.  endif
  2017. ;----------------------------------------------
  2018.         org     7C0h
  2019. aCopyrightC1995:
  2020.         db 0Dh,0Ah
  2021.         db 'Copyright (C) 1995 Honey Soft',0Dh,0Ah
  2022.         db '  AT Keyboard Driver V3.1'
  2023.  if ft_07
  2024.         db      '07'
  2025.  endif
  2026.  if ft_11
  2027.         db      '11'
  2028.  endif
  2029.  if ft_12
  2030.         db      '12'
  2031.  endif
  2032.  if ft_24
  2033.         db      '24'
  2034.  endif
  2035.         db      0Dh,0Ah,0
  2036.         db 0FFh
  2037. ; =================================================
  2038. ;
  2039.         end
  2040.