;************************************************
; Контроллер AT-клавиатуры на 51-ом контроллере *
;************************************************
; R1 - предыдущий code key
; R2 - code key
; R3 - flags
; d0 - Left Shift
; d1 - Ctrl
; d2 - ALT
; d3
; d4 - Caps Lock trigger
; d5 - Num Lock trigger
; d6 - Scroll Lock trigger
; d7 - RUS(1)/LAT(0)
; R4 - d0 - Right Shift
;--------------------------------
$mod52
; ПОРТЫ
; порт P1(A)
; PA0 - CD input
; PA1 - CTS input
; PA2 - RI input
; PA3 - DTR out
; PA4 - RTS out
; PA5 - INT_T out
; PA6 - /RES -out
; PA7 - W_ON -out
; порт P3
; P30 - RX input
; P31 - TX -output
; P32 - CLK_K input
; P33 - /KEYRD inpit
; P34 - VE1 input
; P35 - DATA_K input
; P36 - /VWR -output
; P37 - /VRD -output
dseg
org 00h
INTMEM_0: ds 1
INTMEM_1: ds 1
INTMEM_2: ds 1
INTMEM_3: ds 1
INTMEM_4: ds 1
org 06h
INTMEM_6: ds 1
INTMEM_7: ds 1
org 10h
INTMEM_10: ds 1
INTMEM_11: ds 1
org 17h
INTMEM_17: ds 1
org 1Fh
INTMEM_1F: ds 1
;--------------------------------------------
org 20h
b_sadr: ds 1 ;буфер скан-адреса
org 2Eh
mode: ds 1
;-----------------------
flags: ds 1
f_wait equ flags.0
f_unpres equ flags.1
f_pref equ flags.2
f_press equ flags.3
f_decod equ flags.5
;-----------------------
org 35h
t_res: ds 3 ;буфер контр.строки
org 38h
; Bufer KBD
INTMEM_38: ds 8 ;
;---------
org 40h
tics: ds 1 ;50 тиков в секунду
b_time: ds 3 ;секунды,минуты,часы
b_date: ds 4 ;день,месяц,год,столетие
b_stek: ds 8 ;стек -> вверх
;_________________________________________
; Часы реального времени
f_tic equ 50 ;Частота тиков Ч.Р.В (Гц)
f_proc equ 7000 ;Частота тактирования (КГц)
; Коэфф.деления таймера 0 равна
;KF_T0 equ -f_proc*1000/12/f_tic
;KF_T0 equ 0D26Eh ; 7.0000 Мгц
;KF_T0 equ 0B800h ;11.0592 МГц
KF_T0 equ 0B1E0h ;12.0000 МГц
;*****************************************
CSEG
ORG 000h
;-----------------------------------------
; Стартовый адрес
start: ljmp prog ;-> запуск программы
; ========================================
ORG 003h
; External interrupt 0 ~\_
extint0:
push PSW
push ACC
ajmp L_23C ; int /CLK_K
; ========================================
ORG 00Bh
; Timer interrupt 0 (Часы реального времени)
timint0:
push PSW
push ACC
ajmp L_3FD
; ========================================
ORG 013h
; External interrupt 1 ~\_
extint1: ;2
push PSW ;2
push ACC ;2
push DPH ;2
ajmp RD_KBD ;2 int /RDKEY
; ========================================
ORG 01Bh
; Timer interrupt 1
timint1:reti
; ========================================
ORG 023h
; Serial port interrupt (SERIAL)
serint: reti
; -------------------------
ORG 02Ch
; Ver 2.200
VERS: db 2,2 ;2.2
db 1,2 ;Тактовая Частота в МГц
;*********************************************
;******* START PROGRAMM **********************
;*********************************************
; Сброс при первом включении
reset: mov R0,#t_res ;Буфер контр.строки
mov @R0,#'A'
inc R0
mov @R0,#'T'
inc R0
mov @R0,#'M'
mov P1, #0BFh ;/RESET=0 (PA6=0)
sjmp $ ;жду своего сброса
;=============================================
; Вход по включению питания
prog: mov P1, #0FFh ;/RESET=1;W_ON=1
; Пауза
clr A
mov PSW,A ; = 00h
mov R0,A
djnz R0, $
djnz R0, $
; При первом включении выдать /RESET
mov R0,#t_res ;буфер контрольной строки
cjne @R0,#'A',reset ;
inc R0
cjne @R0,#'T',reset
inc R0
cjne @R0,#'M',reset
;--------------------------------
; ИНИЦИАЛИЗАЦИЯ УЗЛОВ КОНТРОЛЛЕРА
mov PCON, #80h ; SMOD=1
mov SCON, #0E8h ; Serial Port Control
mov TMOD, #21h ;Timer1=mode2 8-бит
;Timer0=mode1 16-бит
; Set Timer 0 (50 Герц)
mov TH0,#HIGH KF_T0 ; Timer0 - High Byte
mov TL0,#LOW KF_T0 ; Timer0 - Low Byte
; скорость RS232 для тактовой частоты 7 МГц
mov TH1,#-30 ;1215 бод (err=1.3%)
; mov TH1,#-15 ;2431 бод (err=1.3%)
mov TCON, #55h ;Timer0,1-On/INT0,1 -Impuls
; Init MEM; 00h -> RAM 02h..38h
mov R0, #02h ;от 02h
mov R1, #36h ; до 38h
clr A ;
c_clr: mov @R0, A ; обнулить
inc R0
djnz R1,c_clr
;-----------------------------------------------
mov SP, #b_stek ;Указатель стека
mov IP, #01h ; Interrupt Priority
mov IE, #87h ; Interrupt Enable INT0,1,T0
clr P1.7 ;Разрешить /WAIT (W_ON=0)
;/=============================================
c0main: acall L_222 ; Clear buf KBD
;/-------------------------------
; Main Cikl Wait press key
c_main: mov R6, #0 ; Флаг Префикса E0h
acall L_102 ; Wait Code KBD
cjne R5, #0E1h, L_66 ; Pause/Break ?
; Принят первый скан-код клавиши PAUSE
; Press Pause/Break [E1,14,77,E1,F0,14,F0,77]
mov R0, #7-2 ; Count Code (-2 кода F0)
;//---
L_5C: acall L_102 ; Wait Code KBD
djnz R0, L_5C ; 7 раз
;\\---
; Переключиться в режим <ПАУЗА> для чего надо
; запретить прерывание по /RDKBD (INT1)
clr EX1 ; Запретить INT1
setb f_wait ; Flag Wait = 1
sjmp c_main ; Ждать нажатий
;\-------------------------------
; Проверить на допустимость скан-кода
L_66: clr C
mov A, R5
subb A, #84h ; Scan-Code >= 84h
jnc c0main ; err code kbd
; Scan-code normal
jnb f_wait, L_7D ; Нет Pause
; Если был включен режим Pause - сбросить
clr f_press ; Clear Flag Press
clr f_wait ; Clear Flag Wait
mov DPTR, #0 ;
movx @DPTR, A ; /VWR=0 (сброс /WAIT)
setb EX1 ; Разрешить INT1
sjmp c0main ; Ждать еще нажатия
;\==================================================
; Press new key
L_7D: mov A, R5 ; =Scan-code AT IBM
mov DPTR, #L_58F
movc A, @A+DPTR ;code set2 -> code set1
jz c_main ; non code
;\-------------------------------
; Yes normal scan-code set1
mov R7, A ; R7 = scan code set1
jnb f_unpres,no_unpres ;
; клавиша отпущена
orl INTMEM_7,#80h ;установить бит отжатия
no_unpres:
mov INTMEM_17,R7 ;запомнить скан-код set1
dec A
mov R5, A ; R5 = scan code - 1
;
mov A, mode ;Mode
jnz L_AC ;не 00h
; Mode = Spectrum KBD
mov A, R5 ;(Number key-1) (0..
mov DPTR, #L_527 ;
movc A, @A+DPTR ; -> Code key
mov R1, A
acall L_134 ;code key -> bufer KBD
;/---- проверить буфер на предмет нажатых клавиш
mov R0, #INTMEM_38
mov R1, #8
mov A, #0FFh
L_9D: anl A, @R0
inc R0
djnz R1, L_9D
;\----
xrl A, #1Fh
anl A, #1Fh
; No press key если код = 00h
clr f_press ;=0
jz L_B6 ; No press KBD
; Yes press key
L_AC: setb f_press ;=1
;==============================================
; mode non Spectrum KBD
L_B6: mov A, R2
mov R1, A ;R1=R2 - предыдущий код клавиши
setb f_decod ;
; Началось декодирование скан-кода клавиатуры IBM
mov A, R5 ;
rl A ;
mov R5, A ;R5=Scan-code*2
mov DPTR, #L_471
jb f_unpres, L_C9 ;Клавиша отжата
;----
; new code key press
movc A, @A+DPTR ;Scan-code -> Sym Code
jz L_C9
;
mov R2, A ;INTMEM_2=Sym-code 1
;----
; code key unpress
L_C9: mov A, R5 ;
inc A
movc A, @A+DPTR
mov R5, A ;R5=Sym-code 2
acall L_16A ;Decode
clr f_decod
;
sjmp c_main ;Wait next key
;\--------------
;****************************************************
; Процедура приема скан-кода нажатой клавиши ********
L_100: acall L_222 ; Clear Buf KBD
;/-----
; Wait Code KBD
L_102: clr f_unpres ; Flag unpress = 0
; wait code after prefix
L_104: mov A, INTMEM_10 ; R0 page 10
jnz L_11E ; yes new code
; Bufer code KBD empty
L_108: mov A, INTMEM_11 ; R1 page 10
jz L_108 ; Wait begin resive
;
mov INTMEM_1F, #3 ; R7 page 18=3
;//----
L_10F: mov A, INTMEM_10 ; R0 page 10
jnz L_11E ; yes code key
;
mov A, INTMEM_1F ;
jnz L_10F ; wait code
;\\---- истек тайм-аут приема скан-кода -----
mov INTMEM_10, A ; 00h -> R0 page 10
mov INTMEM_11, A ; 00h -> R1 page 10
mov R6, A ; 00h -> R6
sjmp L_102 ; wait new code
;\------
; принят скан-код клавиатуры
L_11E: mov R5, A ; Get code KBD
mov INTMEM_10, #0 ; 00h -> R0 Page 10
cjne A, #0E0h, L_129
; Resive prefix 0E0h (next code)
mov R6, #1 ; flag prefix key
sjmp L_104 ; Get Second code
;--------------------------------
; NO prefix = 0E0h
L_129: cjne A, #0F0h, L_130
; Resive ptefix 0F0h (unpress)
setb f_unpres ; Flag unpress=1
sjmp L_104 ;Get second code
;--------------------------------
; No prefix 0E0h & 0F0h
L_130: inc A ;если = 0FFh
jz L_100 ;err code
ret
; Конец процедуры приема скан-кода клавиатуры ***
;************************************************
; R1 (code key) -> bufer Spectrum KBD
; f_unpress = 1 - clear code from bufer
L_134: mov A, R1
jnb ACC.3, L_13E
; ACC.3 = 1 -> Caps Shift
mov A, #1 ;D0
mov R0, #0 ;A8
acall L_15D
; ACC.3 = 0
L_13E: mov A, R1
jnb ACC.7, L_148
; ACC.7 = 1 -> Symbol Shift
mov A, #2 ;D1
mov R0, #7 ;A15
acall L_15D
; ACC.7 = 0
L_148: mov A, R1
anl A, #7
jnz L_14E
; d2..d0 = 000
ret
; d2..d0 <> 000
L_14E: mov R0, A
clr A
setb C
L_151: rlc A
djnz R0, L_151
;
push ACC
mov A, R1
swap A
anl A, #7
mov R0, A ;Adress
pop ACC ;Date
;-----
L_15D: orl INTMEM_0, #INTMEM_38 ;R0
jnb f_unpres, L_166
; Press key - set code
orl A, @R0
mov @R0, A
ret
; Unpress key - clear code from bufer
L_166: cpl A
anl A, @R0
mov @R0, A
ret
; end mode Spectrum KBD
; ========================================
; DECODE Second byte in Tab
; R5 -> ctrl code (mode CP/M)
; R6=1 prefix 0E0h
;
L_16A: mov A, R5 ;
jnz L_16E
; 00h -> exit
L_16D: ret
;
L_16E: anl A, #3 ;d1,d0
jnz L_1A6 ;ALT,Ctrl,Shift
; d1,d0=00
jb f_unpres, L_16D ;exit
;--------------
; press new key
mov A, R5
anl A, #0Ch ;d3,d2
jnz L_1D2
;d3,d2=00
mov A, R5
anl A, #30h ;d5,d4
jnz L_1E4 ;
;d5,d4=00
L_17F: mov A, R5
jb ACC.6, L_19F ;*40h
;d6=0
jnb ACC.7, L_16D ;d7,d6=0 Exit
;d6=0,d7=1 (80h)
mov A, R3
orl A, R4
anl A, #6
cjne A, #6, L_192 ;bits Ctrl,Alt
; Ctrl+Alt
cjne R2, #2Eh, L_16D ;Exit
; press [.]
ajmp reset ;Reset COMP
;-------
; no Ctrl+Alt
L_192: cjne R6, #1, L_1A2 ;set D7
; R6=1 (prefix 0E0h)
mov A, R7 ;Scan code set1
clr C
subb A, #47h ;-47h Код [dig.7]
mov DPTR, #L_582 ;
movc A, @A+DPTR
mov R2, A ;new code
ret
;-------
;^ D6=1
L_19F: mov A, R6 ; R6=0?
jz L_16D ; exit
; R6=1 (prefix 0E0h)
L_1A2: orl INTMEM_2, #80h ;set D7(R2)
ret
;----------
; d1,d0 <>0
L_1A6: anl INTMEM_7, #7Fh ;R7
cjne A, #3, L_1FC
; R5=03h (Left Shift & Right Shift)
mov A, #1 ;bit0 (Flag Shift)
mov R6, #0
cjne R7, #36h, L_1B5 ;Code set1 Right Shift ?
; press Right Shift
mov R6, #1 ;Flag Right Shift=1
L_1B5: jnb f_unpres, L_1C2
; key unpress
cpl A
cjne R6, #1, L_1BF
; R6=1 (Right Shift)
anl INTMEM_4, A ;R4(d0)=0
ret
; R6=0 (Left Shift)
L_1BF: anl INTMEM_3, A ;R3(d0)=0
ret
; key press
L_1C2: cjne R6, #1, L_1D4
; Right Shift
cjne A, #1, L_1CE
; нажат Right Shift
mov A, R3 ;Проверить Left Shift
anl A,#1
jnz L_1DC
; Left Shift еще не нажат
inc A ;A=1
L_1CE: orl INTMEM_4, A ;R4 bit 0=1
sjmp L_1EC
;------
;^ d3,d2<>0
L_1D2: sjmp L_203
;--------------------------------
;
L_1D4: cjne A, #1, L_1EA
; нажат Left Shift
mov A,R4 ;проверить Right Shift
anl A,#1
jz L_1E8 ;еще не нажат
; был нажат
L_1DC: mov R2, #7Ah ;'z' (в XT R2) было R0
cpl A
anl INTMEM_3, A ;
anl INTMEM_4, A ;
ret
;-------
;^ d5,d4<>0
L_1E4: sjmp L_21A ;test 20,30
;-------
;v non Ctrl+Alt
L_1E6: sjmp L_17F
;--------------------------------
; Нажат Left Shift без Right Shift
L_1E8: mov A, #1
L_1EA: orl INTMEM_3, A ;R3(d0)=1
;
L_1EC: mov A, R3
orl A, R4
anl A, #6
cjne A, #6, L_1E6
; press Ctrl(d1)+Alt(d2)
cjne R7, #53h, L_219 ;Scan-cod1 DEL =53h
; Ctrl+Alt+Del
ajmp reset ;Сброс Speccy
;-----
L_1FC: cjne A, #1, L_1B5
; Code ALT = 1
mov A, #4 ;bit2 (flag ALT)
sjmp L_1B5
;------
;^ d3,d2<>0
L_203: jb f_unpres, L_1E6 ;
; key press
cjne A, #0Ch, L_20F ;d3,d2=11
; A=0Ch (Scroll Lock)
cjne R6, #1, L_20F
; R6=1 (prefix 0E0h)
mov R2, #6Fh ;'o'
ret
;-----
L_20F: rr A ;/2
rr A ;/4
mov R5, A
mov A, #8 ;bit3=1
L_214: rl A
djnz R5, L_214
; trigger bit
xrl INTMEM_3, A ;R3
L_219: ret
;------
; второй код = 20h/30h
L_21A: cjne A, #20h, L_21F
; A=20h
sjmp L_1EC
;
L_21F: cjne A, #30h, L_219 ;ret
; A=30h
; ========================================
; Clear buf KBD
L_222: mov A, #0FFh
mov R0, #INTMEM_38
mov R1, #8
L_228: mov @R0, A
inc R0
djnz R1, L_228
;\----
clr A
clr f_press
mov INTMEM_11, A ;R1 page10=0
mov INTMEM_10, A ;R0 page10=0
mov R2, A
mov R3, A
mov R4, A
mov R6, A
ret
; ==========================================
; Прием скан кода нажатой или отжатой клавиши
; CLK_KBD = ~\_
L_23C: ; int0
mov PSW, #10h
;-----
mov C, P3.5 ; P3.5 <- DAT_KBD
mov A, R1
jz L_257 ;R1=0 START
;-----
dec A
jz L_25B ;R1=1 Прием данных
;-----
dec A
jz L_266 ;R1=2 Паритет
;----- ;R1=3 STOP
mov R1, #0 ;00h -> INTMEM_11
mov A, R5 ;Результат приема
mov R0, A ;code -> INTMEM_10
;-----
pop ACC
pop PSW
reti
;-----
; Принят стартовый бит данных
L_257: mov R6, #8 ;Resive 8 bit
sjmp L_260
; -------------------------
; Прием битов данных
L_25B: mov A, R5
rrc A
mov R5, A
djnz R6, L_261
; Принято 8 бит данных
L_260: inc R1
L_261: pop ACC
pop PSW
reti
;-----
; Прием бита паритета
L_266: mov A, R5 ;Принятый байт
jc L_270 ;Бит паритета = 1
;
jb PSW.0, L_260 ; PSW.0 - ACCUMULATOR PARITY FLAG
L_26C: mov R5, #0FFh ; результат при ошибке паритета
sjmp L_260
; -------------------------
L_270: jnb PSW.0, L_260 ; PSW.0 - ACCUMULATOR PARITY FLAG
sjmp L_26C
; =============================================
; Вход запроса кода Клавиатуры от Spectruma
; =============================================
;int1: push PSW ;2
; push ACC ;2
; push DPH ;2
; ajmp RD_KBD ;2
; Int /RDKBD
RD_KBD: ; extint1
jnb P3.4, L_2AF ;2 VE1=0
; Работа контроллера запрещена
mov A, #0FFh ;1
mov DPH, #01h ;1 DPTR=#01xx
movx @DPTR, A ;2 /VWR=0 -> Сбросить /WAIT
setb P1.7 ;1 W_ON=1 Запрет прерываний
; Спектрум работает без /WAIT с механической клавиатурой
L_292: jb P3.4,$ ;2 Ждем VE1=0
; дождались разрешения работы с AT клавиатурой
clr P1.7 ;1 W_ON=0
mov PSW, #8 ;2
clr A ;1
clr f_press ;1
mov INTMEM_6, A ;1
mov INTMEM_10, A ;1
mov INTMEM_11, A ;1
mov R7, A ;1 флаг команды=0
mov R1, A ;1 Z код клавиатуры = 0
sjmp ex_kbd ;2
;************************************************
; Принят код сканирования не 55h (не команда)
no_comm:
mov b_sadr,A ;Скан-адрес -> бит-регистр
inc DPH ;DPTR=#01xx
mov A, mode ;Текущий режим ?
jnz no_m00 ;mode>00h
;================================================
; mode = 00 -> Spectrum KBD
jb f_press,kbd_ve ;есть нажатие
; если нет нажатия, то
movx A,@DPTR ;Порт принтера Speccy
movx @DPTR,A ; Снять /WAIT
ex_kbd: pop DPH
pop ACC
pop PSW
reti
; ================================================
; mode = 00 -> Spectrum KBD (есть нажатие)
kbd_ve:
; РАзвернутый цикл сканирования матрицы
dec A ;A=#0FFh
jb b_sadr.0,A08_1
anl A,INTMEM_38 ;
A08_1: jb b_sadr.1,A09_1
anl A,INTMEM_38+1
A09_1: jb b_sadr.2,A10_1
anl A,INTMEM_38+2
A10_1: jb b_sadr.3,A11_1
anl A,INTMEM_38+3
A11_1: jb b_sadr.4,A12_1
anl A,INTMEM_38+4
A12_1: jb b_sadr.5,A13_1
anl A,INTMEM_38+5
A13_1: jb b_sadr.6,A14_1
anl A,INTMEM_38+6
A14_1: jb b_sadr.7,A15_1
anl A,INTMEM_38+7
A15_1: mov R4,A ;Код контроллера
;\----
movx A,@DPTR ;Порт Spec KBD
anl A,R4 ;+ код контроллера
; -------------------------
movx @DPTR,A ; Снять /WAIT
pop DPH
pop ACC
pop PSW
reti
;=========================================
; VE1=0 разрешена работа контроллера
L_2AF: mov PSW, #8 ;2
mov DPH, #00h ;2 DPTR=#00xx
movx A, @DPTR ;2 A=Adress A15..A8
; проверить признак приема команды (R7)
cjne R7,#0,L_31B ;2 Анализ параметров команды
;--------------------------------
; Test COMM=055h
cjne A,#55h,no_comm ;2 если не 55h, то не команда
;--------------------------------
; Ответить на прием кода 55h
inc R7 ;1 R7=1 (принят код команды)
mov A,#0AAh ;1 Request = 0AAh
inc DPH ;1 DPH=#01h Передать и
movx @DPTR, A ;2 Снять /WAIT
pop DPH ;2
pop ACC ;2
pop PSW ;2
reti ;2
;*****************************************
; mode = 01,02,03
no_m00: cjne A,#01h,no_m01 ;01h ?
;========================================
; Mode = 01h - RD code KBD
; читается код клавиатуры (R2) или (R1)
L_2EB: mov A,INTMEM_1 ;R1 page 00
jb f_decod, L_2F2 ;
; no decode
mov A,INTMEM_2 ;R2 page 00
mov INTMEM_2,#0 ;00h -> R2
L_2F2: movx @DPTR, A ; Снять /WAIT
pop DPH
pop ACC
pop PSW
reti
;============================================
no_m01: cjne A,#02h,no_m02 ;02h ?
; ===========================================
; Mode =02h - CP/M
; Читаются регистры R2(или R1),(R3),(R4)
; в зависимости от состояния битов A15,A14
mov A,b_sadr ; Adress сканирования Axx
rl A
rl A
anl A, #3 ; A15.A14 ?
jz L_2EB ; A15,A14=00
; -------------------------------
add A,#INTMEM_2 ;1..3 + #INTMEM_2
mov R1,A ;
mov A,@R1 ;(R3)..(R5)
movx @DPTR, A ; Снять /WAIT
pop DPH
pop ACC
pop PSW
reti
;=========================================
; Mode = 03h - Direct RD
no_m02: mov A,INTMEM_17 ;R7 Page10
mov INTMEM_17,#0 ;
movx @DPTR, A ; Снять /WAIT
pop DPH
pop ACC
pop PSW
reti
;************************************************
;****** Прием параметров команды ****************
;************************************************
L_31B: mov R6,A ;Скан-адрес -> R6
mov A,R3 ;Код команды
cjne R7,#1,L_344 ;R7=2 (второй параметр)
; first Param=Code COMM
mov A, R6
rl A
rl A
anl A, #3
mov R5, A ;Adress COMM =A15..A14
;
mov A, R6 ;A15..A8
anl A, #3Fh
jz L_33E ; Если =0, выход с A=0FFh
mov R3, A ;R3=Code COMM
;*************************************************
;********** TEST CODE COMM **********************
;*************************************************
L_344: cjne A, #1, L_34E ;Код команды # 01h ?
; COMM = 01h Get Vers.
push DPL
mov DPTR, #vers ;Buf Ver.
mov A, R5 ;0..3 (Adress Param)
movc A, @A+DPTR ;
pop DPL
sjmp L_340 ;
; -------------------------
L_34E: cjne A, #7, L_35C
; COMM = 07h
mov R0,#INTMEM_38 ;Буфер клавиатуры
mov R1,#8
L_355: mov @R0, #0FFh ;все <1>
inc R0
djnz R1, L_355
;-----
sjmp L_33E
; -------------------------
L_35C: cjne A, #8, L_376
; COMM = 08h,<mode>
cjne R7, #2, L_3C5
; Second param =<mode>
mov A, R6 ;Второй параметр команды
anl A,#03h ;младшие 2 бита
mov mode, A ; Mode
mov INTMEM_2,#0 ;Сброс кода
; Завершение команды - выход с кодом 0FFh
L_33E: mov A, #0FFh ;выход с A=0FFh
L_340: mov R7, #0 ;
L_2F3: mov DPH,#01h ;DPTR=#01xx
movx @DPTR, A ; Снять /WAIT
pop DPH
pop ACC
pop PSW
reti
; -------------------------
L_376: cjne A, #9, L_37F
; COMM = 09h,49h,89h,C9h
mov A, R5 ;0..3
inc A ;1..4
mov R0, A
mov A, @R0 ;A=(R1)..(R4)
sjmp L_340
; -------------------------
L_37F: cjne A, #0Ah, L_387
; COMM=0Ah Set RUS
orl INTMEM_3, #80h ; Set RUS (было INTMEM_1)
sjmp L_33E ;выход с A=0FFh
; -------------------------
L_387: cjne A, #0Bh, L_38F
; COMM=0Bh Set LAT
anl INTMEM_3, #7Fh ; Set LAT (было INTMEM_1)
sjmp L_33E ;выход с A=0FFh
; -------------------------
L_38F: cjne A, #0Ch, L_396
; COMM=0Ch
setb f_wait ; Set Wait ON
sjmp L_33E ;выход с A=0FFh
; -------------------------
L_396: cjne A, #0Dh, L_39B
; COMM=0Dh
ajmp reset ; Reset Computer
; -------------------------
L_39B: cjne A, #10h, L_3A4
; COMM=10h (запрос текущего времени)
mov A, #b_time ;секунды
acall L_3E7 ; Get Time
ajmp L_2F3
; -------------------------
L_3A4: cjne A, #11h, L_3AD
; COMM=11h (установка текущего времени)
mov A, #b_time
acall L_3ED ; Set Time
ajmp L_2F3
; -------------------------
L_3AD: cjne A, #12h, L_3B6
; COMM=12h (запрос текущей даты)
mov A, #b_date ; Буфер даты
acall L_3E7 ; Get DATA
ajmp L_2F3
; -------------------------
L_3B6: cjne A, #13h, L_3BF
; COMM=13h (установка текущей даты)
mov A, #b_date ; Буфер даты
acall L_3ED ; Set DATA
ajmp L_2F3
; -------------------------
L_3BF: cjne A, #14h, L_3CD ;
; COMM=14h (установка битов порта P1)
cjne R7, #1, L_3C8
; R7=1
L_3C5: inc R7 ; R7=2
mov A,#0FFh
ajmp L_2F3
; ---
; R7=2
L_3C8: mov A, R6
orl P1, A
ajmp L_33E ;Выход с A=0FFh
; -------------------------
L_3CD: cjne A, #15h, L_3D9
; COMM=15h (сброс битов порта P1)
cjne R7, #2, L_3C5 ;R7=1
; R7=2
mov A, R6
cpl A
anl P1, A
L_3D7: ajmp L_33E ;выход с A=0FFh
; -------------------------
L_3D9: cjne A, #16h, L_3E0
; COMM=16h (чтение порта P3)
mov A, P3
ajmp L_340 ;выход с A=P3
; -------------------------
L_3E0: cjne A, #17h, L_3D7 ;выход с A=0FFh
; COMM=17h (чтение порта P1)
mov A, P1
ajmp L_340 ;выход с A=P1
; End Decode Command
; ========================================
; Get data
L_3E7: add A, R5
mov R0, A
mov A, @R0
mov R7, #0
ret
; ========================================
L_3ED: cjne R7, #2, L_3F9
; Set data
mov R7, #0
add A, R5
mov R0, A
mov A, R6
mov @R0, A
mov A, #0FFh
ret
; -------------------------
; First Param = adress param -> R5
L_3F9: mov A, #0FFh
inc R7 ; R7=2
ret
;**********************************************
; Timer 0 (часы реального времени)
;**********************************************
L_3FD: ; timint0
mov PSW, #18h
; Счетчик тайм-аута клавиатуры
mov A, R7 ; INTMEM_1F
jz L_408 ;
dec R7 ; -1
L_408:
;--------------------------------
djnz tics,L_45A ;
;
mov tics, #f_tic ;50 тиков в секунду
mov R0, #b_time ;Буфер времени
inc @R0
cjne @R0, #60, L_45A ;<60 секунд
;
mov @R0, #0 ;
inc R0
inc @R0
cjne @R0, #60, L_45A ;<60 минут
;
mov @R0, #0
inc R0
inc @R0
cjne @R0, #24, L_45A ;<24 часов
;
mov @R0, #0
;
inc R0
inc @R0 ;след.день
mov A, @R0
mov R2, A
inc R0
mov A, @R0 ;Номер месяца
push DPL
push DPH
mov DPTR, #L_465-1 ;Таблица дней
movc A, @A+DPTR
pop DPH
pop DPL
cjne @R0, #2, L_445
;
inc R0
mov R3, A
mov A, @R0
dec R0
rrc A
jc L_444
rrc A
jc L_444
inc R3
L_444: mov A, R3
;
L_445: clr C
subb A, R2
jnc L_45A
;
dec R0
mov @R0, #1
inc R0
inc @R0
cjne @R0, #13, L_45A ;<13
;
mov @R0, #1
inc R0
inc @R0
cjne @R0, #100, L_45A ;<100
;
mov @R0, #0
;
L_45A: mov TH0,#HIGH KF_T0 ; Timer0 - High Byte
mov TL0,#LOW KF_T0 ; Timer0 - Low Byte
pop ACC
pop PSW
reti
; -------------------------
;
ORG 600h
;----------------------------------------
; Число дней в месяцах
L_465: db 31 ;Январь
db 28 ;Февраль
db 31 ;Март
db 30 ;Апрель
db 31 ;Май
db 30 ;Июнь
db 31 ;Июль
db 31 ;Август
db 30 ;Сентябрь
db 31 ;Октябрь
db 30 ;Ноябрь
db 31 ;Декабрь
;----------------------------------------
; Таблица CP/M - кодов клавиатуры
L_471: db 1Bh ; ESC
db 0 ;
;
db 31h ; 1
db 0 ;
;
db 32h ; 2
db 0 ;
;
db 33h ; 3
db 0 ;
;
db 34h ; 4
db 0 ;
;
db 35h ; 5
db 0 ;
;
db 36h ; 6
db 0 ;
;
db 37h ; 7
db 0 ;
;
db 38h ; 8
db 0 ;
;
db 39h ; 9
db 0 ;
;
db 30h ; 0
db 0 ;
;
db 2Dh ; -/_
db 0 ;
;
db 3Dh ; =/+
db 0 ;
;
db 8 ; BS
db 0 ;
;
db 9 ; TAB
db 0 ;
;
db 51h ; Q
db 0 ;
;
db 57h ; W
db 0 ;
;
db 45h ; E
db 0 ;
;
db 52h ; R
db 0 ;
;
db 54h ; T
db 0 ;
;
db 59h ; Y
db 0 ;
;
db 55h ; U
db 0 ;
;
db 49h ; I
db 0 ;
;
db 4Fh ; O
db 0 ;
;
db 50h ; P
db 0 ;
;
db 5Bh ; [
db 0 ;
;
db 5Dh ; ]
db 0 ;
;
db 0Dh ; Enter
db 0C0h ;
;
db 0 ; Ctrl
db 2 ; bit 1 (R3)
;
db 41h ; A
db 0 ;
;
db 53h ; S
db 0 ;
;
db 44h ; D
db 0 ;
;
db 46h ; F
db 0 ;
;
db 47h ; G
db 0 ;
;
db 48h ; H
db 0 ;
;
db 4Ah ; J
db 0 ;
;
db 4Bh ; K
db 0 ;
;
db 4Ch ; L
db 0 ;
;
db 3Bh ; ;
db 0 ;
;
db 27h ; '
db 0 ;
;
db 60h ; `
db 0 ;
;
db 0 ; Left Shift
db 3 ; bit0 R3
;
db 5Ch ; \
db 0 ;
;
db 5Ah ; Z
db 0 ;
;
db 58h ; X
db 0 ;
;
db 43h ; C
db 0 ;
;
db 56h ; V
db 0 ;
;
db 42h ; B
db 0 ;
;
db 4Eh ; N
db 0 ;
;
db 4Dh ; M
db 0 ;
;
db 2Ch ; ,
db 0 ;
;
db 2Eh ; .
db 0 ;
;
db 2Fh ; /
db 40h ;
;
db 0 ; Rght Shift
db 3 ; bit0 R4
;
db 0AAh ; \/|
db 0 ;
;
db 0 ; ALT
db 1 ; bit2 R3
;
db 20h ; SPACE
db 0 ;
;
db 0 ; CapS LOck
db 4 ; bit4 R3 (trigger)
;----
db 61h ; F1
db 0 ;
;
db 62h ; F2
db 0 ;
;
db 63h ; F3
db 0 ;
;
db 64h ; F4
db 0 ;
;
db 65h ; F5
db 0 ;
;
db 66h ; F6
db 0 ;
;
db 67h ; F7
db 0 ;
;
db 68h ; F8
db 0 ;
;
db 69h ; F9
db 0 ;
;
db 6Ah ; F10
db 0 ;
;
db 0 ; Num Lock
db 8 ; bit5 R3 (trigger)
;
db 0 ; Scroll Lock
db 0Ch ; bit6 R3 (trigger)
;----------------------------------
; Num keyboard scan code set1 > 47h
db 37h ;47h [7]
db 80h ;set bit7 R2
;
db 38h ;48h [8]
db 80h ;
;
db 39h ;49h [9]
db 80h ;
;
db 2Dh ;4Ah [-]
db 80h ;
;
db 34h ;4Bh [4]
db 80h ;
;
db 35h ;4Ch [5]
db 80h ;
;
db 36h ;4Dh [6]
db 80h ;
;
db 2Bh ;4Eh [+]
db 80h ;
;
db 31h ;4Fh [1]
db 80h ;
;
db 32h ;50h [2]
db 80h ;
;
db 33h ;51h [3]
db 80h ;
;
db 30h ;52h [0]
db 80h ;
;
db 2Eh ;53h [.]
db 80h ;
;
db 0 ;54h
db 0 ;
;
db 0 ;55h
db 0 ;
;
db 0 ;56h
db 30h ;
;
db 6Bh ;57h F11
db 0 ;
;
db 6Ch ;58h F12
db 0 ;
;
db 0 ;59h
db 0 ;
;
db 0 ;5Ah
db 0 ;
;
db 0 ;5Bh
db 0 ;
;
;----------------------------------------
; Scan-code IBM(1) -> code Spectrum
; D7 - Symbol Shift
; D6..D4 - Number bit Adress (A8=000..A15=111)
; D3 - Caps Shift
; D2..D0 - Number bit Data (D0=001..D4=101)
L_527:
db 39h ;01 ESC CapSh + 1
;
db 31h ;02 1/!
db 32h ;03 2/@
db 33h ;04 3/#
db 34h ;05 4/$
db 35h ;06 5/%
;
db 45h ;07 6/^
db 44h ;08 7/&
db 43h ;09 8/*
db 42h ;0A 9/(
db 41h ;0B 0/)
;
db 0E4h ;0C -/_ SymSh+Kl_J
db 0E2h ;0D =/+ SymSh+Kl_L
db 49h ;0E BS CapSh+Kl_0
db 3Bh ;0F TAB CapSh+Kl_3
;
db 21h ;10 Q
db 22h ;11 W
db 23h ;12 E
db 24h ;13 R
db 25h ;14 T
;
db 55h ;15 Y
db 54h ;16 U
db 53h ;17 I
db 52h ;18 O
db 51h ;19 P
;
db 0D5h ;1A [/{ SymSh+Kl_Y
db 0D4h ;1B ]/} SymSh+Kl_U
db 61h ;1C ENTER
db 88h ;1D Ctrl CapSh+SymSh
;
db 11h ;1E A
db 12h ;1F S
db 13h ;20 D
db 14h ;21 F
db 15h ;22 G
;
db 65h ;23 H
db 64h ;24 J
db 63h ;25 K
db 62h ;26 L
;
db 0D2h ;27 ;/: SymSh+Kl_O
db 0D1h ;28 '/" SymSh+Kl_P
db 91h ;29 `/~ CapSh+Kl_A
;
db 08h ;2A Left Shift CapSh
db 92h ;2B \/| CapSh+Kl_S
;
db 02h ;2C Z
db 03h ;2D X
db 04h ;2E C
db 05h ;2F V
;
db 75h ;30 B
db 74h ;31 N
db 73h ;32 M
;
db 0F4h ;33 ,/< SymSh+Kl_N
db 0F3h ;34 ./> SymSh+Kl_M
db 85h ;35 //? SymSh+Kl_V
db 80h ;36 Rght Shift SymSh
db 0F5h ;37 [*] SymSh+Kl_B
db 3Ch ;38 Alt CapSh+Kl_4
;
db 71h ;39 SPACE
;
db 3Ah ;3A CapsLock CapSh+Kl_2
;
db 0B1h ;3B F1 SymSh+Kl_1
db 0B2h ;3C F2 SymSh+Kl_2
db 0B3h ;3D F3 SymSh+Kl_3
db 0B4h ;3E F4 SymSh+Kl_4
db 0B5h ;3F F5 SymSh+Kl_5
db 0C5h ;40 F6 SymSh+Kl_6
db 0C4h ;41 F7 SymSh+Kl_7
db 0C3h ;42 F8 SymSh+Kl_8
db 0C2h ;43 F9 SymSh+Kl_9
db 0C1h ;44 F10 SymSh+Kl_0
;
db 0 ;45 NumLock
db 0 ;46 ScrollLock
;
db 3Ch ;47 [7] CapSh+Kl_4
db 4Ch ;48 [8] [Up] CapSh+Kl_7
db 3Dh ;49 [9] CapSh+Kl_5
db 0E4h ;4A [-] SymSh+Kl_J
db 3Dh ;4B [4] CapSh+Kl_5
db 35h ;4C [5] 5
db 4Bh ;4D [6] CapSh+Kl_8
db 0E3h ;4E [+] SymSh+Kl_K
db 4Ah ;4F [1] CapSh+Kl_9
db 4Dh ;50 [2] CapSh+Kl_6
db 4Bh ;51 [3] CapSh+Kl_8
db 84h ;52 [Insert] SymSh+Kl_C
db 49h ;53 [Delete] CapSh+Kl_0
db 0 ;54
db 0 ;55
db 0 ;56
db 0E5h ;57 F11 SymSh+Kl_H
db 94h ;58 F12 SymSh+Kl_F
db 0 ;59
db 0 ;5A
db 0 ;5B
;-----------------------------------------
; Tab for Num KBD
L_582: db 76h ;47h Home
db 70h ;48h Cur Up
db 74h ;49h Page Up
db 0ADh ;4Ah [-]
db 72h ;4Bh Cur Left
db 0B5h ;4Ch [5]
db 73h ;4Dh Cur Right
db 0ABh ;4Eh [+]
db 77h ;4Fh End
db 71h ;50h Cur Down
db 75h ;51h Page Down
db 78h ;52h Insert
db 79h ;53h Del
;-----------------------------------------
; Tab Scan-code Set 2 -> Scan-code Set 1
L_58F: db 0 ;00h
db 43h ;01h F9
db 0 ;02h
db 3Fh ;03h F5
db 3Dh ;04h F3
db 3Bh ;05h F1
db 3Ch ;06h F2
db 58h ;07h F12
db 0 ;08h
db 44h ;09h F10
db 42h ;0Ah F8
db 40h ;0Bh F6
db 3Eh ;0Ch F4
db 0Fh ;0Dh [Tab]
db 29h ;0Eh ~/`
db 0 ;0Fh
db 0 ;10h
db 38h ;11h ALT
db 2Ah ;12h Left Shift
db 0 ;13h
db 1Dh ;14h [Ctrl]
db 10h ;15h Q
db 2 ;16h 1/!
db 0 ;17h
db 0 ;18h
db 0 ;19h
db 2Ch ;1Ah Z
db 1Fh ;1Bh S
db 1Eh ;1Ch A
db 11h ;1Dh W
db 3 ;1Eh 2/@
db 0 ;1Fh
db 0 ;20h
db 2Eh ;21h C
db 2Dh ;22h X
db 20h ;23h D
db 12h ;24h E
db 5 ;25h 4/$
db 4 ;26h 3/#
db 0 ;27h
db 0 ;28h
db 39h ;29h [Space]
db 2Fh ;2Ah V
db 21h ;2Bh F
db 14h ;2Ch T
db 13h ;2Dh R
db 6 ;2Eh 5/%
db 0 ;2Fh
db 0 ;30h
db 31h ;31h N
db 30h ;32h B
db 23h ;33h H
db 22h ;34h G
db 15h ;35h Y
db 7 ;36h 6/^
db 0 ;37h
db 0 ;38h
db 0 ;39h
db 32h ;3Ah M
db 24h ;3Bh J
db 16h ;3Ch U
db 8 ;3Dh 7/&
db 9 ;3Eh 8/*
db 0 ;3Fh
db 0 ;40h
db 33h ;41h ,/<
db 25h ;42h K
db 17h ;43h I
db 18h ;44h O
db 0Bh ;45h 0/)
db 0Ah ;46h 9/(
db 0 ;47h
db 0 ;48h
db 34h ;49h ./>
db 35h ;4Ah //?
db 26h ;4Bh L
db 27h ;4Ch ;/:
db 19h ;4Dh P
db 0Ch ;4Eh -/_
db 0 ;4Fh
db 0 ;50h
db 0 ;51h
db 28h ;52h '/"
db 0 ;53h
db 1Ah ;54h [/{
db 0Dh ;55h =/+
db 0 ;56h
db 0 ;57h
db 3Ah ;58h [Caps Lock]
db 36h ;59h [Right Shift]
db 1Ch ;5Ah [Enter]
db 1Bh ;5Bh ]/}
db 0 ;5Ch
db 2Bh ;5Dh \/|
db 0 ;5Eh
db 0 ;5Fh
db 0 ;60h
db 0 ;61h
db 0 ;62h
db 0 ;63h
db 0 ;64h
db 0 ;65h
db 0Eh ;66h [BS]
db 0 ;67h
db 0 ;68h
db 4Fh ;69h [End]
db 0 ;6Ah
db 4Bh ;6Bh [Left]
db 47h ;6Ch [Home]
db 0 ;6Dh
db 0 ;6Eh
db 0 ;6Fh
db 52h ;70h [Insert]
db 53h ;71h [Delete]
db 50h ;72h [Down]
db 4Ch ;73h [5]
db 4Dh ;74h [Right]
db 48h ;75h [Up]
db 1 ;76h [Esc]
db 45h ;77h [Num Lock]
db 57h ;78h F11
db 4Eh ;79h [+]
db 51h ;7Ah [3] и [Page Down]
db 4Ah ;7Bh [-]
db 37h ;7Ch [*]
db 49h ;7Dh [9] и [Page up]
db 46h ;7Eh [Scroll Lock]
db 0 ;7Fh
db 0 ;80h
db 0 ;81h
db 0 ;82h
db 41h ;83h F7
db 0 ;84h
db 0 ;85h
db 0 ;86h
;----------------------------------------------
org 7C0h
aCopyrightC1995:
db 0Dh,0Ah
db 'Copyright (C) 1995 Honey Soft',0Dh,0Ah
db ' AT Keyboard Driver V2.212',0Dh,0Ah,0
; =================================================
;
end