Subversion Repositories atmturbo

Rev

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

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