├── kbdbabel-lk-ps2 ├── 89c2051-lk-ps2.brd ├── 89c2051-lk-ps2.sch └── kbdbabel_lk_ps2_8051.bin ├── kbdbabel-pc-ps2 ├── 89c2051-pc-ps2.brd ├── 89c2051-pc-ps2.sch └── kbdbabel_ps2_pcxt_8051.asm ├── kbdbabel-st-ps2 ├── 89c2051-st-ps2.brd ├── 89c2051-st-ps2.sch └── kbdbabel_st_ps2_8051.asm ├── kbdbabel-mac-ps2 ├── 89c2051-mac-ps2.brd ├── 89c2051-mac-ps2.sch └── kbdbabel_mac_ps2_fmode_8051.asm ├── kbdbabel-ps2-dec ├── 89c2051-ps2-dec.brd ├── 89c2051-ps2-dec.sch └── kbdbabel_pcxt_dec_8051.asm ├── kbdbabel-ps2-sun ├── 89c2051-ps2-sun.brd ├── 89c2051-ps2-sun.sch └── kbdbabel_pcxt_sun_8051.asm ├── kbdbabel-sun-ps2 ├── 89c2051-sun-ps2.brd ├── 89c2051-sun-ps2.sch ├── kbdbabel_sun_ps2_8051.bin └── kbdbabel_sun_ps2_8051.asm ├── kbdbabel-xdb-ps2 ├── 89c2051-xdb-ps2.brd └── 89c2051-xdb-ps2.sch ├── kbdbabel-a5000-ps2 ├── 89c2051-a5000-ps2.brd └── 89c2051-a5000-ps2.sch ├── kbdbabel-ibm3104 ├── 89c2051-ibm3104-ps2.brd └── 89c2051-ibm3104-ps2.sch ├── kbdbabel-ibm3151 ├── 89c2051-ibm3151-ps2.brd └── 89c2051-ibm3151-ps2.sch ├── kbdbabel-kc85-ps2 ├── 89c2051-kc85-ps2.brd ├── 89c2051-kc85-ps2.sch └── kbdbabel_kc85_ps2_8051.asm ├── kbdbabel-wy85-ps2 ├── 89c2051-wy85-ps2.brd ├── 89c2051-wy85-ps2.sch └── kbdbabel_wy85_ps2_8051.asm ├── kbdbabel-hp9816-ps2 ├── 89c2051-hp9816-ps2.brd └── 89c2051-hp9816-ps2.sch ├── kbdbabel-tandy1k-ps2 ├── 89c2051-tandy1k-ps2.brd └── 89c2051-tandy1k-ps2.sch ├── kbdbabel-amiga2k-ps2 ├── 89c2051-amiga1000-ps2.brd └── 89c2051-amiga1000-ps2.sch ├── kbdbabel-symbolics-ps2 ├── 89c2051-symbolics-ps2.brd └── 89c2051-symbolics-ps2.sch ├── CREDITS ├── BUILD ├── include └── kbdbabel_intervals.inc └── COPYING /kbdbabel-lk-ps2/89c2051-lk-ps2.brd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tmk/kbdbabel/HEAD/kbdbabel-lk-ps2/89c2051-lk-ps2.brd -------------------------------------------------------------------------------- /kbdbabel-lk-ps2/89c2051-lk-ps2.sch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tmk/kbdbabel/HEAD/kbdbabel-lk-ps2/89c2051-lk-ps2.sch -------------------------------------------------------------------------------- /kbdbabel-pc-ps2/89c2051-pc-ps2.brd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tmk/kbdbabel/HEAD/kbdbabel-pc-ps2/89c2051-pc-ps2.brd -------------------------------------------------------------------------------- /kbdbabel-pc-ps2/89c2051-pc-ps2.sch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tmk/kbdbabel/HEAD/kbdbabel-pc-ps2/89c2051-pc-ps2.sch -------------------------------------------------------------------------------- /kbdbabel-st-ps2/89c2051-st-ps2.brd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tmk/kbdbabel/HEAD/kbdbabel-st-ps2/89c2051-st-ps2.brd -------------------------------------------------------------------------------- /kbdbabel-st-ps2/89c2051-st-ps2.sch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tmk/kbdbabel/HEAD/kbdbabel-st-ps2/89c2051-st-ps2.sch -------------------------------------------------------------------------------- /kbdbabel-mac-ps2/89c2051-mac-ps2.brd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tmk/kbdbabel/HEAD/kbdbabel-mac-ps2/89c2051-mac-ps2.brd -------------------------------------------------------------------------------- /kbdbabel-mac-ps2/89c2051-mac-ps2.sch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tmk/kbdbabel/HEAD/kbdbabel-mac-ps2/89c2051-mac-ps2.sch -------------------------------------------------------------------------------- /kbdbabel-ps2-dec/89c2051-ps2-dec.brd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tmk/kbdbabel/HEAD/kbdbabel-ps2-dec/89c2051-ps2-dec.brd -------------------------------------------------------------------------------- /kbdbabel-ps2-dec/89c2051-ps2-dec.sch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tmk/kbdbabel/HEAD/kbdbabel-ps2-dec/89c2051-ps2-dec.sch -------------------------------------------------------------------------------- /kbdbabel-ps2-sun/89c2051-ps2-sun.brd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tmk/kbdbabel/HEAD/kbdbabel-ps2-sun/89c2051-ps2-sun.brd -------------------------------------------------------------------------------- /kbdbabel-ps2-sun/89c2051-ps2-sun.sch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tmk/kbdbabel/HEAD/kbdbabel-ps2-sun/89c2051-ps2-sun.sch -------------------------------------------------------------------------------- /kbdbabel-sun-ps2/89c2051-sun-ps2.brd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tmk/kbdbabel/HEAD/kbdbabel-sun-ps2/89c2051-sun-ps2.brd -------------------------------------------------------------------------------- /kbdbabel-sun-ps2/89c2051-sun-ps2.sch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tmk/kbdbabel/HEAD/kbdbabel-sun-ps2/89c2051-sun-ps2.sch -------------------------------------------------------------------------------- /kbdbabel-xdb-ps2/89c2051-xdb-ps2.brd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tmk/kbdbabel/HEAD/kbdbabel-xdb-ps2/89c2051-xdb-ps2.brd -------------------------------------------------------------------------------- /kbdbabel-xdb-ps2/89c2051-xdb-ps2.sch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tmk/kbdbabel/HEAD/kbdbabel-xdb-ps2/89c2051-xdb-ps2.sch -------------------------------------------------------------------------------- /kbdbabel-a5000-ps2/89c2051-a5000-ps2.brd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tmk/kbdbabel/HEAD/kbdbabel-a5000-ps2/89c2051-a5000-ps2.brd -------------------------------------------------------------------------------- /kbdbabel-a5000-ps2/89c2051-a5000-ps2.sch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tmk/kbdbabel/HEAD/kbdbabel-a5000-ps2/89c2051-a5000-ps2.sch -------------------------------------------------------------------------------- /kbdbabel-ibm3104/89c2051-ibm3104-ps2.brd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tmk/kbdbabel/HEAD/kbdbabel-ibm3104/89c2051-ibm3104-ps2.brd -------------------------------------------------------------------------------- /kbdbabel-ibm3104/89c2051-ibm3104-ps2.sch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tmk/kbdbabel/HEAD/kbdbabel-ibm3104/89c2051-ibm3104-ps2.sch -------------------------------------------------------------------------------- /kbdbabel-ibm3151/89c2051-ibm3151-ps2.brd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tmk/kbdbabel/HEAD/kbdbabel-ibm3151/89c2051-ibm3151-ps2.brd -------------------------------------------------------------------------------- /kbdbabel-ibm3151/89c2051-ibm3151-ps2.sch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tmk/kbdbabel/HEAD/kbdbabel-ibm3151/89c2051-ibm3151-ps2.sch -------------------------------------------------------------------------------- /kbdbabel-kc85-ps2/89c2051-kc85-ps2.brd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tmk/kbdbabel/HEAD/kbdbabel-kc85-ps2/89c2051-kc85-ps2.brd -------------------------------------------------------------------------------- /kbdbabel-kc85-ps2/89c2051-kc85-ps2.sch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tmk/kbdbabel/HEAD/kbdbabel-kc85-ps2/89c2051-kc85-ps2.sch -------------------------------------------------------------------------------- /kbdbabel-lk-ps2/kbdbabel_lk_ps2_8051.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tmk/kbdbabel/HEAD/kbdbabel-lk-ps2/kbdbabel_lk_ps2_8051.bin -------------------------------------------------------------------------------- /kbdbabel-wy85-ps2/89c2051-wy85-ps2.brd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tmk/kbdbabel/HEAD/kbdbabel-wy85-ps2/89c2051-wy85-ps2.brd -------------------------------------------------------------------------------- /kbdbabel-wy85-ps2/89c2051-wy85-ps2.sch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tmk/kbdbabel/HEAD/kbdbabel-wy85-ps2/89c2051-wy85-ps2.sch -------------------------------------------------------------------------------- /kbdbabel-hp9816-ps2/89c2051-hp9816-ps2.brd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tmk/kbdbabel/HEAD/kbdbabel-hp9816-ps2/89c2051-hp9816-ps2.brd -------------------------------------------------------------------------------- /kbdbabel-hp9816-ps2/89c2051-hp9816-ps2.sch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tmk/kbdbabel/HEAD/kbdbabel-hp9816-ps2/89c2051-hp9816-ps2.sch -------------------------------------------------------------------------------- /kbdbabel-sun-ps2/kbdbabel_sun_ps2_8051.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tmk/kbdbabel/HEAD/kbdbabel-sun-ps2/kbdbabel_sun_ps2_8051.bin -------------------------------------------------------------------------------- /kbdbabel-tandy1k-ps2/89c2051-tandy1k-ps2.brd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tmk/kbdbabel/HEAD/kbdbabel-tandy1k-ps2/89c2051-tandy1k-ps2.brd -------------------------------------------------------------------------------- /kbdbabel-tandy1k-ps2/89c2051-tandy1k-ps2.sch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tmk/kbdbabel/HEAD/kbdbabel-tandy1k-ps2/89c2051-tandy1k-ps2.sch -------------------------------------------------------------------------------- /kbdbabel-wy85-ps2/kbdbabel_wy85_ps2_8051.asm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tmk/kbdbabel/HEAD/kbdbabel-wy85-ps2/kbdbabel_wy85_ps2_8051.asm -------------------------------------------------------------------------------- /kbdbabel-amiga2k-ps2/89c2051-amiga1000-ps2.brd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tmk/kbdbabel/HEAD/kbdbabel-amiga2k-ps2/89c2051-amiga1000-ps2.brd -------------------------------------------------------------------------------- /kbdbabel-amiga2k-ps2/89c2051-amiga1000-ps2.sch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tmk/kbdbabel/HEAD/kbdbabel-amiga2k-ps2/89c2051-amiga1000-ps2.sch -------------------------------------------------------------------------------- /kbdbabel-mac-ps2/kbdbabel_mac_ps2_fmode_8051.asm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tmk/kbdbabel/HEAD/kbdbabel-mac-ps2/kbdbabel_mac_ps2_fmode_8051.asm -------------------------------------------------------------------------------- /kbdbabel-symbolics-ps2/89c2051-symbolics-ps2.brd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tmk/kbdbabel/HEAD/kbdbabel-symbolics-ps2/89c2051-symbolics-ps2.brd -------------------------------------------------------------------------------- /kbdbabel-symbolics-ps2/89c2051-symbolics-ps2.sch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tmk/kbdbabel/HEAD/kbdbabel-symbolics-ps2/89c2051-symbolics-ps2.sch -------------------------------------------------------------------------------- /CREDITS: -------------------------------------------------------------------------------- 1 | $Id: CREDITS,v 1.2 2006/11/28 10:18:07 akurz Exp $ 2 | 3 | Thanks to for measurement expertise and prototyping support 4 | -------------------------------------------------------------------------------- /BUILD: -------------------------------------------------------------------------------- 1 | # ----------------- 2 | Compiling 8051-Assembler Sources 3 | 4 | All 8051-type Assembler Sources can be compiled using 5 | the Macroassembler AS written by Alfred Arnold. 6 | This Macroassembler is available as GNU GPL source code. 7 | http://john.ccac.rwth-aachen.de:8000/as/ 8 | 9 | File specific build informations can be found in the 10 | header of each assembler file. 11 | 12 | # ----------------- 13 | PCB and Hardware Layout 14 | 15 | Schematics and PCB files are provided for 16 | CadSoft EAGLE Light which is available as freeware. 17 | http://www.cadsoft.de/freeware.htm 18 | 19 | Schematic and PCB file formats may change in the future 20 | in favor for open source alternative with non-proprietary file formats. 21 | -------------------------------------------------------------------------------- /include/kbdbabel_intervals.inc: -------------------------------------------------------------------------------- 1 | ; --------------------------------------------------------------------- 2 | ; KbdBabel Common constants and definitions 3 | ; for various keyboard interval und timing issues. 4 | ; 5 | ; $Id: kbdbabel_intervals.inc,v 1.6 2009/08/30 15:58:03 akurz Exp $ 6 | ; 7 | ; Copyright 2007 by Alexander Kurz 8 | ; 9 | ; This program is free software; you can redistribute it and/or modify 10 | ; it under the terms of the GNU General Public License as published by 11 | ; the Free Software Foundation; either version 3, or (at your option) 12 | ; any later version. 13 | ; 14 | ; This program is distributed in the hope that it will be useful, 15 | ; but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | ; GNU General Public License for more details. 18 | ;---------------------------------------------------------- 19 | 20 | ;---------------------------------------------------------- 21 | ; misc 8-bit constants 22 | ;---------------------------------------------------------- 23 | ;------------------ AT scancode timing intervals generated with timer 0 in 8 bit mode 24 | ; --- double cycle (21*40mus), usable with >12MHz controller speed 25 | ; 50mus@11.0592MHz -> th0 and tl0=209 or 46 processor cycles ; (256-11059.2*0.05/12) 26 | interval_t0_50u_11059_2k equ 209 27 | 28 | ; 45mus@11.0592MHz -> th0 and tl0=214 or 41 processor cycles ; (256-11059.2*0.045/12) 29 | interval_t0_45u_11059_2k equ 214 30 | 31 | ; 50mus@12.000MHz -> th0 and tl0=206 or 50 processor cycles ; (256-12000*0.05/12) 32 | interval_t0_50u_12M equ 206 33 | 34 | ; 45mus@12.000MHz -> th0 and tl0=211 or 45 processor cycles ; (256-12000*0.045/12) 35 | interval_t0_45u_12M equ 211 36 | 37 | ; 40mus@18.432MHz -> th0 and tl0=194 or 61 processor cycles ; (256-18432*0.04/12) 38 | interval_t0_40u_18432k equ 194 39 | 40 | ; 40mus@22.1184MHz -> th0 and tl0=182 or 80 processor cycles ; (256-22118.4*0.04/12) 41 | interval_t0_40u_22118_4k equ 182 42 | 43 | ; 45mus@24.000MHz -> th0 and tl0=166 or 90 processor cycles ; (256-24000*0.045/12) 44 | interval_t0_45u_24M equ 166 45 | 46 | ; 40mus@24.000MHz -> th0 and tl0=176 or 80 processor cycles ; (256-24000*0.04/12) 47 | interval_t0_40u_24M equ 176 48 | 49 | ; --- single cycle (10*80mus), for <12MHz controller speed 50 | ; 85mus@11.0592MHz -> th0 and tl0=178 or 78 processor cycles ; (256-11059.2*0.085/12) 51 | interval_t0_85u_11059_2k equ 178 52 | 53 | ; 80mus@11.0592MHz -> th0 and tl0=183 or 73 processor cycles ; (256-11059.2*0.08/12) 54 | interval_t0_80u_11059_2k equ 183 55 | 56 | ; 75mus@11.0592MHz -> th0 and tl0=187 or 69 processor cycles ; (256-11059.2*0.075/12) 57 | interval_t0_75u_11059_2k equ 187 58 | 59 | ; 80mus@12.000MHz -> th0 and tl0=176 or 80 processor cycles ; (256-12000*0.08/12) 60 | interval_t0_80u_12M equ 176 61 | 62 | ; do not use: 63 | ; 80mus@18.432MHz -> th0 and tl0=134 or 122 processor cycles ; (256-18432*0.08/12) 64 | ;interval_t0_80u_18432k equ 134 65 | 66 | ; do not use: 67 | ; 80mus@24.000MHz -> th0 and tl0=96 or 160 processor cycles ; (256-24000*0.08/12) 68 | ;interval_t0_80u_24M equ 96 69 | 70 | ;------------------ WY-85 interval generation with timer 1 in 8 bit mode 71 | ; 17mus@24.000MHz -> th0 and tl0=222 or 34 processor cycles ; (256-24000*0.017/12) 72 | interval_t1_17u_24M equ 222 73 | 74 | ; 20mus@24.000MHz -> th0 and tl0=216 or 40 processor cycles ; (256-24000*0.02/12) 75 | interval_t1_20u_24M equ 216 76 | 77 | ; 25mus@24.000MHz -> th0 and tl0=206 or 50 processor cycles ; (256-24000*0.025/12) 78 | interval_t1_25u_24M equ 206 79 | 80 | ; 30mus@24.000MHz -> th0 and tl0=196 or 60 processor cycles ; (256-24000*0.03/12) 81 | interval_t1_30u_24M equ 196 82 | 83 | ;------------------ KC-85 interval generation with timer 1 in 8 bit mode 84 | ; 125mus@11.0592MHz -> th0 and tl0=141 or 115 processor cycles ; (256-11059.2*0.125/12) 85 | interval_t1_125u_11059_2k equ 141 86 | 87 | ; 125mus@12.000MHz -> th0 and tl0=131 or 125 processor cycles ; (256-12000*0.125/12) 88 | interval_t1_125u_12M equ 131 89 | 90 | ; 125mus@18.432MHz -> th0 and tl0=64 or 192 processor cycles ; (256-18432*0.125/12) 91 | interval_t1_125u_18432k equ 64 92 | 93 | ; 125mus@22.1184MHz -> th0 and tl0=26 or 230 processor cycles ; (256-22118.4*0.125/12) 94 | interval_t1_125u_22118_4k equ 26 95 | 96 | ; 125mus@24.000MHz -> th0 and tl0=6 or 250 processor cycles ; (256-24000*0.125/12) 97 | interval_t1_125u_24M equ 6 98 | 99 | ;------------------ Mac scancode timing intervals generated with timer 1 in 8 bit mode 100 | ; 200mus@11.0592MHz -> th0 and tl0=72 or 184 processor cycles ; (256-11059.2*0.2/12) 101 | interval_t1_200u_11059_2k equ 72 102 | 103 | ; 150mus@11.0592MHz -> th0 and tl0=118 or 138 processor cycles ; (256-11059.2*0.15/12) 104 | interval_t1_150u_11059_2k equ 118 105 | 106 | ;------------------ Qume scancode half-timing intervals generated with timer 1 in 8 bit mode 107 | ; 70mus@24.000MHz -> th0 and tl0=116 or 140 processor cycles ; (256-24000*0.07/12) 108 | interval_t0_70u_24M equ 116 109 | 110 | ;------------------ PC/XT transmit scancode timing intervals generated with timer in 8 bit mode 111 | ; 95mus@24.000MHz -> th0 and tl0=66 or 190 processor cycles ; (256-24000*0.095/12) 112 | interval_t0_95u_24M equ 66 113 | 114 | ;---------------------------------------------------------- 115 | ; misc 16-bit constants 116 | ;---------------------------------------------------------- 117 | ;------------------ timeout values using timer 0 in 16 bit mode 118 | ; --- 11.0592MHz 119 | ; 20ms@11.0592MHz -> th0,tl0=0b8h,00h ; (65536-11059.2*20/12) 120 | interval_th_20m_11059_2k equ 184 121 | interval_tl_20m_11059_2k equ 0 122 | 123 | ; 10ms@11.0592MHz -> th0,tl0=0dch,00h ; (65536-11059.2*10/12) 124 | interval_th_10m_11059_2k equ 220 125 | interval_tl_10m_11059_2k equ 0 126 | 127 | ; 1ms@11.0592MHz -> th0,tl0=0fch,66h ; (65536-11059.2*1/12) 128 | interval_th_1m_11059_2k equ 252 129 | interval_tl_1m_11059_2k equ 42 130 | 131 | ; 0.3ms@11.0592MHz -> th0,tl0=0feh,ebh ; (65536-11059.2*0.3/12) 132 | interval_th_300u_11059_2k equ 254 133 | interval_tl_300u_11059_2k equ 235 134 | 135 | ; 0.15ms@11.0592MHz -> th0,tl0=0ffh,76h ; (65536-11059.2*0.15/12) 136 | interval_th_150u_11059_2k equ 255 137 | interval_tl_150u_11059_2k equ 118 138 | 139 | ; 0.13ms@11.0592MHz -> th0,tl0=0ffh,88h ; (65536-11059.2*0.13/12) 140 | interval_th_130u_11059_2k equ 255 141 | interval_tl_130u_11059_2k equ 136 142 | 143 | ; 40mus@11.0592MHz -> th0,tl0=0ffh,dch ; (65536-11059.2*0.04/12) 144 | interval_th_40u_11059_2k equ 255 145 | interval_tl_40u_11059_2k equ 220 146 | 147 | ; --- 12.000MHz 148 | ; 20ms@12.000MHz -> th0,tl0=b1h,0e0h ; (65536-12000*20/12) 149 | interval_th_20m_12M equ 177 150 | interval_tl_20m_12M equ 224 151 | 152 | ; 10ms@12.000MHz -> th0,tl0=0d8h,f0h ; (65536-12000*10/12) 153 | interval_th_10m_12M equ 216 154 | interval_tl_10m_12M equ 240 155 | 156 | ; 1ms@12.000MHz -> th0,tl0=0fch,18h ; (65536-12000*1/12) 157 | interval_th_1m_12M equ 252 158 | interval_tl_1m_12M equ 24 159 | 160 | ; 0.3ms@12.000MHz -> th0,tl0=0feh,d4h ; (65536-12000*.3/12) 161 | interval_th_300u_12M equ 254 162 | interval_tl_300u_12M equ 212 163 | 164 | ; 0.15ms@12.000MHz -> th0,tl0=0ffh,6ah ; (65536-12000*.15/12) 165 | interval_th_15u_12M equ 255 166 | interval_tl_15u_12M equ 106 167 | 168 | ; 0.128ms@12.000MHz -> th0,tl0=0ffh,80h ; (65536-12000*.128/12) 169 | interval_th_128u_12M equ 255 170 | interval_tl_128u_12M equ 128 171 | 172 | ; 40mus@12MHz -> th0,tl0=0ffh,d8h ; (65536-12000*0.04/12) 173 | interval_th_40u_12M equ 255 174 | interval_tl_40u_12M equ 216 175 | 176 | ; --- 18.432MHz 177 | ; 20ms@18.432MHz -> th0,tl0=0c4h,00h ; (65536-18432*20/12) 178 | interval_th_20m_18432k equ 136 179 | interval_tl_20m_18432k equ 0 180 | 181 | ; 10ms@18.432MHz -> th0,tl0=0c4h,00h ; (65536-18432*10/12) 182 | interval_th_10m_18432k equ 196 183 | interval_tl_10m_18432k equ 0 184 | 185 | ; 1ms@18.432MHz -> th0,tl0=0fah,00h ; (65536-18432*1/12) 186 | interval_th_1m_18432k equ 250 187 | interval_tl_1m_18432k equ 0 188 | 189 | ; 0.3ms@18.432MHz -> th0,tl0=0feh,33h ; (65536-18432*0.3/12) 190 | interval_th_300u_18432k equ 254 191 | interval_tl_300u_18432k equ 51 192 | 193 | ; 0.15ms@18.432MHz -> th0,tl0=0ffh,19h ; (65536-18432*0.15/12) 194 | interval_th_150u_18432k equ 255 195 | interval_tl_150u_18432k equ 25 196 | 197 | ; 0.13ms@18.432MHz -> th0,tl0=0ffh,38h ; (65536-18432*0.13/12) 198 | interval_th_130u_18432k equ 255 199 | interval_tl_130u_18432k equ 56 200 | 201 | ; 40mus@18.432MHz -> th0,tl0=0ffh,C3h ; (256-18432*0.04/12) (65536-18432*0.04/12) 202 | interval_th_40u_18432k equ 255 203 | interval_tl_40u_18432k equ 194 204 | 205 | ; --- 22.1184MHz 206 | ; 20ms@22.1184MHz -> th0,tl0=70h,00h ; (65536-22118.4*20/12) 207 | interval_th_20m_22118_4k equ 112 208 | interval_tl_20m_22118_4k equ 0 209 | 210 | ; 10ms@22.1184MHz -> th0,tl0=0B8h,00h ; (65536-22118.4*10/12) 211 | interval_th_10m_22118_4k equ 184 212 | interval_tl_10m_22118_4k equ 0 213 | 214 | ; 1ms@22.1184MHz -> th0,tl0=0f8h,0cdh ; (65536-22118.4*1/12) 215 | interval_th_1m_22118_4k equ 248 216 | interval_tl_1m_22118_4k equ 205 217 | 218 | ; 0.3ms@22.1184MHz -> th0,tl0=0fdh,d7h ; (65536-22118.4*.3/12) 219 | interval_th_300u_22118_4k equ 253 220 | interval_tl_300u_22118_4k equ 215 221 | 222 | ; 0.15ms@22.1184MHz -> th0,tl0=0feh,edh ; (65536-22118.4*.15/12) 223 | interval_th_15u_22118_4k equ 254 224 | interval_tl_15u_22118_4k equ 237 225 | 226 | ; 0.128ms@22.1184MHz -> th0,tl0=0ffh,14h ; (65536-22118.4*.128/12) 227 | interval_th_128u_22118_4k equ 255 228 | interval_tl_128u_22118_4k equ 20 229 | 230 | ; 40mus@22.1184MHz -> th0,tl0=0ffh,b7h ; (65536-22118.4*0.04/12) 231 | interval_th_40u_22118_4k equ 255 232 | interval_tl_40u_22118_4k equ 183 233 | 234 | ; --- 24.000MHz 235 | ; 20ms@24.000MHz -> th0,tl0=63h,0c0h ; (65536-24000*20/12) 236 | interval_th_20m_24M equ 99 237 | interval_tl_20m_24M equ 192 238 | 239 | ; 10ms@24.000MHz -> th0,tl0=0B1h,E0h ; (65536-24000*10/12) 240 | interval_th_10m_24M equ 177 241 | interval_tl_10m_24M equ 224 242 | 243 | ; 1ms@24.000MHz -> th0,tl0=0f8h,30h ; (65536-24000*1/12) 244 | interval_th_1m_24M equ 248 245 | interval_tl_1m_24M equ 48 246 | 247 | ; 0.5ms@24.000MHz -> th0,tl0=0fch,18h ; (65536-24000*0.5/12) 248 | interval_th_500u_24M equ 252 249 | interval_tl_500u_24M equ 12 250 | 251 | ; 0.3ms@24.000MHz -> th0,tl0=0fdh,A8h ; (65536-24000*.3/12) 252 | interval_th_300u_24M equ 253 253 | interval_tl_300u_24M equ 168 254 | 255 | ; 0.15ms@24.000MHz -> th0,tl0=0feh,d4h ; (65536-24000*.15/12) 256 | interval_th_15u_24M equ 254 257 | interval_tl_15u_24M equ 212 258 | 259 | ; 0.128ms@24.000MHz -> th0,tl0=0ffh,00h ; (65536-24000*.128/12) 260 | interval_th_128u_24M equ 255 261 | interval_tl_128u_24M equ 0 262 | 263 | ; 80mus@24MHz -> th0,tl0=0ffh,60h ; (65536-24000*0.08/12) 264 | interval_th_80u_24M equ 255 265 | interval_tl_80u_24M equ 96 266 | 267 | ; 40mus@24MHz -> th0,tl0=0ffh,b0h ; (65536-24000*0.04/12) 268 | interval_th_40u_24M equ 255 269 | interval_tl_40u_24M equ 176 270 | 271 | ;------------------ PCXT RX timeout and interval diagnosis using timer 0 in 16 bit mode 272 | ; --- 11 bit for timing diagnosis 273 | ; 1.02ms @24.000MHz ; 2048*12/24000 274 | ; 1.33ms @18.432MHz ; 2048*12/18432 275 | ; 2.22ms @11.0592MHz ; 2048*12/11059.2 276 | ; 3.33ms @7.3728MHz ; 2048*12/7372.8 277 | interval_th_11_bit equ 0f8h 278 | interval_tl_11_bit equ 0 279 | 280 | ; --- 10 bit for timing diagnosis 281 | ; 1.1ms @11.0592MHz ; 1024*12/11059.2 282 | ; 1.7ms @7.3728MHz ; 1024*12/7372.8 283 | interval_th_10_bit equ 0fch 284 | interval_tl_10_bit equ 0 285 | 286 | ; --- 9 bit for timing diagnosis 287 | ; 0.83ms @7.3728MHz ; 512*12/7372.8 288 | ; 1.7ms @3.6864MHz ; 512*12/3686.4 289 | interval_th_9_bit equ 0feh 290 | interval_tl_9_bit equ 0 291 | 292 | ;---------------------------------------------------------- 293 | ; constants for UART bitrate generation 294 | ;---------------------------------------------------------- 295 | ;------------------ bitrates generated with timer 1 in 8 bit mode 296 | ; --- 600BPS: Sinix keyboard 297 | ; 600BPS @18.432MHz -> tl1 and th1 = #96 with SMOD=1 ; (256-2*18432/384/0.6) 298 | uart_t1_600_18432k equ 96 299 | 300 | ; --- 1.2kBPS: Sun 301 | ; 1200BPS @3.6864MHz -> tl1 and th1 = #240 with SMOD=1 ; (256-2*3686.4/384/1.2) 302 | uart_t1_1200_3686_4k equ 240 303 | 304 | ; 1200BPS @7.3728MHz -> tl1 and th1 = #224 with SMOD=1 ; (256-2*7372.8/384/1.2) 305 | uart_t1_1200_7372_8k equ 224 306 | 307 | ; 1200BPS @11.0592MHz -> tl1 and th1 = #208 with SMOD=1 ; (256-2*11059.2/384/1.2) 308 | uart_t1_1200_11059_2k equ 208 309 | 310 | ; 1200BPS @14.7456MHz -> tl1 and th1 = #192 with SMOD=1 ; (256-2*14745.6/384/1.2) 311 | uart_t1_1200_14745_6k equ 192 312 | 313 | ; 1200BPS @18.432MHz -> tl1 and th1 = #176 with SMOD=1 ; (256-2*18432/384/1.2) 314 | uart_t1_1200_18432k equ 176 315 | 316 | ; --- 4.8kBPS: DEC LK 317 | ; 4800BPS @11.0592MHz -> tl1 and th1 = #244 with SMOD=1 ; (256-2*11059.2/384/4.8) 318 | uart_t1_4800_11059_2k equ 244 319 | 320 | ; 4800BPS @18.432MHz -> tl1 and th1 = #236 with SMOD=1 ; (256-2*18432/384/4.8) 321 | uart_t1_4800_18432k equ 236 322 | 323 | ; --- 7.8125kBPS: Atari ST 324 | ; 7812.5BPS @12MHz -> tl1 and th1 = #248 with SMOD=1 ; (256-2*12000/384/7.8125) 325 | uart_t1_7k8125_12M equ 248 326 | 327 | ; 7812.5BPS @24MHz -> tl1 and th1 = #240 with SMOD=1 ; (256-2*24000/384/7.8125) 328 | uart_t1_7k8125_24M equ 240 329 | 330 | ; --- 31.25kBPS: Acorn A5000 331 | ; 31250BPS @12MHz -> tl1 and th1 = #254 with SMOD=1 ; (256-2*12000/384/31.25) 332 | uart_t1_31k25_12M equ 254 333 | 334 | ; 31250BPS @24MHz -> tl1 and th1 = #252 with SMOD=1 ; (256-2*24000/384/31.25) 335 | uart_t1_31k25_24M equ 252 336 | 337 | ; --- 9k6 with 18.432 338 | ; 9600BPS @18.432MHz -> tl1 and th1 = #246 with SMOD=1 ; (256-2*18432/384/9.6) 339 | uart_t1_9600_18432k equ 246 340 | 341 | ; --- dirty 9k6 with 24MHz 342 | ; precisely this is 9.6152kbps, 0.15% off the correct bitrate 343 | ; 9600BPS @24MHz -> tl1 and th1 = #243 with SMOD=1 ; (256-2*24000/384/9.6) 344 | uart_t1_dirty9600_24M equ 243 345 | 346 | ;------------------ bitrates generated with timer 2 347 | ; 9600 BPS at 18.432MHz -> RCAP2H,RCAP2L=#0FFh,#0c4h ; (256-18432/32/9.6) 348 | uart_t2h_9600_18432k equ 255 349 | uart_t2l_9600_18432k equ 196 350 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | , 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | -------------------------------------------------------------------------------- /kbdbabel-ps2-sun/kbdbabel_pcxt_sun_8051.asm: -------------------------------------------------------------------------------- 1 | ; --------------------------------------------------------------------- 2 | ; PC/XT to Sun keyboard transcoder for 8051 type processors. 3 | ; For shure, nobody will need this. 4 | ; Just the development helper between pc-at and at-sun. 5 | ; 6 | ; $KbdBabel: kbdbabel_pcxt_sun_8051.asm,v 1.1 2007/04/21 18:05:14 akurz Exp $ 7 | ; 8 | ; Clock/Crystal: 18.432MHz. 9 | ; 10 | ; PC/XT Keyboard connect: 11 | ; This two pins need externals 4.7k resistors as pullup. 12 | ; DATA - p3.4 (Pin 14 on DIL40, Pin 8 on AT89C2051 PDIP20) 13 | ; CLOCK - p3.2 (Pin 12 on DIL40, Pin 6 on AT89C2051 PDIP20, Int 0) 14 | ; 15 | ; Sun Host/Computer connect: 16 | ; Inverted signal using transistors and 4.7k resistors 17 | ; is connected to the serial port lines 18 | ; RxD - p3.0 (Pin 10 on DIL40, Pin 2 on AT89C2051 PDIP20) 19 | ; TxD - p3.1 (Pin 11 on DIL40, Pin 3 on AT89C2051 PDIP20) 20 | ; 21 | ; LED-Output connect: 22 | ; LEDs are connected with 220R to Vcc 23 | ; buzzer - p1.7 (Pin 8 on DIL40, Pin 19 on AT89C2051 PDIP20) 24 | ; ? - p1.7 (Pin 8 on DIL40, Pin 19 on AT89C2051 PDIP20) 25 | ; ? - p1.6 (Pin 7 on DIL40, Pin 18 on AT89C2051 PDIP20) 26 | ; ? - p1.5 (Pin 6 on DIL40, Pin 17 on AT89C2051 PDIP20) 27 | ; Ring buffer full - p1.4 28 | ; Compose - p1.3 29 | ; ScrollLock - p1.2 30 | ; CapsLock - p1.1 31 | ; NumLock - p1.0 32 | ; 33 | ; Build: 34 | ; $ asl kbdbabel_pcxt_sun_8051.asm -o kbdbabel_pcxt_sun_8051.p 35 | ; $ p2bin -l \$ff kbdbabel_pcxt_sun_8051 36 | ; write kbdbabel_pcxt_sun_8051.bin on an empty 27C256 or AT89C2051 37 | ; 38 | ; Copyright 2007 by Alexander Kurz 39 | ; 40 | ; This is free software. 41 | ; You may copy and redistibute this software according to the 42 | ; GNU general public license version 2 or any later verson. 43 | ; 44 | ; --------------------------------------------------------------------- 45 | 46 | cpu 8052 47 | include stddef51.inc 48 | 49 | ;---------------------------------------------------------- 50 | ; Variables / Memory layout 51 | ;---------------------------------------------------------- 52 | ;------------------ bits 53 | PCRXBitF bit 20h.0 ; RX-bit-buffer 54 | PCRXCompleteF bit 20h.1 ; full and correct byte-received 55 | PCRXActiveF bit 20h.2 ; receive in progress flag 56 | ATTXBreakF bit 20h.3 ; Release/Break-Code flag 57 | ATTXMasqF bit 20h.4 ; TX-AT-Masq-Char-Bit (send two byte scancode) 58 | ATTXParF bit 20h.5 ; TX-AT-Parity bit 59 | ATTFModF bit 20h.6 ; Timer modifier: alarm clock or clock driver 60 | MiscSleepF bit 20h.7 ; sleep timer active flag 61 | ATCommAbort bit 21h.0 ; AT communication aborted 62 | ATHostToDevIntF bit 21h.1 ; host-do-device init flag triggered by ex1 / unused. 63 | ATHostToDevF bit 21h.2 ; host-to-device flag for timer 64 | ATTXActiveF bit 21h.3 ; AT TX active 65 | ATCmdReceivedF bit 21h.4 ; full and correct AT byte-received 66 | ATCmdResetF bit 21h.5 ; reset 67 | SunCmdLedF bit 21h.6 ; Sun command processing: set LED 68 | ATCmdScancodeF bit 21h.7 ; AT command processing: set scancode 69 | ATKbdDisableF bit 22h.0 ; Keyboard disable 70 | ;------------------ octets 71 | KbBitBufL equ 24h 72 | KbBitBufH equ 25h 73 | KbClockMin equ 26h 74 | KbClockMax equ 27h 75 | ATBitCount equ 28h ; AT scancode TX counter 76 | RawBuf equ 30h ; raw PC/XT scancode 77 | OutputBuf equ 31h ; AT scancode 78 | TXBuf equ 32h ; AT scancode TX buffer 79 | RingBufPtrIn equ 33h ; Ring Buffer write pointer, starting with zero 80 | RingBufPtrOut equ 34h ; Ring Buffer read pointer, starting with zero 81 | SunRXBuf equ 35h ; Sun host-to-dev buffer 82 | ATRXCount equ 36h 83 | ;KbClockIntBuf equ 33h 84 | 85 | ;------------------ arrays 86 | RingBuf equ 40h 87 | RingBufSizeMask equ 0fh ; 16 byte ring-buffer size 88 | 89 | ;------------------ stack 90 | StackBottom equ 50h ; the stack 91 | 92 | ;---------------------------------------------------------- 93 | ; misc constants 94 | ;---------------------------------------------------------- 95 | ;------------------ bitrates generated with timer 1 in 8 bit mode 96 | ; 1200BPS @3.6864MHz -> tl1 and th1 = #240 with SMOD=1 ; (256-2*3686.4/384/1.2) 97 | uart_t1_1200_3686_4k equ 240 98 | 99 | ; 1200BPS @7.3728MHz -> tl1 and th1 = #224 with SMOD=1 ; (256-2*7372.8/384/1.2) 100 | uart_t1_1200_7372_8k equ 224 101 | 102 | ; 1200BPS @11.0592MHz -> tl1 and th1 = #208 with SMOD=1 ; (256-2*11059.2/384/1.2) 103 | uart_t1_1200_11059_2k equ 208 104 | 105 | ; 1200BPS @14.7456MHz -> tl1 and th1 = #192 with SMOD=1 ; (256-2*14745.6/384/1.2) 106 | uart_t1_1200_14745_6k equ 192 107 | 108 | ; 1200BPS @18.432MHz -> tl1 and th1 = #176 with SMOD=1 ; (256-2*18432/384/1.2) 109 | uart_t1_1200_18432k equ 176 110 | 111 | ; 4800BPS @11.0592MHz -> tl1 and th1 = #244 with SMOD=1 ; (256-2*11059.2/384/4.8) 112 | uart_t1_4800_11059_2k equ 244 113 | 114 | ; 4800BPS @18.432MHz -> tl1 and th1 = #236 with SMOD=1 ; (256-2*18432/384/4.8) 115 | uart_t1_4800_18432k equ 236 116 | 117 | ; 9600BPS @18.432MHz -> tl1 and th1 = #246 with SMOD=1 ; (256-2*18432/384/9.6) 118 | uart_t1_9600_18432k equ 246 119 | 120 | ;------------------ bitrates generated with timer 2 121 | ; 9600 BPS at 18.432MHz -> RCAP2H,RCAP2L=#0FFh,#0c4h ; (256-18432/32/9.6) 122 | uart_t2h_9600_18432k equ 255 123 | uart_t2l_9600_18432k equ 196 124 | 125 | ;------------------ AT scancode timing intervals generated with timer 0 in 8 bit mode 126 | ; 50mus@11.0592MHz -> th0 and tl0=209 or 46 processor cycles ; (256-11059.2*0.05/12) 127 | interval_t0_50u_11059_2k equ 209 128 | 129 | ; 50mus@11.0592MHz -> th0 and tl0=214 or 41 processor cycles ; (256-11059.2*0.045/12) 130 | interval_t0_45u_11059_2k equ 214 131 | 132 | ; 45mus@12.000MHz -> th0 and tl0=211 or 45 processor cycles ; (256-12000*0.045/12) 133 | interval_t0_45u_12M equ 211 134 | 135 | ; 40mus@18.432MHz -> th0 and tl0=194 or 61 processor cycles ; (256-18432*0.04/12) 136 | interval_t0_40u_18432k equ 194 137 | 138 | ; 40mus@24.000MHz -> th0 and tl0=176 or 80 processor cycles ; (256-24000*0.04/12) 139 | interval_t0_40u_24M equ 176 140 | 141 | ;------------------ AT RX timeout values using timer 0 in 16 bit mode 142 | ; --- 18.432MHz 143 | ; 20ms@18.432MHz -> th0,tl0=0c4h,00h ; (65536-18432*20/12) 144 | interval_th_20m_18432k equ 136 145 | interval_tl_20m_18432k equ 0 146 | 147 | ; 10ms@18.432MHz -> th0,tl0=0c4h,00h ; (65536-18432*10/12) 148 | interval_th_10m_18432k equ 196 149 | interval_tl_10m_18432k equ 0 150 | 151 | ; 1ms@18.432MHz -> th0,tl0=0fah,00h ; (65536-18432*1/12) 152 | interval_th_1m_18432k equ 250 153 | interval_tl_1m_18432k equ 0 154 | 155 | ; 0.13ms@18.432MHz -> th0,tl0=0ffh,38h ; (65536-18432*0.13/12) 156 | interval_th_130u_18432k equ 255 157 | interval_tl_130u_18432k equ 56 158 | 159 | ; --- 11.0592MHz 160 | ; 20ms@11.0592MHz -> th0,tl0=0b8h,00h ; (65536-11059.2*20/12) 161 | interval_th_20m_11059_2k equ 184 162 | interval_tl_20m_11059_2k equ 0 163 | 164 | ; 10ms@11.0592MHz -> th0,tl0=0dch,00h ; (65536-11059.2*10/12) 165 | interval_th_10m_11059_2k equ 220 166 | interval_tl_10m_11059_2k equ 0 167 | 168 | ; 1ms@11.0592MHz -> th0,tl0=0fch,66h ; (65536-11059.2*1/12) 169 | interval_th_1m_11059_2k equ 252 170 | interval_tl_1m_11059_2k equ 42 171 | 172 | ; 0.13ms@11.0592MHz -> th0,tl0=0ffh,88h ; (65536-11059.2*0.13/12) 173 | interval_th_130u_11059_2k equ 255 174 | interval_tl_130u_11059_2k equ 136 175 | 176 | ; --- 24.000MHz 177 | ; 20ms@24.000MHz -> th0,tl0=63h,0c0h ; (65536-24000*20/12) 178 | interval_th_20m_24M equ 99 179 | interval_tl_20m_24M equ 192 180 | 181 | ; 10ms@24.000MHz -> th0,tl0=0B1h,E0h ; (65536-24000*10/12) 182 | interval_th_10m_24M equ 177 183 | interval_tl_10m_24M equ 224 184 | 185 | ; 1ms@24.000MHz -> th0,tl0=0f8h,30h ; (65536-24000*1/12) 186 | interval_th_1m_24M equ 248 187 | interval_tl_1m_24M equ 48 188 | 189 | ; 0.128ms@24.000MHz -> th0,tl0=0ffh,00h ; (65536-24000*.128/12) 190 | interval_th_128u_24M equ 255 191 | interval_tl_128u_24M equ 0 192 | 193 | ;------------------ PCXT RX timeout and interval diagnosis using timer 0 in 16 bit mode 194 | ; --- 11 bit for timing diagnosis 195 | ; 1.02ms @24.000MHz ; 2048*12/24000 196 | ; 1.33ms @18.432MHz ; 2048*12/18432 197 | ; 2.22ms @11.0592MHz ; 2048*12/11059.2 198 | ; 3.33ms @7.3728MHz ; 2048*12/7372.8 199 | interval_th_11_bit equ 0f8h 200 | interval_tl_11_bit equ 0 201 | 202 | ; --- 10 bit for timing diagnosis 203 | ; 1.1ms @11.0592MHz ; 1024*12/11059.2 204 | ; 1.7ms @7.3728MHz ; 1024*12/7372.8 205 | interval_th_10_bit equ 0fch 206 | interval_tl_10_bit equ 0 207 | 208 | ; --- 9 bit for timing diagnosis 209 | ; 0.83ms @7.3728MHz ; 512*12/7372.8 210 | ; 1.7ms @3.6864MHz ; 512*12/3686.4 211 | interval_th_9_bit equ 0feh 212 | interval_tl_9_bit equ 0 213 | 214 | ;---------------------------------------------------------- 215 | ; start 216 | ;---------------------------------------------------------- 217 | org 0 ; cold start 218 | ljmp Start 219 | ;---------------------------------------------------------- 220 | ; interrupt handlers 221 | ;---------------------------------------------------------- 222 | ;---------------------------- 223 | ; int 0, connected to keyboard clock line. 224 | ; With a raising signal on the clock line there are 15mus 225 | ; left to read the data line. Using a 3.6864 MHz Crystal 226 | ; this will be less than 5 processor cycles. 227 | ;---------------------------- 228 | org 03h ; external interrupt 0 229 | jnb P3.4, HandleInt0 ; this is time critical 230 | setb PCRXBitF 231 | ljmp HandleInt0 232 | ;---------------------------- 233 | org 0bh ; handle TF0 234 | ljmp HandleTF0 235 | ;---------------------------- 236 | ; org 13h ; Int 1 237 | ; ljmp HandleInt1 238 | ;---------------------------- 239 | ; org 1bh ; handle TF1 240 | ; ljmp HandleTF1 241 | ;---------------------------- 242 | ; org 23h ; RI/TI 243 | ; ljmp HandleRITI 244 | ;---------------------------- 245 | ; org 2bh ; handle TF2 246 | ; ljmp HandleTF2 247 | 248 | org 033h 249 | ;---------------------------------------------------------- 250 | ; int0 handler: 251 | ; read one data bit triggered by the keyboard clock line 252 | ; rotate bit into KbBitBufH, KbBitBufL. 253 | ; Last clock sample interval is stored in r6 254 | ; rotate bit into 22h, 23h. 255 | ; Num Bits is in r7 256 | ; buffer: r5 257 | ;---------------------------------------------------------- 258 | HandleInt0: 259 | push acc 260 | push psw 261 | 262 | ; receive in progress flag 263 | setb PCRXActiveF 264 | ; --------------------------- diag: check if PCXT-RX happens during AT-TX 265 | clr p1.6 266 | ; check if flag is set 267 | jnb ATTXActiveF,interCharFlagOk 268 | ; clr p1.4 269 | sjmp interCharTestEnd 270 | interCharFlagOk: 271 | ; setb p1.4 272 | interCharTestEnd: 273 | ; --------------------------- get and save data samples 274 | ; -- write to mem, first 8 bits 275 | mov c,PCRXBitF ; new bit 276 | mov a,KbBitBufL 277 | rrc a 278 | mov KbBitBufL,a 279 | 280 | ; -- write to mem, upper bits 281 | mov a,KbBitBufH 282 | rrc a 283 | mov KbBitBufH,a 284 | 285 | ; -- diag: write data bits to LED-Port 286 | ; mov a,KbBitBufL 287 | ; xrl a,0FFh 288 | ; mov p1,a 289 | 290 | ; -- reset bit buffer 291 | clr PCRXBitF 292 | 293 | ; --------------------------- get and save clock timings 294 | ; this is an optional extra-check for the received data. 295 | ; The PC/XT-Protocol consists of 9 euqally spaced clock cycles proceeded by 296 | ; one clock cycle of double length. These intervals are checked here. 297 | ; For diagnosis purposes the timing samples can be send via serial line. 298 | ; -- diag: time interval buffer address KbClockIntBuf 299 | ; mov a,r7 300 | ; add a,#KbClockIntBuf 301 | ; mov r1,a 302 | 303 | ; -- save and restart timer 304 | ; stop timer 0 305 | clr tr0 306 | 307 | ; 11 bit from 16-bit timer. 308 | mov a,th0 309 | anl a,#07h ; 3 high bits from th0 310 | rr a 311 | rr a 312 | rr a 313 | mov r5, a 314 | 315 | mov a,tl0 316 | anl a,#0F8h ; 5 low bits 317 | rr a 318 | rr a 319 | rr a 320 | orl a, r5 321 | mov r6,a 322 | 323 | ; ; diag: save clock samples 324 | ; mov @r1,a 325 | 326 | ; reset timer value 327 | mov th0, #interval_th_11_bit 328 | mov tl0, #interval_tl_11_bit 329 | 330 | ; start timer 0 331 | setb tr0 332 | 333 | ; --------------------------- consistancy checks 334 | ; -- checks by bit number 335 | mov a,r7 336 | jz Int0Return ; bit zero 337 | dec a 338 | jz Int0StartBit ; start bit 339 | clr c 340 | subb a,#08h 341 | mov r5,a ; save clock bit count result 342 | 343 | ; -- data check clock timings 344 | clr c 345 | mov a, r6 346 | subb a, KbClockMin 347 | jc Int0Error 348 | 349 | mov a, r6 350 | clr c 351 | subb a, KbClockMax 352 | jnc Int0Error 353 | 354 | mov a,r5 355 | jnz Int0Return 356 | 357 | ; -- special handling for last bit: output 358 | ; start-bit must be 1 359 | jnb KbBitBufH.7, Int0Error 360 | setb p1.5 ; error LED off 361 | mov a, KbBitBufL 362 | mov RawBuf, a 363 | mov r7,#0 364 | setb PCRXCompleteF ; fully received flag 365 | clr PCRXActiveF ; receive in progress flag 366 | sjmp Int0Return 367 | 368 | Int0StartBit: 369 | ; -- start bit: calculate timings 370 | clr PCRXCompleteF 371 | mov a,r6 372 | clr c 373 | rrc a 374 | clr c 375 | rrc a 376 | mov KbClockMin,a 377 | add a,acc 378 | add a,acc 379 | mov KbClockMax,a 380 | anl KbBitBufL,#0f0h 381 | mov KbBitBufH,#0 382 | sjmp Int0Return 383 | 384 | Int0Error: 385 | ; -- cleanup buffers 386 | mov KbBitBufL,#0 387 | mov KbBitBufH,#0 388 | mov r7,#0 389 | clr p1.5 ; error LED on 390 | 391 | ; --------------------------- done 392 | Int0Return: 393 | ; -- inc the bit counter 394 | inc r7 395 | setb p1.6 396 | pop psw 397 | pop acc 398 | reti 399 | 400 | ;---------------------------------------------------------- 401 | ; timer 0 int handler: 402 | ; timer is used to measure the clock-signal-interval length 403 | ; Stop the timer after overflow, cleanup RX buffers 404 | ; RX timeout after 1 - 1.3ms 405 | ;---------------------------------------------------------- 406 | HandleTF0: 407 | ; stop timer 408 | clr tr0 409 | 410 | ; cleanup buffers 411 | mov KbBitBufL,#0 412 | mov KbBitBufH,#0 413 | mov r7,#0 414 | 415 | ; reset timer value 416 | mov th0, #interval_th_11_bit 417 | mov tl0, #interval_tl_11_bit 418 | 419 | reti 420 | 421 | ;---------------------------------------------------------- 422 | ; PC/XT to Sun translaton table 423 | ;---------------------------------------------------------- 424 | PCXT2Sunxlt0 DB 000h, 01dh, 01eh, 01fh, 020h, 021h, 022h, 023h, 024h, 025h, 026h, 027h, 028h, 029h, 02bh, 035h 425 | PCXT2Sunxlt1 DB 036h, 037h, 038h, 039h, 03ah, 03bh, 03ch, 03dh, 03eh, 03fh, 040h, 041h, 059h, 04ch, 04dh, 04eh 426 | PCXT2Sunxlt2 DB 04fh, 050h, 051h, 052h, 053h, 054h, 055h, 056h, 057h, 02ah, 063h, 058h, 064h, 065h, 066h, 067h 427 | PCXT2Sunxlt3 DB 068h, 069h, 06ah, 06bh, 06ch, 06dh, 06eh, 02fh, 013h, 079h, 077h, 005h, 006h, 008h, 00ah, 00ch 428 | PCXT2Sunxlt4 DB 00eh, 010h, 011h, 012h, 007h, 062h, 017h, 044h, 045h, 046h, 047h, 05bh, 05ch, 05dh, 07dh, 070h 429 | PCXT2Sunxlt5 DB 071h, 072h, 05eh, 032h, 000h, 000h, 000h, 009h, 00bh, 000h, 000h, 000h, 000h, 000h, 000h, 000h 430 | PCXT2Sunxlt6 DB 000h, 000h, 000h, 000h, 000h, 009h, 00bh, 000h, 000h, 000h, 000h, 02ch, 042h, 014h, 01bh, 018h 431 | PCXT2Sunxlt7 DB 01ch, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h 432 | 433 | ;---------------------------------------------------------- 434 | ; ring buffer insertion helper. Input Data comes in r2 435 | ;---------------------------------------------------------- 436 | RingBufCheckInsert: 437 | ; check for ring buffer overflow 438 | mov a,RingBufPtrOut 439 | setb c 440 | subb a,RingBufPtrIn 441 | anl a,#RingBufSizeMask 442 | jz RingBufFull 443 | 444 | ; some space left, insert data 445 | mov a,RingBufPtrIn 446 | add a,#RingBuf 447 | mov r0,a 448 | mov a,r2 449 | mov @r0,a 450 | 451 | ; increment pointer 452 | inc RingBufPtrIn 453 | anl RingBufPtrIn,#RingBufSizeMask 454 | ret 455 | 456 | RingBufFull: 457 | ; error routine 458 | clr p1.4 459 | ret 460 | 461 | ;---------------------------------------------------------- 462 | ; Get received data and translate it into the ring buffer 463 | ;---------------------------------------------------------- 464 | TranslateToBufPCXT: 465 | ; translate from PC/XT to AT scancode 466 | mov a,RawBuf 467 | 468 | ; save make/break bit 7 469 | mov c,acc.7 470 | mov ATTXBreakF,c 471 | 472 | ; ignore make/break bit 7 473 | anl a,#7fh 474 | 475 | ; ; check for 2-byte scancodes 476 | ; mov r4,a 477 | ; mov dptr,#PCXT2ATxlte0 478 | ; movc a,@a+dptr 479 | ; mov c,acc.0 480 | ; mov ATTXMasqF,c 481 | ; mov a,r4 482 | 483 | ; get Sun scancode 484 | mov dptr,#PCXT2Sunxlt0 485 | movc a,@a+dptr 486 | mov OutputBuf,a 487 | 488 | ; clear received data flag 489 | clr PCRXCompleteF 490 | 491 | ; keyboard disabled? 492 | jb ATKbdDisableF,TranslateToBufEnd 493 | 494 | ; ; check for 0xE0 escape code 495 | ; jnb ATTXMasqF,TranslateToBufNoEsc 496 | ; mov r2,#0E0h 497 | ; call RingBufCheckInsert 498 | 499 | ;TranslateToBufNoEsc: 500 | ; ; check for 0xF0 release / break code 501 | ; jnb ATTXBreakF,TranslateToBufNoRelease 502 | ; mov r2,#0F0h 503 | ; call RingBufCheckInsert 504 | 505 | TranslateToBufNoRelease: 506 | mov a,OutputBuf 507 | 508 | ; restore make/break bit 7 509 | mov c,ATTXBreakF 510 | mov acc.7,c 511 | clr c 512 | 513 | ; insert into buf 514 | mov r2, a 515 | call RingBufCheckInsert 516 | 517 | ; FIXME: will send "all keys released after break code" 518 | 519 | ; insert into buf 520 | mov r2, #7fh 521 | call RingBufCheckInsert 522 | 523 | TranslateToBufEnd: 524 | ret 525 | 526 | ;---------------------------------------------------------- 527 | ; Send data from the ring buffer 528 | ;---------------------------------------------------------- 529 | ; -- send ring buffer contents 530 | BufTX: 531 | ; check if data is present in the ring buffer 532 | clr c 533 | mov a,RingBufPtrIn 534 | subb a,RingBufPtrOut 535 | anl a,#RingBufSizeMask 536 | jz BufTXEnd 537 | 538 | ; clr p1.1 539 | ; -- get data from buffer 540 | mov a,RingBufPtrOut 541 | add a,#RingBuf 542 | mov r0,a 543 | mov a,@r0 544 | 545 | ; -- send data 546 | mov sbuf,a ; 8 data bits 547 | clr TI 548 | 549 | ; -- increment output pointer 550 | inc RingBufPtrOut 551 | anl RingBufPtrOut,#RingBufSizeMask 552 | 553 | BufTXEnd: 554 | ; setb p1.1 555 | ret 556 | 557 | ;---------------------------------------------------------- 558 | ; check and respond to received Sun commands 559 | ;---------------------------------------------------------- 560 | SunCmdProc: 561 | ; -- get received Sun LK command 562 | mov a,SunRXBuf 563 | 564 | ; -- argument for 0xe command: set keyboard LED 565 | jnb SunCmdLedF,SunCPNotEDarg 566 | clr SunCmdLedF 567 | ; NumLock 568 | mov c,acc.0 569 | cpl c 570 | mov p1.0,c 571 | ; CapsLock 572 | mov c,acc.3 573 | cpl c 574 | mov p1.1,c 575 | ; ScrollLock 576 | mov c,acc.2 577 | cpl c 578 | mov p1.2,c 579 | ; Compose 580 | mov c,acc.1 581 | cpl c 582 | mov p1.3,c 583 | sjmp SunCPDone 584 | 585 | SunCPNotEDarg: 586 | ; -- command 0xfd: keyboard reset. send POST code \x01\x00\x00\x00 587 | cjne a,#01h,SunCPNot01 588 | mov r2,#0ffh 589 | call RingBufCheckInsert 590 | mov r2,#04h 591 | call RingBufCheckInsert 592 | mov r2,#7fh 593 | call RingBufCheckInsert 594 | mov r2,#0feh 595 | call RingBufCheckInsert 596 | mov r2,#25h 597 | call RingBufCheckInsert 598 | sjmp SunCPDone 599 | SunCPNot01: 600 | ; -- command 0x0e ; LEDs 601 | cjne a,#0eh,SunCPNot0e 602 | setb SunCmdLedF 603 | sjmp SunCPDone 604 | SunCPNot0e: 605 | cjne a,#0fh,SunCPNot0f 606 | sjmp SunCPSendAck 607 | SunCPNot0f: 608 | sjmp SunCPDone 609 | 610 | SunCPSendAck: 611 | mov r2,#0h 612 | call RingBufCheckInsert 613 | ; sjmp SunCPDone 614 | 615 | SunCPDone: 616 | ret 617 | 618 | ;---------------------------------------------------------- 619 | ; init uart with timer 1 as baudrate generator for 1200 BPS 620 | ;---------------------------------------------------------- 621 | uart_timer1_init: 622 | mov scon, #050h ; uart mode 1 (8 bit), single processor 623 | orl tmod, #020h ; M0,M1, bit4,5 in TMOD, timer 1 in mode 2, 8bit-auto-reload 624 | orl pcon, #080h ; SMOD, bit 7 in PCON 625 | 626 | mov th1, #uart_t1_1200_18432k 627 | mov tl1, #uart_t1_1200_18432k 628 | 629 | clr es ; disable serial interrupt 630 | setb tr1 631 | 632 | clr ri 633 | setb ti 634 | 635 | ret 636 | 637 | ;---------------------------------------------------------- 638 | ; init timer 0 for PC/XT interval timing, timeout=1ms 639 | ;---------------------------------------------------------- 640 | timer0_init: 641 | anl tmod, #0f0h ; clear all lower bits 642 | orl tmod, #01h ; M0,M1, bit0,1 in TMOD, timer 0 in mode 1, 16bit 643 | 644 | mov th0, #interval_th_11_bit 645 | mov tl0, #interval_tl_11_bit 646 | 647 | setb et0 ; (IE.3) enable timer 0 interrupt 648 | setb tr0 ; timer 0 run 649 | ret 650 | 651 | ;---------------------------------------------------------- 652 | ; Id 653 | ;---------------------------------------------------------- 654 | RCSId DB "$Id: kbdbabel_pcxt_sun_8051.asm,v 1.1 2007/04/21 18:09:03 akurz Exp $" 655 | 656 | ;---------------------------------------------------------- 657 | ; main 658 | ;---------------------------------------------------------- 659 | Start: 660 | ; -- init the stack 661 | mov sp,#StackBottom 662 | 663 | ; -- init UART and timer0/1 664 | acall uart_timer1_init 665 | acall timer0_init 666 | 667 | ; -- enable interrupts int0 668 | setb ex0 ; external interupt 0 enable 669 | setb it0 ; falling edge trigger for int 0 670 | setb ea 671 | 672 | ; -- clear all flags 673 | mov 20h,#0 674 | mov 21h,#0 675 | mov 22h,#0 676 | 677 | ; -- init the ring buffer 678 | mov RingBufPtrIn,#0 679 | mov RingBufPtrOut,#0 680 | 681 | ; -- mute the anoying buzzer quiet 682 | clr p1.7 683 | 684 | ; ; -- cold start flag 685 | ; setb ATCmdResetF 686 | 687 | ; ---------------- 688 | Loop: 689 | ; -- check PC/XT receive status 690 | jb PCRXCompleteF,LoopProcessPCXTData 691 | 692 | ; -- check on new Keyboard data received on serial line 693 | jb RI, LoopProcessLKcmd 694 | 695 | ; -- loop if serial TX is active 696 | jnb TI, Loop 697 | 698 | ; send data 699 | call BufTX 700 | 701 | ; -- loop 702 | sjmp Loop 703 | 704 | ;---------------------------------------------------------- 705 | ; helpers for the main loop 706 | ;---------------------------------------------------------- 707 | ; ---------------- 708 | LoopProcessPCXTData: 709 | ; -- PC/XT data received, process the received scancode into output ring buffer 710 | call TranslateToBufPCXT 711 | sjmp Loop 712 | 713 | ; ---------------- 714 | LoopProcessLKcmd: 715 | ; -- commands from DEC host received via serial line 716 | ; clr p1.6 717 | mov a,sbuf 718 | mov SunRXBuf,a 719 | clr RI 720 | acall SunCmdProc 721 | ; setb p1.6 722 | sjmp Loop 723 | 724 | ;---------------------------------------------------------- 725 | ; Still space on the ROM left for the license? 726 | ;---------------------------------------------------------- 727 | LIC01 DB " Copyright 2007 by Alexander Kurz" 728 | LIC02 DB " " 729 | GPL01 DB " This program is free software; you can redistribute it and/or modify" 730 | GPL02 DB " it under the terms of the GNU General Public License as published by" 731 | GPL03 DB " the Free Software Foundation; either version 2, or (at your option)" 732 | GPL04 DB " any later version." 733 | GPL05 DB " " 734 | GPL06 DB " This program is distributed in the hope that it will be useful," 735 | GPL07 DB " but WITHOUT ANY WARRANTY; without even the implied warranty of" 736 | GPL08 DB " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the" 737 | GPL09 DB " GNU General Public License for more details." 738 | GPL10 DB " " 739 | ; ---------------- 740 | end 741 | -------------------------------------------------------------------------------- /kbdbabel-st-ps2/kbdbabel_st_ps2_8051.asm: -------------------------------------------------------------------------------- 1 | ; --------------------------------------------------------------------- 2 | ; Atari ST to AT/PS2 keyboard transcoder for 8051 type processors. 3 | ; 4 | ; $KbdBabel: kbdbabel_st_ps2_8051.asm,v 1.2 2007/07/25 09:51:44 akurz Exp $ 5 | ; 6 | ; Clock/Crystal: 12MHz. 7 | ; 8 | ; Atari Keyboard connect: 9 | ; RxD - p3.0 (Pin 10 on DIL40, Pin 2 on AT89C2051 PDIP20) 10 | ; TxD - p3.1 (Pin 11 on DIL40, Pin 3 on AT89C2051 PDIP20) 11 | ; 12 | ; AT Host connect: 13 | ; DATA - p3.5 (Pin 15 on DIL40, Pin 9 on AT89C2051 PDIP20) 14 | ; CLOCK - p3.3 (Pin 13 on DIL40, Pin 7 on AT89C2051 PDIP20, Int 1) 15 | ; 16 | ; LED-Output connect: 17 | ; LEDs are connected with 220R to Vcc 18 | ; ScrollLock - p1.7 (Pin 8 on DIL40, Pin 19 on AT89C2051 PDIP20) 19 | ; CapsLock - p1.6 (Pin 7 on DIL40, Pin 18 on AT89C2051 PDIP20) 20 | ; NumLock - p1.5 (Pin 6 on DIL40, Pin 17 on AT89C2051 PDIP20) 21 | ; ? - p1.4 22 | ; ? - p1.3 23 | ; AT TX Communication abort - p1.2 24 | ; AT RX Communication abort - p1.1 25 | ; TX buffer full - p1.0 26 | ; 27 | ; Build using the macroassembler by Alfred Arnold 28 | ; $ asl -L kbdbabel_st_ps2_8051.asm -o kbdbabel_st_ps2_8051.p 29 | ; $ p2bin -l \$ff -r 0-\$7ff kbdbabel_st_ps2_8051 30 | ; write kbdbabel_st_ps2_8051.bin on an empty 27C256 or AT89C2051 31 | ; 32 | ; Copyright 2007 by Alexander Kurz 33 | ; 34 | ; This is free software. 35 | ; You may copy and redistibute this software according to the 36 | ; GNU general public license version 3 or any later verson. 37 | ; 38 | ; --------------------------------------------------------------------- 39 | 40 | cpu 8052 41 | include stddef51.inc 42 | include kbdbabel_intervals.inc 43 | 44 | ;---------------------------------------------------------- 45 | ; Variables / Memory layout 46 | ;---------------------------------------------------------- 47 | ;------------------ octets 48 | B20 sfrb 20h ; bit adressable space 49 | B21 sfrb 21h 50 | B22 sfrb 22h 51 | B23 sfrb 23h 52 | KbBitBufL equ 24h 53 | KbBitBufH equ 25h 54 | KbClockMin equ 26h 55 | KbClockMax equ 27h 56 | ATBitCount sfrb 28h ; AT scancode TX counter 57 | RawBuf equ 30h ; raw input scancode 58 | OutputBuf equ 31h ; AT scancode 59 | TXBuf equ 32h ; AT scancode TX buffer 60 | RingBufPtrIn equ 33h ; Ring Buffer write pointer, starting with zero 61 | RingBufPtrOut equ 34h ; Ring Buffer read pointer, starting with zero 62 | ATRXBuf equ 35h ; AT host-to-dev buffer 63 | ATRXCount equ 36h 64 | ATRXResendBuf equ 37h ; for AT resend feature 65 | ;KbClockIntBuf equ 33h 66 | 67 | ;------------------ bits 68 | MiscRXCompleteF bit B20.1 ; full and correct byte-received 69 | ATTXBreakF bit B20.3 ; Release/Break-Code flag 70 | ATTXMasqF bit B20.4 ; TX-AT-Masq-Char-Bit (send two byte scancode) 71 | ATTXParF bit B20.5 ; TX-AT-Parity bit 72 | TFModF bit B20.6 ; Timer modifier: alarm clock or clock driver 73 | MiscSleepT0F bit B20.7 ; sleep timer active flag 74 | ATCommAbort bit B21.0 ; AT communication aborted 75 | ATHostToDevIntF bit B21.1 ; host-do-device init flag triggered by ex1 / unused. 76 | ATHostToDevF bit B21.2 ; host-to-device flag for timer 77 | ATTXActiveF bit B21.3 ; AT TX active 78 | ATCmdReceivedF bit B21.4 ; full and correct AT byte-received 79 | ATCmdResetF bit B21.5 ; reset 80 | ATCmdLedF bit B21.6 ; AT command processing: set LED 81 | ATCmdScancodeF bit B21.7 ; AT command processing: set scancode 82 | ATKbdDisableF bit B22.0 ; Keyboard disable 83 | 84 | ;------------------ arrays 85 | RingBuf equ 40h 86 | RingBufSizeMask equ 0fh ; 16 byte ring-buffer size 87 | 88 | ;------------------ stack 89 | StackBottom equ 50h ; the stack 90 | 91 | ;---------------------------------------------------------- 92 | ; start 93 | ;---------------------------------------------------------- 94 | org 0 ; cold start 95 | ljmp Start 96 | ;---------------------------------------------------------- 97 | ; interrupt handlers 98 | ;---------------------------------------------------------- 99 | ;---------------------------- 100 | ; org 03h ; external interrupt 0 101 | ; ljmp HandleInt0 102 | ;---------------------------- 103 | org 0bh ; handle TF0 104 | ljmp HandleTF0 105 | ;---------------------------- 106 | ; org 13h ; Int 1 107 | ; ljmp HandleInt1 108 | ;---------------------------- 109 | ; org 1bh ; handle TF1 110 | ; ljmp HandleTF1 111 | ;---------------------------- 112 | ; org 23h ; RI/TI 113 | ; ljmp HandleRITI 114 | ;---------------------------- 115 | ; org 2bh ; handle TF2 116 | ; ljmp HandleTF2 117 | 118 | org 033h 119 | 120 | ;---------------------------------------------------------- 121 | ; int1 handler: 122 | ; trigger on host-do-device transmission signal 123 | ;---------------------------------------------------------- 124 | ;HandleInt1: 125 | ; setb ATHostToDevIntF 126 | ; reti 127 | 128 | ;---------------------------------------------------------- 129 | ; timer 0 int handler used for different purposes 130 | ; depending on TFModF and ATHostToDevF 131 | ; 132 | ; TFModF=0: 133 | ; timer is used as 16-bit alarm clock. 134 | ; Stop the timer after overflow, cleanup RX buffers 135 | ; and clear MiscSleepT0F 136 | ; RX timeout at 18.432MHz, set th0,tl0 to 137 | ; 0c0h,00h -> 10ms, 0e0h,00h -> 5ms, 0fah,00h -> 1ms 138 | ; 0fbh,0cdh -> 0.7ms, 0ffh,039h -> 0.12ms 139 | ; 140 | ; TFModF=1: 141 | ; timer is used in 8-bit-auto-reload-mode to generate 142 | ; the AT scancode clock with 2x40 microseconds timings. 143 | ; 40mus@18.432MHz -> th0 and tl0=0c3h or 61 processor cycles. 144 | ; 145 | ; TFModF=1, ATHostToDevF=0: 146 | ; device-to-host communication: send datagrams on the AT line. 147 | ; Each run in this mode will take 36 processor cycles. 148 | ; Extra nops between Data and Clock bit assignment for signal stabilization. 149 | ; 150 | ; TFModF=1, ATHostToDevF=1: 151 | ; host-do-device communication: receive datagrams on the AT line. 152 | ;---------------------------------------------------------- 153 | HandleTF0: 154 | jb TFModF,timerAsClockTimer ; 2,2 155 | 156 | ; --------------------------- timer is used as 16-bit alarm clock 157 | timerAsAlarmClock: 158 | ; -- stop timer 0 159 | clr tr0 160 | clr MiscSleepT0F 161 | reti 162 | 163 | ; --------------------------- AT clock driver, RX or TX 164 | timerAsClockTimer: 165 | push acc ; 2,4 166 | push psw ; 2,6 167 | jb ATHostToDevF,timerHostToDev ; 2,8 168 | 169 | ; --------------------------- device-to-host communication 170 | timerDevToHost: 171 | ; -- switch on bit-number 172 | ; ----------------- 173 | jb ATBitCount.0,timerTXClockRelease ; 2,10 174 | mov dptr,#timerDevToHostJT ; 2,12 175 | mov a,ATBitCount ; 1,13 176 | jmp @a+dptr ; 2,15 177 | 178 | timerDevToHostJT: 179 | sjmp timerTXStartBit ; 2,17 180 | sjmp timerTXDataBit 181 | sjmp timerTXDataBit 182 | sjmp timerTXDataBit 183 | sjmp timerTXDataBit 184 | sjmp timerTXDataBit 185 | sjmp timerTXDataBit 186 | sjmp timerTXDataBit 187 | sjmp timerTXDataBit 188 | sjmp timerTXParityBit 189 | sjmp timerTXStopBit 190 | sjmp timerTXStop ; safety 191 | 192 | ; ----------------- 193 | timerTXStartBit: 194 | ; -- set start bit (0) and pull down clock line 195 | jnb p3.3,timerTXClockBusy ; 2 196 | nop 197 | clr p3.5 ; 1 ; Data Startbit 198 | 199 | call nop20 200 | 201 | clr p3.3 ; 1 ; Clock 202 | sjmp timerTXEnd ; 2 203 | 204 | ; ----------------- 205 | timerTXDataBit: 206 | ; -- set data bit 0-7 and pull down clock line 207 | mov a,TXBuf ; 1 208 | rrc a ; 1 ; next data bit to c 209 | mov p3.5,c ; 2 210 | mov TXBuf,a ; 1 211 | 212 | call nop20 213 | 214 | clr p3.3 ; 1 ; Clock 215 | sjmp timerTXEnd 216 | 217 | ; ----------------- 218 | timerTXParityBit: 219 | ; -- set parity bit from ATTXParF and pull down clock line 220 | nop 221 | mov c,ATTXParF ; 1 ; parity bit 222 | mov p3.5,c ; 2 223 | 224 | call nop20 225 | 226 | clr p3.3 ; 1 ; Clock 227 | sjmp timerTXEnd ; 2 228 | 229 | ; ----------------- 230 | timerTXStopBit: 231 | ; -- set stop bit (1) and pull down clock line 232 | nop 233 | nop 234 | nop 235 | setb p3.5 ; 1 ; Data Stopbit 236 | 237 | call nop20 238 | 239 | clr p3.3 ; 1 ; Clock 240 | sjmp timerTXEnd ; 2 241 | 242 | ; ----------------- 243 | timerTXClockRelease: 244 | ; -- release clock line 245 | 246 | call nop20 247 | 248 | mov a,ATBitCount ; 1 249 | setb p3.3 ; 1 250 | cjne a,#21,timerTXCheckBusy ; 2 251 | setb p1.2 ; diag: data send 252 | ; end of TX sequence, not time critical 253 | sjmp timerTXStop 254 | 255 | timerTXCheckBusy: 256 | ; -- check if clock is released, but not after the stop bit. 257 | ; -- Host may pull down clock to abort communication at any time. 258 | jb p3.3,timerTXEnd 259 | 260 | timerTXClockBusy: 261 | ; -- clock is busy, abort communication 262 | setb ATCommAbort ; AT communication aborted flag 263 | clr p1.2 ; diag: data not send 264 | ; sjmp timerTXStop 265 | 266 | ; ----------------- 267 | timerTXStop: 268 | ; -- stop timer auto-reload 269 | clr TFModF 270 | clr tr0 271 | setb p3.5 ; just for safety, clean up data line state 272 | ; sjmp timerTXEnd 273 | 274 | ; --------------------------- done 275 | timerTXEnd: ; total 7 276 | ; -- done 277 | inc ATBitCount ; 1 278 | pop psw ; 2 279 | pop acc ; 2 280 | reti ; 2 281 | 282 | ; --------------------------- host-to-device communication 283 | timerHostToDev: 284 | ; -- switch on bit-number 285 | ; ----------------- 286 | jb ATBitCount.0,timerRXClockRelease ; 2,10 287 | mov dptr,#timerHostToDevJT ; 2,12 288 | mov a,ATBitCount ; 1,13 289 | jmp @a+dptr ; 2,15 290 | timerHostToDevJT: 291 | sjmp timerRXStartBit ; 2,17 292 | sjmp timerRXDataBit 293 | sjmp timerRXDataBit 294 | sjmp timerRXDataBit 295 | sjmp timerRXDataBit 296 | sjmp timerRXDataBit 297 | sjmp timerRXDataBit 298 | sjmp timerRXDataBit 299 | sjmp timerRXDataBit 300 | sjmp timerRXParityBit 301 | sjmp timerRXACKBit 302 | sjmp timerRXCleanup 303 | sjmp timerRXClockBusy ; safety 304 | 305 | ; ----------------- 306 | timerRXStartBit: 307 | ; -- check start bit, must be zero 308 | jb p3.5,timerRXClockBusy 309 | 310 | ; pull down clock line 311 | clr p3.3 ; 1 ; Clock 312 | sjmp timerRXEnd 313 | 314 | ; ----------------- 315 | timerRXDataBit: 316 | ; -- read bit 1-8 pull down clock line 317 | ; -- new data bit 318 | mov a,ATRXBuf 319 | mov c,p3.5 320 | rrc a 321 | mov ATRXBuf,a 322 | 323 | ; -- pull down clock line 324 | clr p3.3 ; 1 ; Clock 325 | sjmp timerRXEnd 326 | 327 | ; ----------------- 328 | timerRXParityBit: 329 | ; -- read and check parity bit 9 and pull down clock line 330 | ; -- check parity 331 | mov a,ATRXBuf 332 | jb p,timerRXParityBitPar 333 | jnb p3.5,timerRXClockBusy ; parity error 334 | ; -- pull down clock line 335 | clr p3.3 ; 1 ; Clock 336 | sjmp timerRXEnd 337 | 338 | timerRXParityBitPar: 339 | jb p3.5,timerRXClockBusy ; parity error 340 | ; -- pull down clock line 341 | clr p3.3 ; 1 ; Clock 342 | sjmp timerRXEnd 343 | 344 | ; ----------------- 345 | timerRXAckBit: 346 | ; -- check bit 10, stop-bit, must be 1. 347 | ; -- write ACK-bit and pull down clock line 348 | jnb p3.5,timerRXClockBusy 349 | 350 | ; ACK-Bit 351 | clr p3.5 ; 1 352 | nop 353 | nop 354 | nop 355 | clr p3.3 ; 1 ; Clock 356 | sjmp timerRXEnd ; 2 357 | 358 | ; ----------------- 359 | timerRXCleanup: 360 | ; -- end of RX clock sequence after 12 clock pulses 361 | clr TFModF 362 | 363 | ; -- release the data line 364 | setb p3.5 365 | 366 | ; -- datagram received, stop timer auto-reload 367 | setb ATCmdReceivedF ; full message received 368 | clr tr0 369 | sjmp timerRXEnd 370 | 371 | ; ----------------- 372 | timerRXClockRelease: 373 | ; -- release clock line 374 | nop 375 | nop 376 | nop 377 | mov a,ATBitCount ; 1 378 | setb p3.3 ; 1 379 | cjne a,#21,timerRXCheckBusy 380 | setb p1.1 ; diag: host-do-dev ok 381 | sjmp timerRXEnd 382 | 383 | timerRXCheckBusy: 384 | ; -- check if clock is released, but not after the last bit. 385 | ; -- Host may pull down clock to abort communication at any time. 386 | jb p3.3,timerRXEnd 387 | 388 | timerRXClockBusy: 389 | ; -- clock is busy, abort communication 390 | setb ATCommAbort ; AT communication aborted flag 391 | clr p1.1 ; diag: host-do-dev abort 392 | 393 | clr TFModF 394 | clr tr0 395 | setb p3.5 ; just for safety, clean up data line state 396 | ; sjmp timerRXEnd 397 | 398 | ; ----------------- 399 | timerRXEnd: ; total 7 400 | ; -- done 401 | inc ATBitCount ; 1 402 | pop psw ; 2 403 | pop acc ; 2 404 | reti ; 2 405 | 406 | ;---------------------------------------------------------- 407 | ; Atari ST to AT translaton table 408 | ;---------------------------------------------------------- 409 | ST2ATxlt0 DB 0h, 76h, 16h, 1eh, 26h, 25h, 2eh, 36h, 3dh, 3eh, 46h, 45h, 4eh, 55h, 66h, 0dh 410 | ST2ATxlt1 DB 15h, 1dh, 24h, 2dh, 2ch, 35h, 3ch, 43h, 44h, 4dh, 54h, 5bh, 5ah, 14h, 1ch, 1bh 411 | ST2ATxlt2 DB 23h, 2bh, 34h, 33h, 3bh, 42h, 4bh, 4ch, 52h, 5dh, 12h, 0eh, 1ah, 22h, 21h, 2ah 412 | ST2ATxlt3 DB 32h, 31h, 3ah, 41h, 49h, 4ah, 59h, 0h, 11h, 29h, 58h, 05h, 06h, 04h, 0ch, 03h 413 | ST2ATxlt4 DB 0bh, 83h, 0ah, 01h, 09h, 0h, 0h, 6ch, 75h, 0h, 7bh, 6bh, 0h, 74h, 79h, 0h 414 | ST2ATxlt5 DB 72h, 0h, 70h, 71h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h 415 | ST2ATxlt6 DB 61h, 7ah, 7dh, 77h, 7eh, 4ah, 7ch, 6ch, 75h, 7dh, 6bh, 73h, 74h, 69h, 72h, 7ah 416 | ST2ATxlt7 DB 70h, 71h, 5ah, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h 417 | 418 | ;---------------------------------------------------------- 419 | ; Atari ST to AT translaton table 420 | ; Bit-Table for two-byte-AT-Scancodes 421 | ; bit 0: E0-Escape 422 | ; bit 1: send Make E0,12,E0,7C / BreakE0,F0,7C,E0,F0,12 (PrtScr) 423 | ; bit 2: send Make E1,14,77,E1,F0,14,F0,77 (Pause) 424 | ;---------------------------------------------------------- 425 | ST2ATxlte0 DB 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h 426 | ST2ATxlte1 DB 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h 427 | ST2ATxlte2 DB 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h 428 | ST2ATxlte3 DB 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h 429 | ST2ATxlte4 DB 0h, 0h, 0h, 0h, 0h, 0h, 0h, 01h, 01h, 0h, 0h, 01h, 0h, 01h, 0h, 0h 430 | ST2ATxlte5 DB 01h, 0h, 01h, 01h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h 431 | ST2ATxlte6 DB 0h, 01h, 01h, 0h, 0h, 01h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h 432 | ST2ATxlte7 DB 0h, 0h, 01h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h 433 | 434 | ;---------------------------------------------------------- 435 | ; ring buffer insertion helper. Input Data comes in r2 436 | ;---------------------------------------------------------- 437 | RingBufCheckInsert: 438 | ; check for ring buffer overflow 439 | mov a,RingBufPtrOut 440 | setb c 441 | subb a,RingBufPtrIn 442 | anl a,#RingBufSizeMask 443 | jz RingBufFull 444 | 445 | ; some space left, insert data 446 | mov a,RingBufPtrIn 447 | add a,#RingBuf 448 | mov r0,a 449 | mov a,r2 450 | mov @r0,a 451 | 452 | ; increment pointer 453 | inc RingBufPtrIn 454 | anl RingBufPtrIn,#RingBufSizeMask 455 | ret 456 | 457 | RingBufFull: 458 | ; error routine 459 | clr p1.0 460 | ret 461 | 462 | ;---------------------------------------------------------- 463 | ; Get received data and translate it into the ring buffer 464 | ;---------------------------------------------------------- 465 | TranslateToBufST: 466 | ; translate from Atari ST to AT scancode 467 | mov a,RawBuf 468 | 469 | ; save make/break bit 7 470 | mov c,acc.7 471 | mov ATTXBreakF,c 472 | 473 | ; ignore make/break bit 7 474 | anl a,#7fh 475 | 476 | ; check 2-byte scancodes 477 | mov r4,a 478 | mov dptr,#ST2ATxlte0 479 | movc a,@a+dptr 480 | mov c,acc.0 481 | mov ATTXMasqF,c 482 | mov a,r4 483 | 484 | ; get AT scancode 485 | mov dptr,#ST2ATxlt0 486 | movc a,@a+dptr 487 | 488 | ; save AT scancode 489 | mov OutputBuf,a 490 | 491 | ; clear received data flag 492 | clr MiscRXCompleteF 493 | 494 | ; keyboard disabled? 495 | jb ATKbdDisableF,TranslateToBufSTEnd 496 | 497 | ; check for 0xE0 escape code 498 | jnb ATTXMasqF,TranslateToBufSTNoEsc 499 | mov r2,#0E0h 500 | call RingBufCheckInsert 501 | 502 | TranslateToBufSTNoEsc: 503 | ; check for 0xF0 release / break code 504 | jnb ATTXBreakF,TranslateToBufSTNoRelease 505 | mov r2,#0F0h 506 | call RingBufCheckInsert 507 | 508 | TranslateToBufSTNoRelease: 509 | ; normal data byte 510 | mov r2, OutputBuf 511 | call RingBufCheckInsert 512 | 513 | TranslateToBufSTEnd: 514 | ret 515 | 516 | ;---------------------------------------------------------- 517 | ; Send data from the ring buffer 518 | ;---------------------------------------------------------- 519 | ; -- send ring buffer contents 520 | BufTX: 521 | ; check if data is present in the ring buffer 522 | clr c 523 | mov a,RingBufPtrIn 524 | subb a,RingBufPtrOut 525 | anl a,#RingBufSizeMask 526 | jz BufTXEnd 527 | 528 | ; -- get data from buffer 529 | mov a,RingBufPtrOut 530 | add a,#RingBuf 531 | mov r0,a 532 | mov a,@r0 533 | 534 | ; -- send data 535 | mov TXBuf,a ; 8 data bits 536 | mov c,p 537 | cpl c 538 | mov ATTXParF,c ; odd parity bit 539 | clr ATHostToDevF ; timer in TX mode 540 | setb ATTXActiveF ; diag: TX is active 541 | ; clr ex0 ; may diable input interrupt here, better is, better dont. 542 | ; clr ex1 543 | call timer0_init 544 | 545 | ; -- wait for completion 546 | BufTXWaitSent: 547 | jb TFModF,BufTXWaitSent 548 | ; setb ex1 ; enable external interupt 1 549 | ; setb ex0 ; enable external interupt 0 550 | clr ATTXActiveF ; diag 551 | jb ATCommAbort,BufTXEnd ; check on communication abort 552 | 553 | ; ; diag: send also on serial line 554 | ; mov a,@r0 555 | ; mov sbuf,a 556 | ; clr ti 557 | ;BufTXWaitDiagSend: 558 | ; jnb ti,BufTXWaitDiagSend 559 | 560 | ; -- store last transmitted word for resend-feature 561 | mov a,@r0 562 | mov ATRXResendBuf,a 563 | 564 | ; -- increment output pointer 565 | inc RingBufPtrOut 566 | anl RingBufPtrOut,#RingBufSizeMask 567 | 568 | BufTXEnd: 569 | ret 570 | 571 | ;---------------------------------------------------------- 572 | ; check and respond to received AT commands 573 | ; used bits: internal: ATCmdLedF, ATCmdScancodeF external ATCmdResetF 574 | ;---------------------------------------------------------- 575 | ATCmdProc: 576 | ; -- check for new data 577 | jb ATCmdReceivedF,ATCPGo 578 | ljmp ATCPDone 579 | 580 | ATCPGo: 581 | ; ; -- diag: send received AT command via serial line 582 | ; mov sbuf,ATRXBuf 583 | ; clr ti 584 | ;ATCPWait: 585 | ; jnb ti,ATCPWait 586 | 587 | ; -- get received AT command 588 | mov a,ATRXBuf 589 | clr ATCmdReceivedF 590 | 591 | ; -- argument for 0xed command: set keyboard LED 592 | jnb ATCmdLedF,ATCPNotLEDarg 593 | clr ATCmdLedF 594 | 595 | ; -- set build-in LEDs 596 | ; NumLock 597 | mov c,acc.1 598 | cpl c 599 | mov p1.5,c 600 | ; CapsLock 601 | mov c,acc.2 602 | cpl c 603 | mov p1.6,c 604 | ; ScrollLock 605 | mov c,acc.0 606 | cpl c 607 | mov p1.7,c 608 | 609 | ljmp ATCPSendAck 610 | 611 | ATCPNotLEDarg: 612 | ; -- argument for 0xf0 command: set scancode. 613 | jnb ATCmdScancodeF,ATCPNotF0Arg 614 | clr ATCmdScancodeF 615 | jnz ATCPSendAck 616 | ; -- Argument 0x0: send ACK and scancode 617 | mov r2,#0FAh 618 | call RingBufCheckInsert 619 | ; send 0x02, the default scancode 620 | mov r2,#02h 621 | call RingBufCheckInsert 622 | sjmp ATCPDone 623 | ATCPNotF0Arg: 624 | ; -- command 0xed: set keyboard LED command. set bit for next argument processing and send ACK 625 | cjne a,#0edh,ATCPNotED 626 | setb ATCmdLedF 627 | sjmp ATCPSendAck 628 | ATCPNotED: 629 | ; -- command 0xee: echo command. send 0xee 630 | cjne a,#0EEh,ATCPNotEE 631 | mov r2,#0EEh 632 | call RingBufCheckInsert 633 | sjmp ATCPDone 634 | ATCPNotEE: 635 | ; -- command 0xf0: scan code set. set bit for next argument processing and send ACK 636 | cjne a,#0f0h,ATCPNotF0 637 | setb ATCmdScancodeF 638 | sjmp ATCPSendAck 639 | ATCPNotF0: 640 | cjne a,#0f1h,ATCPNotF1 641 | sjmp ATCPSendAck 642 | ATCPNotF1: 643 | ; -- command 0xf2: keyboard model detection. send ACK,xab,x83 644 | cjne a,#0f2h,ATCPNotF2 645 | mov r2,#0FAh 646 | call RingBufCheckInsert 647 | mov r2,#0ABh 648 | call RingBufCheckInsert 649 | mov r2,#083h 650 | call RingBufCheckInsert 651 | sjmp ATCPDone 652 | ATCPNotF2: 653 | ; -- command 0xf3: typematic repeat rate. send ACK and ignore 654 | cjne a,#0f3h,ATCPNotF3 655 | sjmp ATCPSendAck 656 | ATCPNotF3: 657 | ; -- command 0xf4: keyboard enable. clear TX buffer, send ACK 658 | cjne a,#0f4h,ATCPNotF4 659 | mov RingBufPtrIn,#0 660 | mov RingBufPtrOut,#0 661 | clr ATKbdDisableF 662 | sjmp ATCPSendAck 663 | ATCPNotF4: 664 | ; -- command 0xf5: keyboard disable. send ACK and set ATKbdDisableF 665 | cjne a,#0f5h,ATCPNotF5 666 | setb ATKbdDisableF 667 | sjmp ATCPSendAck 668 | ATCPNotF5: 669 | ; -- command 0xf6: keyboard enable. clear TX buffer, send ACK 670 | cjne a,#0f6h,ATCPNotF6 671 | mov RingBufPtrIn,#0 672 | mov RingBufPtrOut,#0 673 | clr ATKbdDisableF 674 | sjmp ATCPSendAck 675 | ATCPNotF6: 676 | ; -- command 0xfe: resend last word 677 | cjne a,#0feh,ATCPNotFE 678 | mov r2,ATRXResendBuf 679 | call RingBufCheckInsert 680 | sjmp ATCPDone 681 | ATCPNotFE: 682 | ; -- command 0xff: keyboard reset 683 | cjne a,#0ffh,ATCPNotFF 684 | mov RingBufPtrIn,#0 685 | mov RingBufPtrOut,#0 686 | setb ATCmdResetF 687 | clr ATKbdDisableF 688 | sjmp ATCPSendAck 689 | ATCPNotFF: 690 | sjmp ATCPSendAck 691 | 692 | ATCPSendAck: 693 | mov r2,#0FAh 694 | call RingBufCheckInsert 695 | ; sjmp ATCPDone 696 | 697 | ATCPDone: 698 | ret 699 | 700 | ;---------------------------------------------------------- 701 | ; helper, waste 20 cpu cycles 702 | ; note: call and return takes 4 cycles 703 | ;---------------------------------------------------------- 704 | nop20: 705 | nop 706 | nop 707 | nop 708 | nop 709 | nop 710 | nop 711 | 712 | nop 713 | nop 714 | nop 715 | nop 716 | nop 717 | nop 718 | nop 719 | nop 720 | nop 721 | nop 722 | 723 | ret 724 | 725 | ;---------------------------------------------------------- 726 | ; init uart with timer 2 as baudrate generator 727 | ; note: this timer is not present on the AT89C2051 728 | ;---------------------------------------------------------- 729 | ;uart_timer2_init: 730 | ; mov scon, #050h ; uart mode 1 (8 bit), single processor 731 | ; 732 | ; orl t2con, #34h ; Timer 2: internal baudrate generate mode RX/TX 733 | ; mov rcap2h, #uart_t2h_9600_18432k 734 | ; mov rcap2l, #uart_t2l_9600_18432k 735 | ; clr es ; disable serial interrupt 736 | ; 737 | ; ret 738 | 739 | ;---------------------------------------------------------- 740 | ; init uart with timer 1 as baudrate generator 741 | ; Atari 7812.5 BPS 742 | ;---------------------------------------------------------- 743 | uart_timer1_init: 744 | mov scon, #050h ; uart mode 1 (8 bit), single processor 745 | orl tmod, #020h ; M0,M1, bit4,5 in TMOD, timer 1 in mode 2, 8bit-auto-reload 746 | orl pcon, #080h ; SMOD, bit 7 in PCON 747 | mov th1, #uart_t1_7k8125_12M 748 | mov tl1, #uart_t1_7k8125_12M 749 | clr es ; disable serial interrupt 750 | setb tr1 751 | 752 | clr ri 753 | setb ti 754 | 755 | ret 756 | 757 | ;---------------------------------------------------------- 758 | ; init timer 0 for interval timing (fast 8 bit reload) 759 | ; need 75-85mus intervals 760 | ;---------------------------------------------------------- 761 | timer0_init: 762 | clr tr0 763 | anl tmod, #0f0h ; clear all lower bits 764 | orl tmod, #02h; ; 8-bit Auto-Reload Timer, mode 2 765 | mov th0, #interval_t0_45u_12M 766 | mov tl0, #interval_t0_45u_12M 767 | setb et0 ; (IE.1) enable timer 0 interrupt 768 | setb TFModF ; see timer 0 interrupt code 769 | clr ATCommAbort ; communication abort flag 770 | mov ATBitCount,#0 771 | setb tr0 ; go 772 | ret 773 | 774 | ;---------------------------------------------------------- 775 | ; init timer 0 in 16 bit mode for inter-char delay of 0.13ms 776 | ;---------------------------------------------------------- 777 | timer0_diag_init: 778 | clr tr0 779 | anl tmod, #0f0h ; clear all lower bits 780 | orl tmod, #01h; ; M0,M1, bit0,1 in TMOD, timer 0 in mode 1, 16bit 781 | mov th0, #interval_th_128u_12M 782 | mov tl0, #interval_tl_128u_12M 783 | setb et0 ; (IE.1) enable timer 0 interrupt 784 | clr TFModF ; see timer 0 interrupt code 785 | setb MiscSleepT0F 786 | setb tr0 ; go 787 | ret 788 | 789 | ;---------------------------------------------------------- 790 | ; init timer 0 in 16 bit mode for faked POST delay of of 20ms 791 | ;---------------------------------------------------------- 792 | timer0_20ms_init: 793 | clr tr0 794 | anl tmod, #0f0h ; clear all upper bits 795 | orl tmod, #01h; ; M0,M1, bit0,1 in TMOD, timer 0 in mode 1, 16bit 796 | mov th0, #interval_th_20m_12M 797 | mov tl0, #interval_tl_20m_12M 798 | setb et0 ; (IE.1) enable timer 0 interrupt 799 | clr TFModF ; see timer 0 interrupt code 800 | setb MiscSleepT0F 801 | setb tr0 ; go 802 | ret 803 | 804 | ;---------------------------------------------------------- 805 | ; Id 806 | ;---------------------------------------------------------- 807 | RCSId DB "$Id: kbdbabel_st_ps2_8051.asm,v 1.2 2007/07/25 09:55:36 akurz Exp $" 808 | 809 | ;---------------------------------------------------------- 810 | ; main 811 | ;---------------------------------------------------------- 812 | Start: 813 | ; -- init the stack 814 | mov sp,#StackBottom 815 | ; -- init UART and timer0/1 816 | ; acall uart_timer2_init 817 | acall uart_timer1_init 818 | acall timer0_diag_init 819 | 820 | ; -- enable interrupts int0 821 | setb ea 822 | 823 | ; -- clear all flags 824 | mov B20,#0 825 | mov B21,#0 826 | mov B22,#0 827 | mov B23,#0 828 | 829 | ; -- init the ring buffer 830 | mov RingBufPtrIn,#0 831 | mov RingBufPtrOut,#0 832 | 833 | ; -- cold start flag 834 | setb ATCmdResetF 835 | 836 | ; ---------------- 837 | Loop: 838 | ; -- check input receive status 839 | jb RI,LoopProcessSTData 840 | 841 | ; -- check on new AT data received 842 | jb ATCmdReceivedF,LoopProcessATcmd 843 | 844 | ; -- check if AT communication active. 845 | jb TFModF,Loop 846 | 847 | ; -- delay flag 848 | ; jb MiscSleepT0F,Loop 849 | 850 | ; -- check AT line status, clock line must not be busy 851 | jnb p3.3,Loop 852 | 853 | ; -- check data line for RX or TX status 854 | jb p3.5,LoopATTX 855 | 856 | sjmp LoopATRX 857 | 858 | ;---------------------------------------------------------- 859 | ; helpers for the main loop 860 | ;---------------------------------------------------------- 861 | ; ---------------- 862 | LoopProcessSTData: 863 | ; -- input data received, process the received scancode into output ring buffer 864 | mov a,sbuf 865 | mov RawBuf,a 866 | clr RI 867 | 868 | jb ATCmdResetF, Loop 869 | setb MiscRXCompleteF 870 | call TranslateToBufST 871 | sjmp Loop 872 | 873 | ; ----------------- 874 | LoopProcessATcmd: 875 | ; -- AT command processing 876 | call ATCmdProc 877 | sjmp loop 878 | 879 | ; ---------------- 880 | LoopATRX: 881 | ; -- Host-do-Device communication 882 | ; -- diag: host-do-dev ok 883 | setb p1.1 884 | 885 | ; -- receive data on the AT line 886 | mov ATRXCount,#0 887 | mov ATRXBuf,#0 888 | ; clr ATHostToDevIntF 889 | setb ATHostToDevF 890 | call timer0_init 891 | 892 | ; wait for completion 893 | LoopTXWaitSent: 894 | jb TFModF,LoopTXWaitSent 895 | LoopCheckATEnd: 896 | ljmp Loop 897 | 898 | 899 | ; ---------------- 900 | LoopATTX: 901 | ; -- Device-to-Host communication 902 | ; -- send data on the AT line 903 | ; some delay 0.15ms 904 | call timer0_diag_init 905 | LoopTXWaitDelay: 906 | ; jb PCRXActiveF,LoopTXWaitDelayEnd ; new receive in progress ; @@@@@@@@@@ FIXME 907 | jb MiscSleepT0F,LoopTXWaitDelay 908 | 909 | LoopSendData: 910 | ; send data 911 | call BufTX 912 | 913 | ; -- keyboard reset/cold start: send AAh after some delay 914 | jnb ATCmdResetF,LoopTXWaitDelayEnd 915 | clr ATCmdResetF 916 | ; -- optional delay of 20ms after faked cold start 917 | ; yes, some machines will not boot without this, e.g. IBM PS/ValuePoint 433DX/D 918 | call timer0_20ms_init 919 | LoopTXResetDelay: 920 | jb MiscSleepT0F,LoopTXResetDelay 921 | ; -- send "self test passed" 922 | mov r2,#0AAh 923 | call RingBufCheckInsert 924 | LoopTXWaitDelayEnd: 925 | ljmp Loop 926 | 927 | ;---------------------------------------------------------- 928 | ; Still space on the ROM left for the license? 929 | ;---------------------------------------------------------- 930 | LIC01 DB " Copyright 2007 by Alexander Kurz" 931 | LIC02 DB " " 932 | GPL01 DB " This program is free software; you can redistribute it and/or modify" 933 | GPL02 DB " it under the terms of the GNU General Public License as published by" 934 | GPL03 DB " the Free Software Foundation; either version 3, or (at your option)" 935 | GPL04 DB " any later version." 936 | GPL05 DB " " 937 | GPL06 DB " This program is distributed in the hope that it will be useful," 938 | GPL07 DB " but WITHOUT ANY WARRANTY; without even the implied warranty of" 939 | GPL08 DB " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the" 940 | GPL09 DB " GNU General Public License for more details." 941 | GPL10 DB " " 942 | ; ---------------- 943 | end 944 | -------------------------------------------------------------------------------- /kbdbabel-pc-ps2/kbdbabel_ps2_pcxt_8051.asm: -------------------------------------------------------------------------------- 1 | ; --------------------------------------------------------------------- 2 | ; AT/PS2 to PC/XT keyboard transcoder for 8051 type processors. 3 | ; 4 | ; $Id: kbdbabel_ps2_pcxt_8051.asm,v 1.1 2009/08/21 22:09:54 akurz Exp $ 5 | ; 6 | ; Clock/Crystal: 24MHz. 7 | ; 8 | ; PC/XT Keyboard connect: 9 | ; This two pins need externals 4.7k resistors as pullup. 10 | ; DATA - p3.4 (Pin 14 on DIL40, Pin 8 on AT89C2051 PDIP20) 11 | ; CLOCK - p3.2 (Pin 12 on DIL40, Pin 6 on AT89C2051 PDIP20, Int 0) 12 | ; 13 | ; AT/PS2 Keyboard connect: 14 | ; This two pins need externals 4.7k resistors as pullup. 15 | ; DATA - p3.5 (Pin 14 on DIL40, Pin 8 on AT89C2051 PDIP20) 16 | ; CLOCK - p3.3 (Pin 12 on DIL40, Pin 6 on AT89C2051 PDIP20, Int 0) 17 | ; 18 | ; LED-Output connect: 19 | ; LEDs are connected with 220R to Vcc 20 | ; PCXT Ring buffer full - p1.7 (Pin 8 on DIL40, Pin 19 on AT89C2051 PDIP20) 21 | ; AT/PS2 RX error - p1.6 (Pin 7 on DIL40, Pin 18 on AT89C2051 PDIP20) 22 | ; AT/PS2 RX Parity error- p1.5 (Pin 6 on DIL40, Pin 17 on AT89C2051 PDIP20) 23 | ; PS2 Ring buffer full - p1.4 (Pin 5 on DIL40, Pin 16 on AT89C2051 PDIP20) 24 | ; - p1.3 (Pin 4 on DIL40, Pin 15 on AT89C2051 PDIP20) 25 | ; - p1.2 (Pin 3 on DIL40, Pin 14 on AT89C2051 PDIP20) 26 | ; - p1.1 (Pin 2 on DIL40, Pin 13 on AT89C2051 PDIP20) 27 | ; - p1.0 (Pin 1 on DIL40, Pin 12 on AT89C2051 PDIP20) 28 | ; 29 | ; Build: 30 | ; $ asl -L kbdbabel_ps2_pcxt_8051.asm -o kbdbabel_ps2_pcxt_8051.p 31 | ; $ p2bin -l \$ff -r 0-\$7ff kbdbabel_ps2_pcxt_8051 32 | ; write kbdbabel_ps2_pcxt_8051.bin on an empty 27C256 or AT89C2051 33 | ; 34 | ; Copyright 2009 by Alexander Kurz 35 | ; 36 | ; This is free software. 37 | ; You may copy and redistibute this software according to the 38 | ; GNU general public license version 3 or any later version. 39 | ; 40 | ; --------------------------------------------------------------------- 41 | 42 | cpu 8052 43 | include stddef51.inc 44 | include kbdbabel_intervals.inc 45 | 46 | ;---------------------------------------------------------- 47 | ; Variables / Memory layout 48 | ;---------------------------------------------------------- 49 | ;------------------ octets 50 | B20 sfrb 20h ; bit adressable space 51 | B21 sfrb 21h 52 | B22 sfrb 22h 53 | B23 sfrb 23h 54 | KbBitBufL sfrb 24h 55 | KbBitBufH sfrb 25h 56 | ;KbClockMin equ 26h 57 | ;KbClockMax equ 27h 58 | PS2TXBitBuf equ 28h 59 | PS2ResendBuf equ 29h 60 | PCXTBitCount equ 2ah 61 | PCXTTXBuf equ 2bh 62 | RawBuf equ 30h ; raw PC/XT scancode 63 | PS2ResendTTL equ 31h ; prevent resent-loop 64 | TXBuf equ 32h ; AT scancode TX buffer 65 | RingBuf1PtrIn equ 33h ; Ring Buffer write pointer, starting with zero 66 | RingBuf1PtrOut equ 34h ; Ring Buffer read pointer, starting with zero 67 | RingBuf2PtrIn equ 35h ; Ring Buffer write pointer, starting with zero 68 | RingBuf2PtrOut equ 36h ; Ring Buffer read pointer, starting with zero 69 | PS2RXLastBuf equ 37h ; Last received scancode 70 | PS2LedBuf equ 38h ; LED state buffer for PS2 Keyboard 71 | 72 | ;------------------ bits 73 | PS2RXBitF bit B20.0 ; RX-bit-buffer 74 | PS2RXCompleteF bit B20.1 ; full and correct byte-received 75 | PS2ActiveF bit B20.2 ; PS2 RX or TX in progress flag 76 | PS2HostToDevF bit B20.3 ; host-to-device flag for Int0-handler 77 | PS2RXBreakF bit B20.4 ; AT/PS2 0xF0 Break scancode received 78 | PS2RXEscapeF bit B20.5 ; AT/PS2 0xE0 Escape scancode received 79 | PS2TXAckF bit B20.6 ; ACK-Bit on host-to-dev 80 | PS2RXAckF bit B20.7 ; ACK-Scancode received 81 | MiscSleepF bit B21.0 ; sleep timer active flag 82 | TFModF bit B21.1 ; Timer modifier: PS2 timeout or alarm clock 83 | TimeoutF bit B21.2 ; Timeout occured 84 | PS2ResendF bit B21.3 ; AT/PS2 resend 85 | PCXTNextBitF bit B22.0 ; Next PC/XT Data Bit to send 86 | PCXTActiveF bit B22.1 ; PCXT TX in progress flag 87 | ;------------------ arrays 88 | RingBuf1 equ 40h ; Data for the host 89 | RingBuf1SizeMask equ 0fh ; 16 byte ring-buffer size 90 | RingBuf2 equ 50h ; Data for the keyboard 91 | RingBuf2SizeMask equ 0fh ; 16 byte ring-buffer size 92 | 93 | ;------------------ stack 94 | StackBottom equ 60h ; the stack 95 | 96 | ;---------------------------------------------------------- 97 | ; start 98 | ;---------------------------------------------------------- 99 | org 0 ; cold start 100 | ljmp Start 101 | ;---------------------------------------------------------- 102 | ; interrupt handlers 103 | ;---------------------------------------------------------- 104 | ;---------------------------- 105 | ; int 0, connected to keyboard clock line. 106 | ; With a raising signal on the clock line there are 15mus 107 | ; left to read the data line. Using a 3.6864 MHz Crystal 108 | ; this will be less than 5 processor cycles. 109 | ;---------------------------- 110 | org 03h ; external interrupt 0 111 | reti 112 | ; ljmp HandleInt0 113 | ;---------------------------- 114 | org 0bh ; handle TF0 115 | ljmp HandleTF0 116 | ;---------------------------- 117 | org 13h ; Int 1 118 | jnb P3.5, HandleInt1 ; this is time critical 119 | setb PS2RXBitF 120 | ljmp HandleInt1 121 | ;---------------------------- 122 | org 1bh ; handle TF1 123 | ljmp HandleTF1 124 | ;---------------------------- 125 | ; org 23h ; RI/TI 126 | ; ljmp HandleRITI 127 | ;---------------------------- 128 | ; org 2bh ; handle TF2 129 | ; ljmp HandleTF2 130 | 131 | org 033h 132 | 133 | ;---------------------------------------------------------- 134 | ; timer 0 int handler: 135 | ; 136 | ; TFModF=0: 137 | ; timer is used to measure the clock-signal-interval length 138 | ; Stop the timer after overflow, cleanup RX buffers 139 | ; RX timeout after 1 - 1.3ms 140 | ; 141 | ; TFModF=1: delay timer 142 | ;---------------------------------------------------------- 143 | HandleTF0: 144 | ; stop timer 145 | clr tr0 146 | 147 | jb TFModF,timerAsClockTimer 148 | 149 | ; --- timer used for AT/PS2 bus timeout 150 | ; buzzeroff 151 | ; clr p3.7 152 | ; cleanup buffers 153 | mov KbBitBufL,#0 154 | mov KbBitBufH,#0 155 | mov r7,#0 156 | clr PS2ActiveF ; receive in progress flag 157 | clr PS2HostToDevF 158 | setb TimeoutF 159 | 160 | ; reset timer value 161 | mov th0, #interval_th_11_bit 162 | mov tl0, #interval_tl_11_bit 163 | 164 | ; setb p3.5 ; data 165 | ; setb p3.3 ; clock 166 | 167 | sjmp HandleTF0End 168 | 169 | timerAsClockTimer: 170 | ; --- timer used to generate delays 171 | setb MiscSleepF 172 | clr TFModF 173 | 174 | HandleTF0End: 175 | reti 176 | 177 | ;---------------------------------------------------------- 178 | ; int1 handler: 179 | ; read one AT/PS2 data bit triggered by the keyboard clock line 180 | ; rotate bit into KbBitBufH, KbBitBufL. 181 | ; Last clock sample interval is stored in r6 182 | ; rotate bit into 22h, 23h. 183 | ; Num Bits is in r7 184 | ; 185 | ; TX: 186 | ; Byte to sent is read from PS2TXBitBuf 187 | ; ACK result is stored in PS2TXAckF. 0 is ACK, 1 is NACK. 188 | ;---------------------------------------------------------- 189 | HandleInt1: 190 | push acc 191 | push psw 192 | clr p1.0 193 | 194 | ; receive in progress flag 195 | setb PS2ActiveF 196 | 197 | ; -- reset timeout timer 198 | ; stop timer 0 199 | clr tr0 200 | 201 | ; reset timer value 202 | mov th0, #interval_th_11_bit 203 | mov tl0, #interval_tl_11_bit 204 | 205 | ; start timer 0 206 | setb tr0 207 | 208 | ; -- check for RX/TX 209 | jb PS2HostToDevF,Int1PS2TX 210 | 211 | ; --------------------------- AT/PS2 RX: get and save data samples 212 | ; -- write to mem, first 8 bits 213 | mov c,PS2RXBitF ; new bit 214 | mov a,KbBitBufL 215 | rrc a 216 | mov KbBitBufL,a 217 | 218 | ; -- write to mem, upper bits 219 | mov a,KbBitBufH 220 | rrc a 221 | mov KbBitBufH,a 222 | 223 | ; -- diag: write byte count or data bits to LED-Port 224 | ; mov a,r7 225 | ; mov a,KbBitBufL 226 | ; xrl a,0FFh 227 | ; mov p1,a 228 | 229 | ; -- reset bit buffer 230 | clr PS2RXBitF 231 | 232 | ; --------------------------- consistancy checks 233 | ; -- checks by bit number 234 | mov a,r7 235 | jnz Int1NotStartBit ; start bit 236 | Int1NotStartBit: 237 | clr c 238 | subb a,#0ah 239 | jz Int1LastBit 240 | 241 | ; -- inc the bit counter 242 | inc r7 243 | ljmp Int1Return 244 | 245 | ; -- special handling for last bit: output 246 | Int1LastBit: 247 | ; start-bit must be 0 248 | jb KbBitBufH.5, Int1Error 249 | ; stop-bit must be 1 250 | jnb KbBitBufL.7, Int1Error 251 | ; error LED off 252 | setb p1.5 253 | setb p1.6 254 | 255 | ; -- rotate back 2x 256 | mov a,KbBitBufH 257 | rlc a 258 | mov KbBitBufH,a 259 | mov a,KbBitBufL 260 | rlc a 261 | mov KbBitBufL,a 262 | 263 | mov a,KbBitBufH 264 | rlc a 265 | mov KbBitBufH,a 266 | mov a,KbBitBufL 267 | rlc a 268 | mov KbBitBufL,a 269 | 270 | ; -- check parity 271 | jb p,Int1RXParityBitPar 272 | jnc Int1ParityError 273 | sjmp Int1Output 274 | 275 | Int1RXParityBitPar: 276 | jc Int1ParityError 277 | 278 | Int1Output: 279 | ; -- return received byte 280 | mov a, KbBitBufL 281 | mov RawBuf, a 282 | mov r7,#0 283 | setb PS2RXCompleteF ; fully received flag 284 | clr PS2ActiveF ; receive in progress flag 285 | 286 | ; ; --- write to LED 287 | ; xrl a,0FFh 288 | ; mov p1,a 289 | 290 | sjmp Int1Return 291 | 292 | Int1ParityError: 293 | ; -- cleanup buffers 294 | mov KbBitBufL,#0 295 | mov KbBitBufH,#0 296 | mov r7,#0 297 | clr p1.5 298 | sjmp Int1Return 299 | 300 | Int1Error: 301 | ; -- cleanup buffers 302 | mov KbBitBufL,#0 303 | mov KbBitBufH,#0 304 | mov r7,#0 305 | clr p1.6 306 | sjmp Int1Return 307 | 308 | ; --------------------------- AT/PS2 TX 309 | Int1PS2TX: 310 | ; clr p1.4 311 | ; -- reset RX bit buffer 312 | clr PS2RXBitF 313 | setb PS2TXAckF 314 | ; setb p1.5 315 | ; -- checks by bit number 316 | mov a,r7 317 | jz Int1PS2TXStart 318 | clr c 319 | subb a,#09h 320 | jc Int1PS2TXData 321 | jz Int1PS2TXPar 322 | dec a 323 | jz Int1PS2TXStop 324 | 325 | ; --- the last bit. read ACK-bit 326 | mov c,p3.5 327 | mov PS2TXAckF,c 328 | ; mov p1.5,c 329 | 330 | ; --- reset data and clock 331 | mov r7,#0h 332 | clr p3.3 ; pull down clock 333 | setb p3.5 ; data 334 | clr PS2ActiveF ; receive in progress flag 335 | clr PS2HostToDevF 336 | sjmp Int1Return 337 | 338 | Int1PS2TXStart: 339 | ; --- set start bit 340 | clr p3.5 341 | sjmp Int1PS2TXReturn 342 | 343 | Int1PS2TXData 344 | ; --- set data bit 345 | mov a,PS2TXBitBuf 346 | mov c,acc.0 347 | mov p3.5,c 348 | rr a 349 | mov PS2TXBitBuf,a 350 | sjmp Int1PS2TXReturn 351 | 352 | Int1PS2TXPar: 353 | ; --- set parity bit 354 | mov a,PS2TXBitBuf 355 | mov c,p 356 | cpl c 357 | mov p3.5,c 358 | sjmp Int1PS2TXReturn 359 | 360 | Int1PS2TXStop: 361 | ; --- set stop bit 362 | setb p3.5 363 | sjmp Int1PS2TXReturn 364 | 365 | Int1PS2TXReturn: 366 | ; -- inc the bit counter 367 | inc r7 368 | ; sjmp Int1Return 369 | 370 | ; --------------------------- done 371 | Int1Return: 372 | setb p1.0 373 | pop psw 374 | pop acc 375 | reti 376 | 377 | ;---------------------------------------------------------- 378 | ; timer 1 int handler: PC/XT transmitter 379 | ;---------------------------------------------------------- 380 | HandleTF1: 381 | ; --------------------------- PC/XT clock driver, TX only 382 | push acc ; 2,4 383 | push psw ; 2,6 384 | 385 | ; --------------------------- device-to-host communication 386 | ; -- switch on bit-number 387 | ; ----------------- 388 | mov dptr,#timer1PCXTJT ; 2,8 389 | mov a,PCXTBitCount ; 1,9 390 | add a,PCXTBitCount ; 1,10 391 | jmp @a+dptr ; 2,12 392 | 393 | timer1PCXTJT: 394 | sjmp timer1TXStart1Bit ; 2,14 395 | sjmp timer1TXEnd 396 | sjmp timer1TXStart2Bit 397 | sjmp timer1TXRelease 398 | sjmp timer1TXDataBit 399 | sjmp timer1TXRelease 400 | sjmp timer1TXDataBit 401 | sjmp timer1TXRelease 402 | sjmp timer1TXDataBit 403 | sjmp timer1TXRelease 404 | sjmp timer1TXDataBit 405 | sjmp timer1TXRelease 406 | sjmp timer1TXDataBit 407 | sjmp timer1TXRelease 408 | sjmp timer1TXDataBit 409 | sjmp timer1TXRelease 410 | sjmp timer1TXDataBit 411 | sjmp timer1TXRelease 412 | sjmp timer1TXDataBit 413 | sjmp timer1TXRelease 414 | sjmp timer1TXStopBit 415 | sjmp timer1TXRelease 416 | sjmp timer1TXStop 417 | 418 | ; ----------------- 419 | timer1TXRelease: 420 | ; -- output of the data bit 421 | ; note: PCXTNextBitF is computed in the previous step due to timing issues 422 | ; low-delay-output is important here 423 | ; data bit output 424 | mov c,PCXTNextBitF 425 | mov p3.4,c 426 | nop 427 | nop 428 | nop 429 | nop 430 | nop 431 | nop 432 | nop 433 | nop 434 | ; set clock line 435 | setb p3.2 436 | sjmp timer1TXEnd 437 | 438 | ; ----------------- 439 | timer1TXStart1Bit: 440 | clr p3.2 441 | nop 442 | nop 443 | nop 444 | nop 445 | nop 446 | nop 447 | nop 448 | nop 449 | setb p3.4 450 | sjmp timer1TXEnd 451 | 452 | ; ----------------- 453 | timer1TXStart2Bit: 454 | setb PCXTNextBitF ; 1 455 | nop 456 | nop 457 | nop 458 | nop 459 | call nop20 460 | clr p3.2 461 | sjmp timer1TXEnd 462 | 463 | ; ----------------- 464 | timer1TXDataBit: 465 | ; -- set data bit 0-7 and pull down clock line 466 | mov a,PCXTTXBuf ; 1 467 | rrc a ; 1 ; next data bit to c 468 | mov PCXTNextBitF,c ; 2 469 | mov PCXTTXBuf,a ; 1 470 | call nop20 471 | clr p3.2 472 | sjmp timer1TXEnd 473 | 474 | ; ----------------- 475 | timer1TXStopBit: 476 | clr PCXTNextBitF 477 | nop 478 | nop 479 | nop 480 | nop 481 | call nop20 482 | clr p3.2 483 | sjmp timer1TXEnd 484 | 485 | ; ----------------- 486 | timer1TXStop: 487 | ; -- stop timer auto-reload 488 | clr tr1 489 | clr PCXTActiveF 490 | setb p3.5 491 | setb p3.3 ; release PS2-Clock to allow PS2-Communication 492 | ; sjmp timer1TXEnd 493 | 494 | ; --------------------------- done 495 | timer1TXEnd: 496 | ; -- done 497 | inc PCXTBitCount ; 1 498 | pop psw ; 2 499 | pop acc ; 2 500 | reti ; 2 501 | 502 | ;---------------------------------------------------------- 503 | ; AT/PS2 to PC/XT translaton table 504 | ;---------------------------------------------------------- 505 | ATPS22PCXTxlt0 DB 0h, 43h, 0h, 3fh, 3dh, 3bh, 3ch, 58h, 0h, 44h, 42h, 40h, 3eh, 0fh, 0h, 0h 506 | ATPS22PCXTxlt1 DB 0h, 38h, 2ah, 0h, 1dh, 10h, 02h, 0h, 0h, 0h, 2ch, 1fh, 1eh, 11h, 03h, 0h 507 | ATPS22PCXTxlt2 DB 0h, 2eh, 2dh, 20h, 12h, 05h, 04h, 0h, 0h, 39h, 2fh, 21h, 14h, 13h, 06h, 0h 508 | ATPS22PCXTxlt3 DB 0h, 31h, 30h, 23h, 22h, 15h, 07h, 0h, 0h, 0h, 32h, 24h, 16h, 08h, 09h, 0h 509 | ATPS22PCXTxlt4 DB 0h, 33h, 25h, 17h, 18h, 0bh, 0ah, 0h, 0h, 34h, 35h, 26h, 27h, 19h, 0ch, 0h 510 | ATPS22PCXTxlt5 DB 0h, 0h, 28h, 0h, 1ah, 0dh, 0h, 0h, 3ah, 36h, 1ch, 1bh, 0h, 29h, 0h, 0h 511 | ATPS22PCXTxlt6 DB 0h, 2bh, 0h, 0h, 0h, 0h, 0eh, 0h, 0h, 4fh, 0h, 4bh, 47h, 0h, 0h, 0h 512 | ATPS22PCXTxlt7 DB 52h, 53h, 50h, 4ch, 4dh, 48h, 01h, 45h, 57h, 4eh, 51h, 4ah, 0h, 49h, 46h, 0h 513 | ATPS22PCXTxlt8 DB 0h, 0h, 0h, 41h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h 514 | ATPS22PCXTxlt9 DB 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h 515 | ATPS22PCXTxlta DB 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h 516 | ATPS22PCXTxltb DB 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h 517 | ATPS22PCXTxltc DB 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h 518 | ATPS22PCXTxltd DB 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h 519 | ATPS22PCXTxlte DB 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h 520 | ATPS22PCXTxltf DB 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h 521 | 522 | ;---------------------------------------------------------- 523 | ; AT/PS2 to PC/XT translaton table for 0xE0-Escaped scancodes 524 | ; Note: Ctrl-R (E014h) is mapped like Ctrl-L (14h) 525 | ;---------------------------------------------------------- 526 | ATPS22PCXTxltE0 DB 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h 527 | ATPS22PCXTxltE1 DB 0h, 38h, 0h, 0h, 1dh, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h 528 | ATPS22PCXTxltE2 DB 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h 529 | ATPS22PCXTxltE3 DB 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h 530 | ATPS22PCXTxltE4 DB 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h 531 | ATPS22PCXTxltE5 DB 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 1ch, 0h, 0h, 0h, 0h, 0h 532 | ATPS22PCXTxltE6 DB 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 4fh, 0h, 4bh, 47h, 0h, 0h, 0h 533 | ATPS22PCXTxltE7 DB 52h, 53h, 50h, 0h, 4dh, 48h, 0h, 0h, 0h, 0h, 51h, 0h, 37h, 49h, 0h, 0h 534 | ATPS22PCXTxltE8 DB 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h 535 | ATPS22PCXTxltE9 DB 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h 536 | ATPS22PCXTxltEa DB 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h 537 | ATPS22PCXTxltEb DB 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h 538 | ATPS22PCXTxltEc DB 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h 539 | ATPS22PCXTxltEd DB 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h 540 | ATPS22PCXTxltEe DB 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h 541 | ATPS22PCXTxltEf DB 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h, 0h 542 | 543 | ;---------------------------------------------------------- 544 | ; Helper, translate normal AT/PS2 to PCXT scancode 545 | ; input: dptr: table address, a: AT/PS2 scancode 546 | ;---------------------------------------------------------- 547 | ATPS22PCXT: 548 | jb PS2RXEscapeF,ATPS22PCXTEsc 549 | 550 | ; --- normal single scancodes 551 | mov dptr,#ATPS22PCXTxlt0 552 | movc a,@a+dptr 553 | sjmp ATPS22PCXTEnd 554 | 555 | ; --- 0xE0-escaped scancodes 556 | ATPS22PCXTEsc: 557 | clr PS2RXEscapeF 558 | mov dptr,#ATPS22PCXTxltE0 559 | movc a,@a+dptr 560 | ; sjmp ATPS22PCXTEnd 561 | 562 | ATPS22PCXTEnd: 563 | ret 564 | 565 | ;---------------------------------------------------------- 566 | ; ring buffer insertion helper. Input Data comes in r2 567 | ;---------------------------------------------------------- 568 | RingBuf1CheckInsert: 569 | ; check for ring buffer overflow 570 | mov a,RingBuf1PtrOut 571 | setb c 572 | subb a,RingBuf1PtrIn 573 | anl a,#RingBuf1SizeMask 574 | jz RingBuf1Full 575 | 576 | ; some space left, insert data 577 | mov a,RingBuf1PtrIn 578 | add a,#RingBuf1 579 | mov r0,a 580 | mov a,r2 581 | mov @r0,a 582 | 583 | ; increment pointer 584 | inc RingBuf1PtrIn 585 | anl RingBuf1PtrIn,#RingBuf1SizeMask 586 | ret 587 | 588 | RingBuf1Full: 589 | ; error routine 590 | clr p1.7 591 | ret 592 | 593 | ;---------------------------------------------------------- 594 | ; ring buffer insertion helper. Input Data comes in r2 595 | ;---------------------------------------------------------- 596 | RingBuf2CheckInsert: 597 | ; check for ring buffer overflow 598 | mov a,RingBuf2PtrOut 599 | setb c 600 | subb a,RingBuf2PtrIn 601 | anl a,#RingBuf2SizeMask 602 | jz RingBuf2Full 603 | 604 | ; some space left, insert data 605 | mov a,RingBuf2PtrIn 606 | add a,#RingBuf2 607 | mov r0,a 608 | mov a,r2 609 | mov @r0,a 610 | 611 | ; increment pointer 612 | inc RingBuf2PtrIn 613 | anl RingBuf2PtrIn,#RingBuf2SizeMask 614 | ret 615 | 616 | RingBuf2Full: 617 | ; error routine 618 | clr p1.4 619 | ret 620 | 621 | ;---------------------------------------------------------- 622 | ; Get received data and translate it into the ring buffer 623 | ;---------------------------------------------------------- 624 | TranslateToBuf: 625 | mov a,RawBuf 626 | ; --- check for 0xFA ACK-Code 627 | cjne a,#0FAh,TranslateToBufNotFA ; 628 | clr PS2RXCompleteF 629 | setb PS2RXAckF 630 | ljmp TranslateToBufEnd 631 | TranslateToBufNotFA: 632 | ; --- check for 0xFE Resend-Code 633 | cjne a,#0FEh,TranslateToBufNotFE ; 634 | clr PS2RXCompleteF 635 | setb PS2ResendF 636 | ljmp TranslateToBufEnd 637 | TranslateToBufNotFE: 638 | ; ------ check for Escape codes 639 | ; --- check for 0xF0 release / break code 640 | cjne a,#0F0h,TranslateToBufNotF0 ; 641 | clr PS2RXCompleteF 642 | setb PS2RXBreakF 643 | ljmp TranslateToBufEnd 644 | TranslateToBufNotF0: 645 | ; --- check for 0xE0 ESC code 646 | cjne a,#0E0h,TranslateToBufNotE0 ; esc code 647 | clr PS2RXCompleteF 648 | setb PS2RXEscapeF 649 | ljmp TranslateToBufEnd 650 | TranslateToBufNotE0: 651 | 652 | ; --- restore new scancode 653 | mov a,RawBuf 654 | 655 | ; keyboard disabled? 656 | ; jb FooBarDisableF,TranslateToBufEnd 657 | 658 | ; --- translate 659 | clr PS2RXCompleteF 660 | call ATPS22PCXT 661 | 662 | ; --- dont insert zeros 663 | jz TranslateToBufClrEnd 664 | 665 | ; --- insert 666 | TranslateToBufInsert: 667 | ; restore make/break bit 7 668 | mov c,PS2RXBreakF 669 | mov acc.7,c 670 | clr c 671 | 672 | ; insert into buf 673 | mov r2, a 674 | call RingBuf1CheckInsert 675 | 676 | TranslateToBufClrEnd: 677 | clr PS2RXBreakF 678 | clr PS2RXEscapeF 679 | 680 | TranslateToBufEnd: 681 | ret 682 | 683 | ;---------------------------------------------------------- 684 | ; Send data from the ring buffer 685 | ;---------------------------------------------------------- 686 | ; -- send ring buffer contents 687 | Buf1TX: 688 | ; -- check if AT/PS2 bus or PCXT-transmit is active 689 | jb PS2ActiveF,Buf1TXEnd 690 | jb PCXTActiveF,Buf1TXEnd 691 | 692 | ; check if data is present in the ring buffer 693 | clr c 694 | mov a,RingBuf1PtrIn 695 | subb a,RingBuf1PtrOut 696 | anl a,#RingBuf1SizeMask 697 | jz Buf1TXEnd 698 | 699 | ; -- get data from buffer 700 | mov a,RingBuf1PtrOut 701 | add a,#RingBuf1 702 | mov r0,a 703 | mov a,@r0 704 | 705 | ; -- send data 706 | setb p3.5 707 | clr p3.3 ; pull down PS2-Clock to inhibit PS2-Communication 708 | mov PCXTBitCount,#0 709 | mov PCXTTXBuf,a ; 8 data bits 710 | call timer1_init_45mus 711 | 712 | ; -- increment output pointer 713 | inc RingBuf1PtrOut 714 | anl RingBuf1PtrOut,#RingBuf1SizeMask 715 | 716 | Buf1TXEnd: 717 | ret 718 | 719 | ;---------------------------------------------------------- 720 | ; Send data from the ring buffer to the keyboard 721 | ;---------------------------------------------------------- 722 | Buf2TX: 723 | ; -- check if AT/PS2 bus is active 724 | jb PS2ActiveF,Buf2TXEnd 725 | 726 | ; -- allow Device-to-Host communication 727 | jnb TimeoutF,Buf2TXEnd 728 | 729 | ; ; -- check for resend-flag 730 | ; jnb PS2ResendF,Buf2TXNoResend 731 | ; dec PS2ResendTTL 732 | ; mov a,PS2ResendTTL 733 | ; jnz Buf2TXGo 734 | ; 735 | ; ; -- Resend-TTL expired, reset the keyboard, FIXME 736 | ; mov RingBuf2PtrIn,#0 737 | ; mov RingBuf2PtrOut,#0 738 | ; mov PS2ResendBuf,#0ffh 739 | ; sjmp Buf2TXGo 740 | 741 | ; -- check if data is present in the ring buffer 742 | Buf2TXNoResend: 743 | mov PS2ResendTTL,#08h 744 | clr c 745 | mov a,RingBuf2PtrIn 746 | subb a,RingBuf2PtrOut 747 | anl a,#RingBuf2SizeMask 748 | jz Buf2TXEnd 749 | 750 | Buf2TXGo: 751 | ; -- check if AT/PS2 bus is active 752 | jb PS2ActiveF,Buf2TXEnd 753 | 754 | ; -- init the bus 755 | clr tr0 756 | clr ex0 ; may diable input interrupt here 757 | clr p3.3 ; clock down 758 | 759 | ; -- wait 40mus 760 | call timer0_init_40mus 761 | Buf2TXWait1: 762 | jnb MiscSleepF,Buf2TXWait1 763 | clr p3.5 ; data down 764 | 765 | ; -- wait 40mus 766 | call timer0_init_40mus 767 | Buf2TXWait2: 768 | jnb MiscSleepF,Buf2TXWait2 769 | 770 | ; -- timeout timer 771 | call timer0_init 772 | 773 | ; jb PS2ResendF,Buf2TXResend 774 | ; -- get data from buffer 775 | mov a,RingBuf2PtrOut 776 | add a,#RingBuf2 777 | mov r0,a 778 | mov a,@r0 779 | mov PS2TXBitBuf,a 780 | mov PS2ResendBuf,a 781 | sjmp Buf2TXSend 782 | 783 | ;Buf2TXResend: 784 | ; ; -- resend last byte 785 | ; clr PS2ResendF 786 | ; mov a,PS2ResendBuf 787 | ; mov PS2TXBitBuf,a 788 | 789 | Buf2TXSend: 790 | ; -- init int handler 791 | mov r7,#0 792 | setb PS2HostToDevF 793 | setb ex0 794 | setb p3.3 ; clock up 795 | ; -- keyboard should start sending clocks now 796 | Buf2TXWait3: 797 | jb PS2HostToDevF,Buf2TXWait3 798 | setb p3.5 ; data up 799 | 800 | ; -- wait 1ms 801 | call timer0_init_1ms 802 | ; call timer0_init_40mus 803 | Buf2TXWait4: 804 | jnb MiscSleepF,Buf2TXWait4 805 | setb p3.3 ; clock up 806 | 807 | ; -- output to LED 808 | ; mov a,PS2TXBitBuf 809 | ; cpl a 810 | ; mov p1,a 811 | 812 | ; -- increment output pointer 813 | inc RingBuf2PtrOut 814 | anl RingBuf2PtrOut,#RingBuf2SizeMask 815 | 816 | ; -- restore normal timeout 817 | call timer0_init 818 | setb tr0 819 | setb ex0 ; may diable input interrupt here 820 | 821 | Buf2TXEnd: 822 | ret 823 | 824 | ;---------------------------------------------------------- 825 | ; helper, waste 20 cpu cycles 826 | ; note: call and return takes 4 cycles 827 | ;---------------------------------------------------------- 828 | nop20: 829 | nop 830 | nop 831 | nop 832 | nop 833 | nop 834 | nop 835 | 836 | nop 837 | nop 838 | nop 839 | nop 840 | nop 841 | nop 842 | nop 843 | nop 844 | nop 845 | nop 846 | 847 | ret 848 | 849 | ;---------------------------------------------------------- 850 | ; init timer 0 for AT/PS2 interval timing, timeout=1ms 851 | ;---------------------------------------------------------- 852 | timer0_init: 853 | anl tmod, #0f0h ; clear all lower bits 854 | orl tmod, #01h ; M0,M1, bit0,1 in TMOD, timer 0 in mode 1, 16bit 855 | 856 | mov th0, #interval_th_11_bit 857 | mov tl0, #interval_tl_11_bit 858 | 859 | clr TimeoutF 860 | clr TFModF 861 | setb et0 ; (IE.3) enable timer 0 interrupt 862 | setb tr0 ; timer 0 run 863 | ret 864 | 865 | ;---------------------------------------------------------- 866 | ; init timer 0 for interval timing 867 | ; need 40-50mus intervals 868 | ;---------------------------------------------------------- 869 | timer0_init_40mus: 870 | anl tmod, #0f0h ; clear all lower bits 871 | orl tmod, #01h ; M0,M1, bit0,1 in TMOD, timer 0 in mode 1, 16bit 872 | 873 | mov th0, #interval_th_40u_24M 874 | mov tl0, #interval_tl_40u_24M 875 | 876 | setb TFModF 877 | clr MiscSleepF 878 | setb et0 ; (IE.3) enable timer 0 interrupt 879 | setb tr0 ; timer 0 run 880 | ret 881 | 882 | ;---------------------------------------------------------- 883 | ; init timer 0 for interval timing 884 | ; need 1ms 885 | ;---------------------------------------------------------- 886 | timer0_init_1ms: 887 | anl tmod, #0f0h ; clear all lower bits 888 | orl tmod, #01h ; M0,M1, bit0,1 in TMOD, timer 0 in mode 1, 16bit 889 | 890 | mov th0, #interval_th_1m_24M 891 | mov tl0, #interval_tl_1m_24M 892 | 893 | setb TFModF 894 | clr MiscSleepF 895 | setb et0 ; (IE.3) enable timer 0 interrupt 896 | setb tr0 ; timer 0 run 897 | ret 898 | 899 | ;---------------------------------------------------------- 900 | ; init timer 1 for PC/XT for interval timing with 2*45mus 901 | ;---------------------------------------------------------- 902 | timer1_init_45mus: 903 | anl tmod, #0fh ; clear all lower bits 904 | orl tmod, #20h ; 8-bit Auto-Reload Timer, mode 2 905 | 906 | mov th1, #interval_t0_45u_24M 907 | mov tl1, #interval_t0_45u_24M 908 | 909 | setb PCXTActiveF 910 | 911 | setb et1 ; (IE.3) enable timer 1 interrupt 912 | setb tr1 ; timer 1 run 913 | ret 914 | 915 | ;---------------------------------------------------------- 916 | ; Id 917 | ;---------------------------------------------------------- 918 | RCSId DB "$KbdBabel: kbdbabel_ps2_pcxt_8051.asm,v 1.4 2009/03/31 09:48:25 akurz Exp $" 919 | 920 | ;---------------------------------------------------------- 921 | ; main 922 | ;---------------------------------------------------------- 923 | Start: 924 | ; -- init the stack 925 | mov sp,#StackBottom 926 | ; -- init UART and timer0/1 927 | acall timer0_init 928 | clr TFModF 929 | 930 | ; -- enable interrupts int0 931 | setb ex1 ; external interupt 1 enable 932 | setb it1 ; falling edge trigger for int 1 933 | setb ea 934 | 935 | ; -- clear all flags 936 | mov B20,#0 937 | mov B21,#0 938 | mov B22,#0 939 | mov B23,#0 940 | 941 | ; -- set PS2 clock and data line 942 | setb p3.3 943 | setb p3.5 944 | 945 | ; -- init the ring buffers 946 | mov RingBuf1PtrIn,#0 947 | mov RingBuf1PtrOut,#0 948 | mov RingBuf2PtrIn,#0 949 | mov RingBuf2PtrOut,#0 950 | 951 | ; ---------------- 952 | Loop: 953 | ; -- check AT/PS2 receive status 954 | jb PS2RXCompleteF,LoopProcessATPS2Data 955 | 956 | ; -- loop PCXT-TX is active 957 | jb PCXTActiveF, Loop 958 | 959 | ; send data to computer 960 | call Buf1TX 961 | 962 | ; send data to keyboard 963 | call Buf2TX 964 | 965 | ; -- loop 966 | sjmp Loop 967 | 968 | ;---------------------------------------------------------- 969 | ; helpers for the main loop 970 | ;---------------------------------------------------------- 971 | ; ---------------- 972 | LoopProcessATPS2Data: 973 | ; -- AT/PS2 data received, process the received scancode into output ring buffer 974 | call TranslateToBuf 975 | sjmp Loop 976 | 977 | ;---------------------------------------------------------- 978 | ; Still space on the ROM left for the license? 979 | ;---------------------------------------------------------- 980 | LIC01 DB " Copyright 2009 by Alexander Kurz" 981 | LIC02 DB " --- " 982 | ;GPL_S1 DB " This program is free software; licensed under the terms of the GNU GPL V3" 983 | GPL01 DB " This program is free software; you can redistribute it and/or modify" 984 | GPL02 DB " it under the terms of the GNU General Public License as published by" 985 | GPL03 DB " the Free Software Foundation; either version 3, or (at your option)" 986 | GPL04 DB " any later version." 987 | GPL05 DB " --- " 988 | GPL06 DB " This program is distributed in the hope that it will be useful," 989 | GPL07 DB " but WITHOUT ANY WARRANTY; without even the implied warranty of" 990 | GPL08 DB " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the" 991 | GPL09 DB " GNU General Public License for more details." 992 | GPL10 DB " " 993 | ; ---------------- 994 | end 995 | 996 | -------------------------------------------------------------------------------- /kbdbabel-ps2-dec/kbdbabel_pcxt_dec_8051.asm: -------------------------------------------------------------------------------- 1 | ; --------------------------------------------------------------------- 2 | ; PC/XT to DEC LK201/LK401 keyboard transcoder for 8051 type processors. 3 | ; For shure, nobody will need this. Otherwise, please tell me. 4 | ; Just the development helper between pc-at and at-dec. 5 | ; 6 | ; $KbdBabel: kbdbabel_pcxt_dec_8051.asm,v 1.1 2007/04/17 10:04:51 akurz Exp $ 7 | ; 8 | ; Clock/Crystal: 18.432MHz. 9 | ; 3.6864MHz or 7.3728 may do as well. 10 | ; 11 | ; PC/XT Keyboard connect: 12 | ; This two pins need externals 4.7k resistors as pullup. 13 | ; DATA - p3.4 (Pin 14 on DIL40, Pin 8 on AT89C2051 PDIP20) 14 | ; CLOCK - p3.2 (Pin 12 on DIL40, Pin 6 on AT89C2051 PDIP20, Int 0) 15 | ; 16 | ; DEC Host connect: 17 | ; RS232 level using a MAX232-IC 18 | ; RxD - p3.0 (Pin 10 on DIL40, Pin 2 on AT89C2051 PDIP20) 19 | ; TxD - p3.1 (Pin 11 on DIL40, Pin 3 on AT89C2051 PDIP20) 20 | ; 21 | ; LED-Output connect: 22 | ; LEDs are connected with 220R to Vcc 23 | ; ScrollLock - p1.7 (Pin 8 on DIL40, Pin 19 on AT89C2051 PDIP20) 24 | ; CapsLock - p1.6 (Pin 7 on DIL40, Pin 18 on AT89C2051 PDIP20) 25 | ; NumLock - p1.5 (Pin 6 on DIL40, Pin 17 on AT89C2051 PDIP20) 26 | ; Wait - p1.4 (Pin 5 on DIL40, Pin 16 on AT89C2051 PDIP20) 27 | ; TX buffer full- p1.3 28 | ; numlockfeature- p1.2 29 | ; 1/3 Volume - p1.1 30 | ; 1/9 Volume - p1.0 31 | ; Buzzer - p3.7 (Pin 11 on AT89C2051 PDIP20) 32 | ; 33 | ; Build: 34 | ; $ asl kbdbabel_pcxt_dec_8051.asm -o kbdbabel_pcxt_dec_8051.p 35 | ; $ p2bin -l \$ff kbdbabel_pcxt_dec_8051 36 | ; write kbdbabel_pcxt_dec_8051.bin on an empty 27C256 or AT89C2051 37 | ; 38 | ; Copyright 2006 by Alexander Kurz 39 | ; 40 | ; This is free software. 41 | ; You may copy and redistibute this software according to the 42 | ; GNU general public license version 2 or any later verson. 43 | ; 44 | ; --------------------------------------------------------------------- 45 | 46 | cpu 8052 47 | include stddef51.inc 48 | 49 | ;---------------------------------------------------------- 50 | ; Variables / Memory layout 51 | ;---------------------------------------------------------- 52 | ;------------------ bits 53 | PCRXBitF bit 20h.0 ; RX-bit-buffer 54 | PCRXCompleteF bit 20h.1 ; full and correct byte-received 55 | PCRXActiveF bit 20h.2 ; receive in progress flag 56 | PCXTBreakF bit 20h.3 ; Release/Break-Code flag 57 | ATTXMasqF bit 20h.4 ; TX-AT-Masq-Char-Bit (send two byte scancode) 58 | ATTXParF bit 20h.5 ; TX-AT-Parity bit 59 | ATTFModF bit 20h.6 ; Timer modifier: alarm clock or clock driver 60 | MiscSleepF bit 20h.7 ; sleep timer active flag 61 | ATCommAbort bit 21h.0 ; AT communication aborted 62 | ATHostToDevIntF bit 21h.1 ; host-do-device init flag triggered by ex1 / unused. 63 | ATHostToDevF bit 21h.2 ; host-to-device flag for timer 64 | ATTXActiveF bit 21h.3 ; AT TX active 65 | ATCmdReceivedF bit 21h.4 ; full and correct AT byte-received 66 | ATCmdResetF bit 21h.5 ; reset 67 | LKCmdClrLedF bit 21h.6 ; LK command processing: clear LED 68 | LKCmdSetLedF bit 21h.7 ; LK command processing: set LED 69 | ATKbdDisableF bit 22h.0 ; Keyboard disable 70 | LKModeNumLock_ bit 22h.1 ; emulated NumLock-Mode, for arrow-keys on PC-Keyboard 71 | PCXTTypematicF bit 22h.2 ; typematic scancode received 72 | 73 | LKModSL bit 23h.0 ; LK modifier state storage: left shift 74 | LKModSR bit 23h.1 ; LK modifier state storage: right shift 75 | LKModAL bit 23h.2 ; LK modifier state storage: left alt 76 | LKModAR bit 23h.3 ; LK modifier state storage: right alt 77 | LKModC bit 23h.4 ; LK modifier state storage: ctrl 78 | 79 | ;------------------ octets 80 | LKModAll equ 23h ; collective access to stored LK modifier flags 81 | KbBitBufL equ 24h 82 | KbBitBufH equ 25h 83 | KbClockMin equ 26h 84 | KbClockMax equ 27h 85 | ATBitCount equ 28h ; AT scancode TX counter 86 | LKLEDBuf equ 29h ; must be bit-addressable 87 | ATLEDBuf equ 2ah ; must be bit-addressable 88 | RawBuf equ 30h ; raw PC/XT scancode 89 | OutputBuf equ 31h ; AT scancode 90 | TXBuf equ 32h ; AT scancode TX buffer 91 | RingBufPtrIn equ 33h ; Ring Buffer write pointer, starting with zero 92 | RingBufPtrOut equ 34h ; Ring Buffer read pointer, starting with zero 93 | DECRXBuf equ 35h ; DEC host-to-dev buffer 94 | ATRXCount equ 36h 95 | DECBeepPCL equ 37h ; Beep pulse counter, 8 low bits 96 | DECBeepPCH equ 38h ; Beep pulse counter, more bits 97 | PCXTLastBuf equ 39h ; last scancode received 98 | ;KbClockIntBuf equ 33h 99 | 100 | ;------------------ arrays 101 | RingBuf equ 40h 102 | RingBufSizeMask equ 0fh ; 16 byte ring-buffer size 103 | 104 | ;------------------ stack 105 | StackBottom equ 50h ; the stack 106 | 107 | ;---------------------------------------------------------- 108 | ; misc constants 109 | ;---------------------------------------------------------- 110 | ;------------------ bitrates generated with timer 1 in 8 bit mode 111 | ; 1200BPS @3.6864MHz -> tl1 and th1 = #240 with SMOD=1 ; (256-2*3686.4/384/1.2) 112 | uart_t1_1200_3686_4k equ 240 113 | 114 | ; 1200BPS @7.3728MHz -> tl1 and th1 = #224 with SMOD=1 ; (256-2*7372.8/384/1.2) 115 | uart_t1_1200_7372_8k equ 224 116 | 117 | ; 1200BPS @11.0592MHz -> tl1 and th1 = #208 with SMOD=1 ; (256-2*11059.2/384/1.2) 118 | uart_t1_1200_11059_2k equ 208 119 | 120 | ; 1200BPS @14.7456MHz -> tl1 and th1 = #192 with SMOD=1 ; (256-2*14745.6/384/1.2) 121 | uart_t1_1200_14745_6k equ 192 122 | 123 | ; 1200BPS @18.432MHz -> tl1 and th1 = #176 with SMOD=1 ; (256-2*18432/384/1.2) 124 | uart_t1_1200_18432k equ 176 125 | 126 | ; 4800BPS @11.0592MHz -> tl1 and th1 = #244 with SMOD=1 ; (256-2*11059.2/384/4.8) 127 | uart_t1_4800_11059_2k equ 244 128 | 129 | ; 4800BPS @18.432MHz -> tl1 and th1 = #236 with SMOD=1 ; (256-2*18432/384/4.8) 130 | uart_t1_4800_18432k equ 236 131 | 132 | ; 9600BPS @18.432MHz -> tl1 and th1 = #246 with SMOD=1 ; (256-2*18432/384/9.6) 133 | uart_t1_9600_18432k equ 246 134 | 135 | ;------------------ bitrates generated with timer 2 136 | ; 9600 BPS at 18.432MHz -> RCAP2H,RCAP2L=#0FFh,#0c4h ; (256-18432/32/9.6) 137 | uart_t2h_9600_18432k equ 255 138 | uart_t2l_9600_18432k equ 196 139 | 140 | ;------------------ AT scancode timing intervals generated with timer 0 in 8 bit mode 141 | ; 50mus@11.0592MHz -> th0 and tl0=209 or 46 processor cycles ; (256-11059.2*0.05/12) 142 | interval_t0_50u_11059_2k equ 209 143 | 144 | ; 50mus@11.0592MHz -> th0 and tl0=214 or 41 processor cycles ; (256-11059.2*0.045/12) 145 | interval_t0_45u_11059_2k equ 214 146 | 147 | ; 45mus@12.000MHz -> th0 and tl0=211 or 45 processor cycles ; (256-12000*0.045/12) 148 | interval_t0_45u_12M equ 211 149 | 150 | ; 40mus@18.432MHz -> th0 and tl0=194 or 61 processor cycles ; (256-18432*0.04/12) 151 | interval_t0_40u_18432k equ 194 152 | 153 | ; 40mus@24.000MHz -> th0 and tl0=176 or 80 processor cycles ; (256-24000*0.04/12) 154 | interval_t0_40u_24M equ 176 155 | 156 | ;------------------ AT RX timeout values using timer 0 in 16 bit mode 157 | ; --- 18.432MHz 158 | ; 20ms@18.432MHz -> th0,tl0=0c4h,00h ; (65536-18432*20/12) 159 | interval_th_20m_18432k equ 136 160 | interval_tl_20m_18432k equ 0 161 | 162 | ; 10ms@18.432MHz -> th0,tl0=0c4h,00h ; (65536-18432*10/12) 163 | interval_th_10m_18432k equ 196 164 | interval_tl_10m_18432k equ 0 165 | 166 | ; 1ms@18.432MHz -> th0,tl0=0fah,00h ; (65536-18432*1/12) 167 | interval_th_1m_18432k equ 250 168 | interval_tl_1m_18432k equ 0 169 | 170 | ; 0.13ms@18.432MHz -> th0,tl0=0ffh,38h ; (65536-18432*0.13/12) 171 | interval_th_130u_18432k equ 255 172 | interval_tl_130u_18432k equ 56 173 | 174 | ; --- 11.0592MHz 175 | ; 20ms@11.0592MHz -> th0,tl0=0b8h,00h ; (65536-11059.2*20/12) 176 | interval_th_20m_11059_2k equ 184 177 | interval_tl_20m_11059_2k equ 0 178 | 179 | ; 10ms@11.0592MHz -> th0,tl0=0dch,00h ; (65536-11059.2*10/12) 180 | interval_th_10m_11059_2k equ 220 181 | interval_tl_10m_11059_2k equ 0 182 | 183 | ; 1ms@11.0592MHz -> th0,tl0=0fch,66h ; (65536-11059.2*1/12) 184 | interval_th_1m_11059_2k equ 252 185 | interval_tl_1m_11059_2k equ 42 186 | 187 | ; 0.13ms@11.0592MHz -> th0,tl0=0ffh,88h ; (65536-11059.2*0.13/12) 188 | interval_th_130u_11059_2k equ 255 189 | interval_tl_130u_11059_2k equ 136 190 | 191 | ; --- 24.000MHz 192 | ; 20ms@24.000MHz -> th0,tl0=63h,0c0h ; (65536-24000*20/12) 193 | interval_th_20m_24M equ 99 194 | interval_tl_20m_24M equ 192 195 | 196 | ; 10ms@24.000MHz -> th0,tl0=0B1h,E0h ; (65536-24000*10/12) 197 | interval_th_10m_24M equ 177 198 | interval_tl_10m_24M equ 224 199 | 200 | ; 1ms@24.000MHz -> th0,tl0=0f8h,30h ; (65536-24000*1/12) 201 | interval_th_1m_24M equ 248 202 | interval_tl_1m_24M equ 48 203 | 204 | ; 0.128ms@24.000MHz -> th0,tl0=0ffh,00h ; (65536-24000*.128/12) 205 | interval_th_128u_24M equ 255 206 | interval_tl_128u_24M equ 0 207 | 208 | ;------------------ PCXT RX timeout and interval diagnosis using timer 0 in 16 bit mode 209 | ; --- 11 bit for timing diagnosis 210 | ; 1.02ms @24.000MHz ; 2048*12/24000 211 | ; 1.33ms @18.432MHz ; 2048*12/18432 212 | ; 2.22ms @11.0592MHz ; 2048*12/11059.2 213 | ; 3.33ms @7.3728MHz ; 2048*12/7372.8 214 | interval_th_11_bit equ 0f8h 215 | interval_tl_11_bit equ 0 216 | 217 | ; --- 10 bit for timing diagnosis 218 | ; 1.1ms @11.0592MHz ; 1024*12/11059.2 219 | ; 1.7ms @7.3728MHz ; 1024*12/7372.8 220 | interval_th_10_bit equ 0fch 221 | interval_tl_10_bit equ 0 222 | 223 | ; --- 9 bit for timing diagnosis 224 | ; 0.83ms @7.3728MHz ; 512*12/7372.8 225 | ; 1.7ms @3.6864MHz ; 512*12/3686.4 226 | interval_th_9_bit equ 0feh 227 | interval_tl_9_bit equ 0 228 | 229 | ;---------------------------------------------------------- 230 | ; start 231 | ;---------------------------------------------------------- 232 | org 0 ; cold start 233 | ljmp Start 234 | ;---------------------------------------------------------- 235 | ; interrupt handlers 236 | ;---------------------------------------------------------- 237 | ;---------------------------- 238 | ; int 0, connected to keyboard clock line. 239 | ; With a raising signal on the clock line there are 15mus 240 | ; left to read the data line. Using a 3.6864 MHz Crystal 241 | ; this will be less than 5 processor cycles. 242 | ;---------------------------- 243 | org 03h ; external interrupt 0 244 | jnb P3.4, HandleInt0 ; this is time critical 245 | setb PCRXBitF 246 | ljmp HandleInt0 247 | ;---------------------------- 248 | org 0bh ; handle TF0 249 | ljmp HandleTF0 250 | ;---------------------------- 251 | ; org 13h ; Int 1 252 | ; ljmp HandleInt1 253 | ;---------------------------- 254 | ; org 1bh ; handle TF1 255 | ; ljmp HandleTF1 256 | ;---------------------------- 257 | ; org 23h ; RI/TI 258 | ; ljmp HandleRITI 259 | ;---------------------------- 260 | ; org 2bh ; handle TF2 261 | ; ljmp HandleTF2 262 | 263 | org 033h 264 | ;---------------------------------------------------------- 265 | ; int0 handler: 266 | ; read one data bit triggered by the keyboard clock line 267 | ; rotate bit into KbBitBufH, KbBitBufL. 268 | ; Last clock sample interval is stored in r6 269 | ; rotate bit into 22h, 23h. 270 | ; Num Bits is in r7 271 | ; buffer: r5 272 | ;---------------------------------------------------------- 273 | HandleInt0: 274 | push acc 275 | push psw 276 | 277 | ; receive in progress flag 278 | setb PCRXActiveF 279 | ; --------------------------- diag: check if PCXT-RX happens during AT-TX 280 | ; clr p1.7 ; @@@@@@@@@@ FIXME 281 | ; check if flag is set 282 | jnb ATTXActiveF,interCharFlagOk 283 | ; clr p1.4 ; @@@@@@@@@@ FIXME 284 | sjmp interCharTestEnd 285 | interCharFlagOk: 286 | ; setb p1.4 ; @@@@@@@@@@ FIXME 287 | interCharTestEnd: 288 | ; --------------------------- get and save data samples 289 | ; -- write to mem, first 8 bits 290 | mov c,PCRXBitF ; new bit 291 | mov a,KbBitBufL 292 | rrc a 293 | mov KbBitBufL,a 294 | 295 | ; -- write to mem, upper bits 296 | mov a,KbBitBufH 297 | rrc a 298 | mov KbBitBufH,a 299 | 300 | ; -- diag: write data bits to LED-Port 301 | ; mov a,KbBitBufL 302 | ; xrl a,0FFh 303 | ; mov p1,a 304 | 305 | ; -- reset bit buffer 306 | clr PCRXBitF 307 | 308 | ; --------------------------- get and save clock timings 309 | ; this is an optional extra-check for the received data. 310 | ; The PC/XT-Protocol consists of 8 equally spaced clock cycles proceeded by 311 | ; one clock cycle of double length. These intervals are checked here. 312 | ; For diagnosis purposes the timing samples can be send via serial line. 313 | ; -- diag: time interval buffer address KbClockIntBuf 314 | ; mov a,r7 315 | ; add a,#KbClockIntBuf 316 | ; mov r1,a 317 | 318 | ; -- save and restart timer 319 | ; stop timer 0 320 | clr tr0 321 | 322 | ; 11 bit from 16-bit timer. 323 | mov a,th0 324 | anl a,#07h ; 3 high bits from th0 325 | rr a 326 | rr a 327 | rr a 328 | mov r5, a 329 | 330 | mov a,tl0 331 | anl a,#0F8h ; 5 low bits 332 | rr a 333 | rr a 334 | rr a 335 | orl a, r5 336 | mov r6,a 337 | 338 | ; ; diag: save clock samples 339 | ; mov @r1,a 340 | 341 | ; reset timer value 342 | mov th0, #interval_th_11_bit 343 | mov tl0, #interval_tl_11_bit 344 | 345 | ; start timer 0 346 | setb tr0 347 | 348 | ; --------------------------- consistancy checks 349 | ; -- checks by bit number 350 | mov a,r7 351 | jz Int0Return ; bit zero 352 | dec a 353 | jz Int0StartBit ; start bit 354 | clr c 355 | subb a,#08h 356 | mov r5,a ; save clock bit count result 357 | 358 | ; -- data check clock timings 359 | clr c 360 | mov a, r6 361 | subb a, KbClockMin 362 | jc Int0Error 363 | 364 | mov a, r6 365 | clr c 366 | subb a, KbClockMax 367 | jnc Int0Error 368 | 369 | mov a,r5 370 | jnz Int0Return 371 | 372 | ; -- special handling for last bit: output 373 | ; start-bit must be 1 374 | jnb KbBitBufH.7, Int0Error 375 | setb p1.3 ; error LED off 376 | mov a, KbBitBufL 377 | mov RawBuf, a 378 | mov r7,#0 379 | setb PCRXCompleteF ; fully received flag 380 | clr PCRXActiveF ; receive in progress flag 381 | sjmp Int0Return 382 | 383 | Int0StartBit: 384 | ; -- start bit: calculate timings 385 | clr PCRXCompleteF 386 | mov a,r6 387 | clr c 388 | rrc a 389 | clr c 390 | rrc a 391 | mov KbClockMin,a 392 | add a,acc 393 | add a,acc 394 | mov KbClockMax,a 395 | anl KbBitBufL,#0f0h 396 | mov KbBitBufH,#0 397 | sjmp Int0Return 398 | 399 | Int0Error: 400 | ; -- cleanup buffers 401 | mov KbBitBufL,#0 402 | mov KbBitBufH,#0 403 | mov r7,#0 404 | clr p1.3 ; error LED on 405 | 406 | ; --------------------------- done 407 | Int0Return: 408 | ; -- inc the bit counter 409 | inc r7 410 | ; setb p1.7 ; @@@@@@@@@@ FIXME 411 | pop psw 412 | pop acc 413 | reti 414 | 415 | ;---------------------------------------------------------- 416 | ; timer 0 int handler: 417 | ; timer is used to measure the clock-signal-interval length 418 | ; Stop the timer after overflow, cleanup RX buffers 419 | ; RX timeout after 1 - 1.3ms 420 | ;---------------------------------------------------------- 421 | HandleTF0: 422 | cpl p3.7 ; @@@@@@@@@@@ TESTING 423 | 424 | ; stop timer 425 | clr tr0 426 | 427 | ; cleanup buffers 428 | mov KbBitBufL,#0 429 | mov KbBitBufH,#0 430 | mov r7,#0 431 | 432 | ; reset timer value 433 | mov th0, #interval_th_11_bit 434 | mov tl0, #interval_tl_11_bit 435 | 436 | reti 437 | 438 | ;---------------------------------------------------------- 439 | ; PC/XT to DEC LK translaton table 440 | ; F1-F10 are shifted to F11-F20 441 | ;---------------------------------------------------------- 442 | PCXT2DECxlt0 DB 00h, 0bfh, 0c0h, 0c5h, 0cbh, 0d0h, 0d6h, 0dbh, 0e0h, 0e5h, 0eah, 0efh, 0f9h, 0f5h, 0bch, 0beh 443 | PCXT2DECxlt1 DB 0c1h, 0c6h, 0cch, 0d1h, 0d7h, 0dch, 0e1h, 0e6h, 0ebh, 0f0h, 0fah, 0f6h, 0bdh, 0afh, 0c2h, 0c7h 444 | PCXT2DECxlt2 DB 0cdh, 0d2h, 0d8h, 0ddh, 0e2h, 0e7h, 0ech, 0f2h, 0fbh, 0bfh, 0aeh, 0f7h, 0c3h, 0c8h, 0ceh, 0d3h 445 | PCXT2DECxlt3 DB 0d9h, 0deh, 0e3h, 0e8h, 0edh, 0f3h, 0abh, 00h, 0ach, 0d4h, 0b0h, 071h, 072h, 073h, 074h, 07ch 446 | PCXT2DECxlt4 DB 07dh, 080h, 081h, 082h, 083h, 00h, 00h, 09dh, 09eh, 09fh, 0a0h, 099h, 09ah, 09bh, 00h, 096h 447 | PCXT2DECxlt5 DB 097h, 098h, 092h, 094h, 00h, 00h, 00h, 071h, 072h, 00h, 00h, 00h, 00h, 00h, 00h, 00h 448 | PCXT2DECxlt6 DB 00h, 00h, 00h, 00h, 00h, 071h, 072h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h 449 | PCXT2DECxlt7 DB 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h 450 | 451 | 452 | ;---------------------------------------------------------- 453 | ; PC/XT to DEC LK translaton table 454 | ; Num Keys are in Arrow/PgUp/Dn/Del/Ins-Mode 455 | ;---------------------------------------------------------- 456 | PCXT2DECxltm0 DB 00h, 0bfh, 0c0h, 0c5h, 0cbh, 0d0h, 0d6h, 0dbh, 0e0h, 0e5h, 0eah, 0efh, 0f9h, 0f5h, 0bch, 0beh 457 | PCXT2DECxltm1 DB 0c1h, 0c6h, 0cch, 0d1h, 0d7h, 0dch, 0e1h, 0e6h, 0ebh, 0f0h, 0fah, 0f6h, 0bdh, 0afh, 0c2h, 0c7h 458 | PCXT2DECxltm2 DB 0cdh, 0d2h, 0d8h, 0ddh, 0e2h, 0e7h, 0ech, 0f2h, 0fbh, 0bfh, 0aeh, 0f7h, 0c3h, 0c8h, 0ceh, 0d3h 459 | PCXT2DECxltm3 DB 0d9h, 0deh, 0e3h, 0e8h, 0edh, 0f3h, 0abh, 00h, 0ach, 0d4h, 0b0h, 056h, 057h, 058h, 059h, 05ah 460 | PCXT2DECxltm4 DB 064h, 065h, 066h, 067h, 068h, 00h, 00h, 08ah, 0aah, 08eh, 0a0h, 0a7h, 09ah, 0a8h, 00h, 08dh 461 | PCXT2DECxltm5 DB 0a9h, 08fh, 08bh, 08ch, 00h, 00h, 00h, 071h, 072h, 00h, 00h, 00h, 00h, 00h, 00h, 00h 462 | PCXT2DECxltm6 DB 00h, 00h, 00h, 00h, 00h, 071h, 072h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h 463 | PCXT2DECxltm7 DB 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h 464 | 465 | ;---------------------------------------------------------- 466 | ; PC/XT to DEC LK translaton table 467 | ; special key flags 468 | ; bit 0: key is modifier key 469 | ; bit 1: ignore PCXT typematic 470 | ;---------------------------------------------------------- 471 | ;PCXT2DECxlte0 DB 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h 472 | ;PCXT2DECxlte1 DB 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 03h, 00h, 00h 473 | ;PCXT2DECxlte2 DB 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 03h, 00h, 00h, 00h, 00h, 00h, 00h 474 | ;PCXT2DECxlte3 DB 00h, 00h, 00h, 00h, 00h, 00h, 03h, 00h, 03h, 00h, 02h, 00h, 00h, 00h, 00h, 00h 475 | ;PCXT2DECxlte4 DB 00h, 00h, 00h, 00h, 00h, 02h, 02h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h 476 | ;PCXT2DECxlte5 DB 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h 477 | ;PCXT2DECxlte6 DB 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h 478 | ;PCXT2DECxlte7 DB 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h 479 | 480 | ;---------------------------------------------------------- 481 | ; ring buffer insertion helper. Input Data comes in r2 482 | ;---------------------------------------------------------- 483 | RingBufCheckInsert: 484 | ; check for ring buffer overflow 485 | mov a,RingBufPtrOut 486 | setb c 487 | subb a,RingBufPtrIn 488 | anl a,#RingBufSizeMask 489 | jz RingBufFull 490 | 491 | ; some space left, insert data 492 | mov a,RingBufPtrIn 493 | add a,#RingBuf 494 | mov r0,a 495 | mov a,r2 496 | mov @r0,a 497 | 498 | ; increment pointer 499 | inc RingBufPtrIn 500 | anl RingBufPtrIn,#RingBufSizeMask 501 | ret 502 | 503 | RingBufFull: 504 | ; error routine 505 | clr p1.3 506 | ret 507 | 508 | ;---------------------------------------------------------- 509 | ; Get received data and translate it into the ring buffer 510 | ;---------------------------------------------------------- 511 | TranslateToBufDEC: 512 | ; translate from PC/XT to DEC LK scancode 513 | mov a,RawBuf 514 | 515 | ; clear received data flag 516 | clr PCRXCompleteF 517 | 518 | ; -- check if scancode is typematic 519 | clr PCXTTypematicF 520 | cjne a,PCXTLastBuf,TranslateToBufTypematicPassed 521 | setb PCXTTypematicF 522 | TranslateToBufTypematicPassed: 523 | ; save scancode for typematic-eleminator 524 | mov PCXTLastBuf,a 525 | 526 | ; -- save make/break bit 7 527 | mov c,acc.7 528 | mov PCXTBreakF,c 529 | 530 | ; -- clear make/break bit 7 531 | anl a,#7fh 532 | 533 | ; -- check for modifier key codes 534 | ; - make and break codes must be translated 535 | ; - make codes generated by typematic must be filtered 536 | ; - keypress status will be saved in LKMod 537 | cjne a,#02ah,TranslateToBufNot2a ; Shift L 538 | mov c,PCXTBreakF 539 | cpl c 540 | mov LKModSL,c 541 | sjmp TranslateToBufModKey 542 | TranslateToBufNot2a: 543 | cjne a,#036h,TranslateToBufNot36 ; Shift R 544 | mov c,PCXTBreakF 545 | cpl c 546 | mov LKModSR,c 547 | sjmp TranslateToBufModKey 548 | TranslateToBufNot36: 549 | cjne a,#1dh,TranslateToBufNot1d ; Ctrl 550 | mov c,PCXTBreakF 551 | cpl c 552 | mov LKModC,c 553 | sjmp TranslateToBufModKey 554 | TranslateToBufNot1d: 555 | cjne a,#038h,TranslateToBufNot38 ; Alt 556 | mov c,PCXTBreakF 557 | cpl c 558 | mov LKModAL,c 559 | sjmp TranslateToBufModKey 560 | TranslateToBufNot38: 561 | 562 | ; -- ignore break / key release codes for non-modifier keys 563 | jnb PCXTBreakF,TranslateToBufNoBreak 564 | sjmp TranslateToBufEnd 565 | TranslateToBufNoBreak: 566 | 567 | ; --- check non-typematic keys 568 | ; make codes generated by typematic must be filtered 569 | cjne a,#03ah,TranslateToBufNot3a ; CapsLock 570 | sjmp TranslateToBufNoTypematic 571 | TranslateToBufNot3a: 572 | cjne a,#045h,TranslateToBufNot45 ; NumLock 573 | sjmp TranslateToBufNoTypematic 574 | TranslateToBufNot45: 575 | cjne a,#046h,TranslateToBufNot46 ; ScrollLock 576 | sjmp TranslateToBufNoTypematic 577 | TranslateToBufNot46: 578 | sjmp TranslateToBufGo 579 | 580 | TranslateToBufModKey: 581 | ; -- check if last modifier is released 582 | mov r3,a 583 | mov a,LKModAll 584 | jz TranslateToBufAllModRel 585 | mov a,r3 586 | sjmp TranslateToBufNoTypematic 587 | 588 | TranslateToBufAllModRel: 589 | ; send \xb3 "all modifiers released" 590 | mov r2, #0b3h 591 | call RingBufCheckInsert 592 | sjmp TranslateToBufEnd 593 | 594 | TranslateToBufNoTypematic: 595 | ; --- filter typematic 596 | jnb PCXTTypematicF,TranslateToBufNoTypematicKey 597 | sjmp TranslateToBufEnd 598 | TranslateToBufNoTypematicKey: 599 | 600 | ; -- check for NumLock to switch mode 601 | cjne a,#045h,TranslateToBufNot45_2 602 | cpl LKModeNumLock_ 603 | mov c,LKModeNumLock_ 604 | mov p1.2,c 605 | clr c 606 | sjmp TranslateToBufEnd 607 | TranslateToBufNot45_2: 608 | 609 | TranslateToBufGo: 610 | ; -- process scancode 611 | jb LKModeNumLock_,PCXT2DECArrowMode 612 | ; get NumLock-Mode LK scancode 613 | mov dptr,#PCXT2DECxlt0 614 | movc a,@a+dptr 615 | sjmp PCXT2DECEnd 616 | 617 | PCXT2DECArrowMode: 618 | ; get Arrow-Mode LK scancode 619 | mov dptr,#PCXT2DECxltm0 620 | movc a,@a+dptr 621 | 622 | PCXT2DECEnd: 623 | mov OutputBuf,a 624 | 625 | ; ; keyboard disabled? 626 | ; jb ATKbdDisableF,TranslateToBufEnd 627 | 628 | ; normal data byte 629 | mov r2, OutputBuf 630 | call RingBufCheckInsert 631 | 632 | TranslateToBufEnd: 633 | ret 634 | 635 | ;---------------------------------------------------------- 636 | ; Send data from the ring buffer 637 | ;---------------------------------------------------------- 638 | ; -- send ring buffer contents 639 | BufTX: 640 | ; check if data is present in the ring buffer 641 | clr c 642 | mov a,RingBufPtrIn 643 | subb a,RingBufPtrOut 644 | anl a,#RingBufSizeMask 645 | jz BufTXEnd 646 | 647 | ; clr p1.1 ; @@@@@@@@@@ FIXME 648 | ; -- get data from buffer 649 | mov a,RingBufPtrOut 650 | add a,#RingBuf 651 | mov r0,a 652 | mov a,@r0 653 | 654 | ; -- send data 655 | mov sbuf,a ; 8 data bits 656 | clr TI 657 | 658 | ; -- increment output pointer 659 | inc RingBufPtrOut 660 | anl RingBufPtrOut,#RingBufSizeMask 661 | 662 | BufTXEnd: 663 | ; setb p1.1 ; @@@@@@@@@@ FIXME 664 | ret 665 | 666 | ;---------------------------------------------------------- 667 | ; check and respond to received DEC commands 668 | ;---------------------------------------------------------- 669 | DECCmdProc: 670 | ; -- get received DEC LK command 671 | mov a,DECRXBuf 672 | 673 | ; -- argument for 0x11 command: clear keyboard LED 674 | jnb LKCmdClrLedF,DECCPNotClrLEDarg 675 | clr LKCmdClrLedF 676 | anl a,#0fh 677 | cpl a 678 | anl LKLEDBuf,a 679 | sjmp DECCPLEDarg 680 | 681 | DECCPNotClrLEDarg: 682 | ; -- argument for 0x13 command: set keyboard LED 683 | jnb LKCmdSetLedF,DECCPNotSetLEDarg 684 | clr LKCmdSetLedF 685 | anl a,#0fh 686 | orl LKLEDBuf,a 687 | ; sjmp DECCPLEDarg 688 | 689 | DECCPLEDarg: 690 | ; -- process LED buffer 691 | ; Wait 692 | mov c,acc.0 693 | cpl c 694 | mov p1.4,c 695 | ; Compose to NumLock 696 | mov c,acc.1 697 | mov ATLEDBuf.1,c 698 | cpl c 699 | mov p1.5,c 700 | mov p1.0,c ; @@@@@@@@@@@@@ TESTING 701 | ; CapsLock 702 | mov c,acc.2 703 | mov ATLEDBuf.2,c 704 | cpl c 705 | mov p1.6,c 706 | mov p1.1,c ; @@@@@@@@@@@@@ TESTING 707 | ; ScrollLock 708 | mov c,acc.3 709 | mov ATLEDBuf.0,c 710 | cpl c 711 | mov p1.7,c 712 | sjmp DECCPDone 713 | 714 | DECCPNotSetLEDarg: 715 | ; -- command 0xfd: keyboard reset. send POST code \x01\x00\x00\x00 716 | cjne a,#0fdh,DECCPNotFD 717 | mov r2,#01h 718 | call RingBufCheckInsert 719 | mov r2,#00h 720 | call RingBufCheckInsert 721 | mov r2,#00h 722 | call RingBufCheckInsert 723 | mov r2,#00h 724 | call RingBufCheckInsert 725 | sjmp DECCPDone 726 | DECCPNotFD: 727 | ; -- command 0x0A 728 | cjne a,#0Ah,DECCPNot0A 729 | sjmp DECCPSendAck 730 | DECCPNot0A: 731 | ; -- command 0x11: clear LED 732 | cjne a,#11h,DECCPNot11 733 | setb LKCmdClrLedF 734 | sjmp DECCPDone 735 | DECCPNot11: 736 | ; -- command 0x13: set LED 737 | cjne a,#13h,DECCPNot13 738 | setb LKCmdSetLedF 739 | sjmp DECCPDone 740 | DECCPNot13: 741 | ; -- command 0x1A 742 | cjne a,#1Ah,DECCPNot1A 743 | sjmp DECCPSendAck 744 | DECCPNot1A: 745 | ; -- command 0x3A 746 | cjne a,#3Ah,DECCPNot3A 747 | sjmp DECCPSendAck 748 | DECCPNot3A: 749 | ; -- command 0x4A 750 | cjne a,#4Ah,DECCPNot4A 751 | sjmp DECCPSendAck 752 | DECCPNot4A: 753 | ; -- command 0x5A 754 | cjne a,#5Ah,DECCPNot5A 755 | sjmp DECCPSendAck 756 | DECCPNot5A: 757 | ; -- command 0x6A 758 | cjne a,#6Ah,DECCPNot6A 759 | sjmp DECCPSendAck 760 | DECCPNot6A: 761 | ; -- command 0x72 762 | cjne a,#72h,DECCPNot72 763 | sjmp DECCPSendAck 764 | DECCPNot72: 765 | ; -- command 0x0A2 766 | cjne a,#0A2h,DECCPNotA2 767 | sjmp DECCPSendAck 768 | DECCPNotA2: 769 | ; -- command 0x78 770 | cjne a,#78h,DECCPNot78 771 | sjmp DECCPSendAck 772 | DECCPNot78: 773 | sjmp DECCPDone 774 | 775 | DECCPSendAck: 776 | mov r2,#0BAh 777 | call RingBufCheckInsert 778 | ; sjmp DECCPDone 779 | 780 | DECCPDone: 781 | ret 782 | 783 | ;---------------------------------------------------------- 784 | ; init uart with timer 1 as baudrate generator for 4800 BPS 785 | ;---------------------------------------------------------- 786 | uart_timer1_init: 787 | mov scon, #050h ; uart mode 1 (8 bit), single processor 788 | orl tmod, #020h ; M0,M1, bit4,5 in TMOD, timer 1 in mode 2, 8bit-auto-reload 789 | orl pcon, #080h ; SMOD, bit 7 in PCON 790 | 791 | mov th1, #uart_t1_4800_18432k 792 | mov tl1, #uart_t1_4800_18432k 793 | 794 | clr es ; disable serial interrupt 795 | setb tr1 796 | 797 | clr ri 798 | setb ti 799 | 800 | ret 801 | 802 | ;---------------------------------------------------------- 803 | ; init timer 0 for PC/XT interval timing, timeout=1ms 804 | ;---------------------------------------------------------- 805 | timer0_init: 806 | anl tmod, #0f0h ; clear all lower bits 807 | orl tmod, #01h ; M0,M1, bit0,1 in TMOD, timer 0 in mode 1, 16bit 808 | 809 | mov th0, #interval_th_11_bit 810 | mov tl0, #interval_tl_11_bit 811 | 812 | setb et0 ; (IE.3) enable timer 0 interrupt 813 | setb tr0 ; timer 0 run 814 | ret 815 | 816 | ;---------------------------------------------------------- 817 | ; init timer 0 as buzzer driver 818 | ;---------------------------------------------------------- 819 | timer0_init_beep: 820 | anl tmod, #0f0h ; clear all lower bits 821 | orl tmod, #01h ; M0,M1, bit0,1 in TMOD, timer 0 in mode 1, 16bit 822 | 823 | mov th0, #interval_th_11_bit 824 | mov tl0, #interval_tl_11_bit 825 | 826 | setb et0 ; (IE.3) enable timer 0 interrupt 827 | setb tr0 ; timer 0 run 828 | ret 829 | 830 | 831 | ;DECBeepPCL 832 | ;DECBeepPCH 833 | 834 | ;---------------------------------------------------------- 835 | ; Id 836 | ;---------------------------------------------------------- 837 | RCSId DB "$Id: kbdbabel_pcxt_dec_8051.asm,v 1.1 2007/05/02 08:37:33 akurz Exp $" 838 | 839 | ;---------------------------------------------------------- 840 | ; main 841 | ;---------------------------------------------------------- 842 | Start: 843 | ; -- init the stack 844 | mov sp,#StackBottom 845 | ; -- init UART and timer0/1 846 | acall uart_timer1_init 847 | acall timer0_init 848 | 849 | ; -- enable interrupts int0 850 | setb ex0 ; external interupt 0 enable 851 | setb it0 ; falling edge trigger for int 0 852 | setb ea 853 | 854 | ; -- clear buffers and all flags 855 | mov 20h,#0 856 | mov 21h,#0 857 | mov 22h,#0 858 | mov LKLEDBuf,#0 859 | mov ATLEDBuf,#0 860 | mov LKModAll,#0 861 | 862 | ; -- init the ring buffer 863 | mov RingBufPtrIn,#0 864 | mov RingBufPtrOut,#0 865 | 866 | ; ; -- cold start flag 867 | ; setb ATCmdResetF 868 | 869 | ; ---------------- 870 | Loop: 871 | ; -- check PC/XT receive status 872 | jb PCRXCompleteF,LoopProcessPCXTData 873 | 874 | ; -- check on new DEC/LK data received on serial line 875 | jb RI, LoopProcessLKcmd 876 | 877 | ; -- loop if serial TX is active 878 | jnb TI, Loop 879 | 880 | ; send data 881 | call BufTX 882 | 883 | ; -- loop 884 | sjmp Loop 885 | 886 | ;---------------------------------------------------------- 887 | ; helpers for the main loop 888 | ;---------------------------------------------------------- 889 | ; ---------------- 890 | LoopProcessPCXTData: 891 | ; -- PC/XT data received, process the received scancode into output ring buffer 892 | call TranslateToBufDEC 893 | sjmp Loop 894 | 895 | ; ---------------- 896 | LoopProcessLKcmd: 897 | ; -- commands from DEC host received via serial line 898 | ; clr p1.6 ; @@@@@@@@@@ FIXME 899 | mov a,sbuf 900 | mov DECRXBuf,a 901 | clr RI 902 | acall DECCmdProc 903 | ; setb p1.6 ; @@@@@@@@@@ FIXME 904 | sjmp Loop 905 | 906 | ;---------------------------------------------------------- 907 | ; Still space on the ROM left for the license? 908 | ;---------------------------------------------------------- 909 | LIC01 DB " Copyright 2006 by Alexander Kurz" 910 | LIC02 DB " " 911 | GPL01 DB " This program is free software; you can redistribute it and/or modify" 912 | GPL02 DB " it under the terms of the GNU General Public License as published by" 913 | GPL03 DB " the Free Software Foundation; either version 2, or (at your option)" 914 | GPL04 DB " any later version." 915 | GPL05 DB " " 916 | GPL06 DB " This program is distributed in the hope that it will be useful," 917 | GPL07 DB " but WITHOUT ANY WARRANTY; without even the implied warranty of" 918 | GPL08 DB " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the" 919 | GPL09 DB " GNU General Public License for more details." 920 | GPL10 DB " " 921 | ; ---------------- 922 | end 923 | -------------------------------------------------------------------------------- /kbdbabel-sun-ps2/kbdbabel_sun_ps2_8051.asm: -------------------------------------------------------------------------------- 1 | ; --------------------------------------------------------------------- 2 | ; Sun to AT/PS2 keyboard transcoder for 8051 type processors. 3 | ; 4 | ; $Id: kbdbabel_sun_ps2_8051.asm,v 1.7 2008/04/16 21:30:38 akurz Exp $ 5 | ; 6 | ; Clock/Crystal: 11.0592MHz. 7 | ; alternatively 18.432MHz and 14.7456 may be used. 8 | ; 3.6864MHz or 7.3728 will be too slow to drive the AT/PS2 timer. 9 | ; 10 | ; Sun Keyboard connect: 11 | ; Inverted signal using transistors and 4.7k resistors 12 | ; is connected to the serial port lines 13 | ; RxD - p3.0 (Pin 10 on DIL40, Pin 2 on AT89C2051 PDIP20) 14 | ; TxD - p3.1 (Pin 11 on DIL40, Pin 3 on AT89C2051 PDIP20) 15 | ; 16 | ; AT Host connect: 17 | ; DATA - p3.5 (Pin 15 on DIL40, Pin 9 on AT89C2051 PDIP20) 18 | ; CLOCK - p3.3 (Pin 13 on DIL40, Pin 7 on AT89C2051 PDIP20, Int 1) 19 | ; 20 | ; LED-Output connect: 21 | ; LEDs are connected with 220R to Vcc 22 | ; ScrollLock - p1.7 (Pin 8 on DIL40, Pin 19 on AT89C2051 PDIP20) 23 | ; CapsLock - p1.6 (Pin 7 on DIL40, Pin 18 on AT89C2051 PDIP20) 24 | ; NumLock - p1.5 (Pin 6 on DIL40, Pin 17 on AT89C2051 PDIP20) 25 | ; ? - p1.4 26 | ; ? - p1.3 27 | ; AT TX Communication abort - p1.2 28 | ; AT RX Communication abort - p1.1 29 | ; TX buffer full - p1.0 30 | ; 31 | ; Build using the macroassembler by Alfred Arnold 32 | ; $ asl -L kbdbabel_sun_ps2_8051.asm -o kbdbabel_sun_ps2_8051.p 33 | ; $ p2bin -l \$ff -r 0-\$7ff kbdbabel_sun_ps2_8051 34 | ; write kbdbabel_sun_ps2_8051.bin on an empty 27C256 or AT89C2051 35 | ; 36 | ; Copyright 2006, 2007 by Alexander Kurz 37 | ; 38 | ; This is free software. 39 | ; You may copy and redistibute this software according to the 40 | ; GNU general public license version 3 or any later verson. 41 | ; 42 | ; --------------------------------------------------------------------- 43 | 44 | cpu 8052 45 | include stddef51.inc 46 | include kbdbabel_intervals.inc 47 | 48 | ;---------------------------------------------------------- 49 | ; Variables / Memory layout 50 | ;---------------------------------------------------------- 51 | ;------------------ octets 52 | B20 sfrb 20h ; bit adressable space 53 | B21 sfrb 21h 54 | B22 sfrb 22h 55 | SunLEDBuf sfrb 23h ; must be bit-adressable 56 | KbBitBufL equ 24h 57 | KbBitBufH equ 25h 58 | KbClockMin equ 26h 59 | KbClockMax equ 27h 60 | ATBitCount equ 28h ; AT scancode TX counter 61 | RawBuf equ 30h ; raw input scancode 62 | OutputBuf equ 31h ; AT scancode 63 | TXBuf equ 32h ; AT scancode TX buffer 64 | RingBufPtrIn equ 33h ; Ring Buffer write pointer, starting with zero 65 | RingBufPtrOut equ 34h ; Ring Buffer read pointer, starting with zero 66 | ATRXBuf equ 35h ; AT host-to-dev buffer 67 | ATRXCount equ 36h 68 | ATRXResendBuf equ 37h ; for AT resend feature 69 | ;KbClockIntBuf equ 33h 70 | 71 | ;------------------ bits 72 | MiscRXCompleteF bit B20.1 ; full and correct byte-received 73 | ATTXBreakF bit B20.3 ; Release/Break-Code flag 74 | ATTXMasqF bit B20.4 ; TX-AT-Masq-Char-Bit (send two byte scancode) 75 | ATTXParF bit B20.5 ; TX-AT-Parity bit 76 | ATTFModF bit B20.6 ; Timer modifier: alarm clock or clock driver 77 | MiscSleepT0F bit B20.7 ; sleep timer active flag 78 | ATCommAbort bit B21.0 ; AT communication aborted 79 | ATHostToDevIntF bit B21.1 ; host-do-device init flag triggered by ex1 / unused. 80 | ATHostToDevF bit B21.2 ; host-to-device flag for timer 81 | ATTXActiveF bit B21.3 ; AT TX active 82 | ATCmdReceivedF bit B21.4 ; full and correct AT byte-received 83 | ATCmdResetF bit B21.5 ; reset 84 | ATCmdLedF bit B21.6 ; AT command processing: set LED 85 | ATCmdScancodeF bit B21.7 ; AT command processing: set scancode 86 | ATKbdDisableF bit B22.0 ; Keyboard disable 87 | SunSetLedF bit B22.1 ; send SetLed Command to sun keyboard: argunent 88 | SunCtrlLedF bit B22.2 ; send SetLed Command to sun keyboard: control code 89 | 90 | ;------------------ arrays 91 | RingBuf equ 40h 92 | RingBufSizeMask equ 0fh ; 16 byte ring-buffer size 93 | 94 | ;------------------ stack 95 | StackBottom equ 50h ; the stack 96 | 97 | ;---------------------------------------------------------- 98 | ; start 99 | ;---------------------------------------------------------- 100 | org 0 ; cold start 101 | ljmp Start 102 | ;---------------------------------------------------------- 103 | ; interrupt handlers 104 | ;---------------------------------------------------------- 105 | ;---------------------------- 106 | ; org 03h ; external interrupt 0 107 | ; ljmp HandleInt0 108 | ;---------------------------- 109 | org 0bh ; handle TF0 110 | ljmp HandleTF0 111 | ;---------------------------- 112 | ; org 13h ; Int 1 113 | ; ljmp HandleInt1 114 | ;---------------------------- 115 | ; org 1bh ; handle TF1 116 | ; ljmp HandleTF1 117 | ;---------------------------- 118 | ; org 23h ; RI/TI 119 | ; ljmp HandleRITI 120 | ;---------------------------- 121 | ; org 2bh ; handle TF2 122 | ; ljmp HandleTF2 123 | 124 | org 033h 125 | 126 | ;---------------------------------------------------------- 127 | ; int1 handler: 128 | ; trigger on host-do-device transmission signal 129 | ;---------------------------------------------------------- 130 | ;HandleInt1: 131 | ; setb ATHostToDevIntF 132 | ; reti 133 | 134 | ;---------------------------------------------------------- 135 | ; timer 0 int handler used for different purposes 136 | ; depending on ATTFModF and ATHostToDevF 137 | ; 138 | ; ATTFModF=0: 139 | ; timer is used as 16-bit alarm clock. 140 | ; Stop the timer after overflow, cleanup RX buffers 141 | ; and clear MiscSleepT0F 142 | ; 143 | ; ATTFModF=1: 144 | ; timer is used in 8-bit-auto-reload-mode to generate 145 | ; the AT scancode clock timings. 146 | ; 147 | ; ATTFModF=1, ATHostToDevF=0: 148 | ; device-to-host communication: send datagrams on the AT line. 149 | ; Each run in this mode will take 36 processor cycles. 150 | ; Extra nops between Data and Clock bit assignment for signal stabilization. 151 | ; 152 | ; ATTFModF=1, ATHostToDevF=1: 153 | ; host-do-device communication: receive datagrams on the AT line. 154 | ;---------------------------------------------------------- 155 | HandleTF0: 156 | jb ATTFModF,timerAsClockTimer ; 2,2 157 | 158 | ; --------------------------- timer is used as 16-bit alarm clock 159 | timerAsAlarmClock: 160 | ; -- stop timer 0 161 | clr tr0 162 | clr MiscSleepT0F 163 | reti 164 | 165 | ; --------------------------- AT clock driver, RX or TX 166 | timerAsClockTimer: 167 | push acc ; 2,4 168 | push psw ; 2,6 169 | jb ATHostToDevF,timerHostToDev ; 2,8 170 | 171 | ; --------------------------- device-to-host communication 172 | timerDevToHost: 173 | ; -- switch on bit-number 174 | ; ----------------- 175 | mov dptr,#timerDevToHostJT ; 2,10 176 | mov a,ATBitCount ; 1,11 177 | rl a ; 1,12 178 | jmp @a+dptr ; 2,14 179 | 180 | timerDevToHostJT: 181 | sjmp timerTXStartBit ; 2,16 182 | sjmp timerTXDataBit 183 | sjmp timerTXDataBit 184 | sjmp timerTXDataBit 185 | sjmp timerTXDataBit 186 | sjmp timerTXDataBit 187 | sjmp timerTXDataBit 188 | sjmp timerTXDataBit 189 | sjmp timerTXDataBit 190 | sjmp timerTXParityBit 191 | sjmp timerTXStopBit 192 | sjmp timerTXStop ; safety 193 | 194 | ; ----------------- 195 | timerTXStartBit: 196 | ; -- set start bit (0) and pull down clock line 197 | jnb p3.3,timerTXClockBusy ; 2 198 | nop 199 | clr p3.5 ; 1 ; Data Startbit 200 | call ATTX_delay_clk 201 | clr p3.3 ; 1 ; Clock 202 | sjmp timerTXClockRelease ; 2 203 | 204 | ; ----------------- 205 | timerTXDataBit: 206 | ; -- set data bit 0-7 and pull down clock line 207 | mov a,TXBuf ; 1 208 | rrc a ; 1 ; next data bit to c 209 | mov p3.5,c ; 2 210 | mov TXBuf,a ; 1 211 | call ATTX_delay_clk 212 | clr p3.3 ; 1 ; Clock 213 | sjmp timerTXClockRelease ; 2 214 | 215 | ; ----------------- 216 | timerTXParityBit: 217 | ; -- set parity bit from ATTXParF and pull down clock line 218 | nop 219 | mov c,ATTXParF ; 1 ; parity bit 220 | mov p3.5,c ; 2 221 | call ATTX_delay_clk 222 | clr p3.3 ; 1 ; Clock 223 | sjmp timerTXClockRelease ; 2 224 | 225 | ; ----------------- 226 | timerTXStopBit: 227 | ; -- set stop bit (1) and pull down clock line 228 | nop 229 | nop 230 | nop 231 | setb p3.5 ; 1 ; Data Stopbit 232 | call ATTX_delay_clk 233 | clr p3.3 ; 1 ; Clock 234 | sjmp timerTXClockRelease ; 2 235 | 236 | ; ----------------- 237 | timerTXClockRelease: 238 | ; -- release clock line 239 | call ATTX_delay_release 240 | mov a,ATBitCount ; 1 241 | cjne a,#10,timerTXCheckBusy ; 2 242 | setb p3.3 ; 1 243 | setb p1.2 ; diag: data send 244 | ; end of TX sequence, not time critical 245 | sjmp timerTXStop 246 | 247 | timerTXCheckBusy: 248 | ; -- check if clock is released, but not after the stop bit. 249 | ; -- Host may pull down clock to abort communication at any time. 250 | setb p3.3 ; 1 251 | jb p3.3,timerTXEnd 252 | 253 | timerTXClockBusy: 254 | ; -- clock is busy, abort communication 255 | setb ATCommAbort ; AT communication aborted flag 256 | clr p1.2 ; diag: data not send 257 | ; sjmp timerTXStop 258 | 259 | ; ----------------- 260 | timerTXStop: 261 | ; -- stop timer auto-reload 262 | clr ATTFModF 263 | clr tr0 264 | setb p3.5 ; just for safety, clean up data line state 265 | ; sjmp timerTXEnd 266 | 267 | ; --------------------------- done 268 | timerTXEnd: ; total 7 269 | ; -- done 270 | inc ATBitCount ; 1 271 | pop psw ; 2 272 | pop acc ; 2 273 | reti ; 2 274 | 275 | ; --------------------------- host-to-device communication 276 | timerHostToDev: 277 | ; -- switch on bit-number 278 | ; ----------------- 279 | mov dptr,#timerHostToDevJT ; 2,10 280 | mov a,ATBitCount ; 1,11 281 | rl a ; 1,12 282 | jmp @a+dptr ; 2,14 283 | timerHostToDevJT: 284 | sjmp timerRXStartBit ; 2,16 285 | sjmp timerRXDataBit 286 | sjmp timerRXDataBit 287 | sjmp timerRXDataBit 288 | sjmp timerRXDataBit 289 | sjmp timerRXDataBit 290 | sjmp timerRXDataBit 291 | sjmp timerRXDataBit 292 | sjmp timerRXDataBit 293 | sjmp timerRXParityBit 294 | sjmp timerRXACKBit 295 | sjmp timerRXCleanup 296 | sjmp timerRXClockBusy ; safety 297 | 298 | ; ----------------- 299 | timerRXStartBit: 300 | ; -- check start bit, must be zero 301 | jb p3.5,timerRXClockBusy 302 | 303 | ; pull down clock line 304 | clr p3.3 ; 1 ; Clock 305 | sjmp timerRXClockRelease 306 | 307 | ; ----------------- 308 | timerRXDataBit: 309 | ; -- read bit 1-8 pull down clock line 310 | ; -- new data bit 311 | mov a,ATRXBuf 312 | mov c,p3.5 313 | rrc a 314 | mov ATRXBuf,a 315 | 316 | ; -- pull down clock line 317 | clr p3.3 ; 1 ; Clock 318 | sjmp timerRXClockRelease 319 | 320 | ; ----------------- 321 | timerRXParityBit: 322 | ; -- read and check parity bit 9 and pull down clock line 323 | ; -- check parity 324 | mov a,ATRXBuf 325 | jb p,timerRXParityBitPar 326 | jnb p3.5,timerRXClockBusy ; parity error 327 | ; -- pull down clock line 328 | clr p3.3 ; 1 ; Clock 329 | sjmp timerRXClockRelease 330 | 331 | timerRXParityBitPar: 332 | jb p3.5,timerRXClockBusy ; parity error 333 | ; -- pull down clock line 334 | clr p3.3 ; 1 ; Clock 335 | sjmp timerRXClockRelease 336 | 337 | ; ----------------- 338 | timerRXAckBit: 339 | ; -- check bit 10, stop-bit, must be 1. 340 | ; -- write ACK-bit and pull down clock line 341 | jnb p3.5,timerRXClockBusy 342 | 343 | ; ACK-Bit 344 | clr p3.5 ; 1 345 | call ATTX_delay_clk 346 | clr p3.3 ; 1 ; Clock 347 | sjmp timerRXClockRelease ; 2 348 | 349 | ; ----------------- 350 | timerRXCleanup: 351 | ; -- end of RX clock sequence after 12 clock pulses 352 | clr ATTFModF 353 | 354 | ; -- release the data line 355 | setb p3.5 356 | 357 | ; -- datagram received, stop timer auto-reload 358 | setb ATCmdReceivedF ; full message received 359 | clr tr0 360 | sjmp timerRXEnd 361 | 362 | ; ----------------- 363 | timerRXClockRelease: 364 | ; -- release clock line 365 | call ATTX_delay_release 366 | mov a,ATBitCount ; 1 367 | cjne a,#10,timerRXCheckBusy 368 | setb p3.3 ; 1 369 | setb p1.1 ; diag: host-do-dev ok 370 | sjmp timerRXEnd 371 | 372 | timerRXCheckBusy: 373 | ; -- check if clock is released, but not after the last bit. 374 | ; -- Host may pull down clock to abort communication at any time. 375 | setb p3.3 ; 1 376 | jb p3.3,timerRXEnd 377 | 378 | timerRXClockBusy: 379 | ; -- clock is busy, abort communication 380 | setb ATCommAbort ; AT communication aborted flag 381 | clr p1.1 ; diag: host-do-dev abort 382 | 383 | clr ATTFModF 384 | clr tr0 385 | setb p3.5 ; just for safety, clean up data line state 386 | ; sjmp timerRXEnd 387 | 388 | ; ----------------- 389 | timerRXEnd: ; total 7 390 | ; -- done 391 | inc ATBitCount ; 1 392 | pop psw ; 2 393 | pop acc ; 2 394 | reti ; 2 395 | 396 | ;---------------------------------------------------------- 397 | ; Sun to AT translaton table 398 | ;---------------------------------------------------------- 399 | 400 | Sun2ATxlt0 DB 0h, 028h, 021h, 00h, 032h, 05h, 06h, 09h, 04h, 078h, 0ch, 07h, 03h, 011h, 0bh, 00h 401 | Sun2ATxlt1 DB 083h, 0ah, 01h, 011h, 075h, 077h, 07fh, 07eh, 06bh, 00h, 00h, 072h, 074h, 076h, 016h, 01eh 402 | Sun2ATxlt2 DB 026h, 025h, 02eh, 036h, 03dh, 03eh, 046h, 045h, 04eh, 055h, 0eh, 066h, 070h, 023h, 04ah, 07ch 403 | Sun2ATxlt3 DB 037h, 00h, 071h, 00h, 06ch, 0dh, 015h, 01dh, 024h, 02dh, 02ch, 035h, 03ch, 043h, 044h, 04dh 404 | Sun2ATxlt4 DB 054h, 05bh, 071h, 00h, 06ch, 075h, 07dh, 07bh, 00h, 00h, 069h, 00h, 014h, 01ch, 01bh, 023h 405 | Sun2ATxlt5 DB 02bh, 034h, 033h, 03bh, 042h, 04bh, 04ch, 052h, 05dh, 05ah, 05ah, 06bh, 073h, 074h, 070h, 00h 406 | Sun2ATxlt6 DB 07dh, 00h, 077h, 012h, 01ah, 022h, 021h, 02ah, 032h, 031h, 03ah, 041h, 049h, 04ah, 059h, 00h 407 | Sun2ATxlt7 DB 069h, 072h, 07ah, 00h, 00h, 00h, 00h, 058h, 02fh, 029h, 027h, 07ah, 061h, 079h, 00h, 00h 408 | 409 | ;---------------------------------------------------------- 410 | ; Sun to AT translaton table 411 | ; Bit-Table for two-byte-AT-Scancodes 412 | ; Note: even in the small 89c2051 there is enough program memory space for 413 | ; this space-consuming lookup table. Does not look nice, 414 | ; but it is easy to read and will execute fast. 415 | ;---------------------------------------------------------- 416 | Sun2ATxlte0 DB 00h, 01h, 01h, 00h, 01h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 01h, 00h, 00h 417 | Sun2ATxlte1 DB 00h, 00h, 00h, 00h, 01h, 01h, 00h, 00h, 01h, 00h, 00h, 01h, 01h, 00h, 00h, 00h 418 | Sun2ATxlte2 DB 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 01h, 01h, 01h, 00h 419 | Sun2ATxlte3 DB 01h, 00h, 00h, 00h, 01h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h 420 | Sun2ATxlte4 DB 00h, 00h, 01h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 01h, 00h, 00h, 00h, 00h, 00h 421 | Sun2ATxlte5 DB 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 01h, 00h, 00h, 00h, 00h, 00h 422 | Sun2ATxlte6 DB 01h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h 423 | Sun2ATxlte7 DB 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 01h, 00h, 01h, 01h, 00h, 00h, 00h, 00h 424 | 425 | ;---------------------------------------------------------- 426 | ; ring buffer insertion helper. Input Data comes in r2 427 | ;---------------------------------------------------------- 428 | RingBufCheckInsert: 429 | ; check for ring buffer overflow 430 | mov a,RingBufPtrOut 431 | setb c 432 | subb a,RingBufPtrIn 433 | anl a,#RingBufSizeMask 434 | jz RingBufFull 435 | 436 | ; some space left, insert data 437 | mov a,RingBufPtrIn 438 | add a,#RingBuf 439 | mov r0,a 440 | mov a,r2 441 | mov @r0,a 442 | 443 | ; increment pointer 444 | inc RingBufPtrIn 445 | anl RingBufPtrIn,#RingBufSizeMask 446 | ret 447 | 448 | RingBufFull: 449 | ; error routine 450 | clr p1.0 451 | ret 452 | 453 | ;---------------------------------------------------------- 454 | ; Get received data and translate it into the ring buffer 455 | ;---------------------------------------------------------- 456 | TranslateToBufSun: 457 | ; translate from Sun to AT scancode 458 | mov a,RawBuf 459 | 460 | ; save make/break bit 7 461 | mov c,acc.7 462 | mov ATTXBreakF,c 463 | 464 | ; ignore make/break bit 7 465 | anl a,#7fh 466 | 467 | ; check 2-byte scancodes 468 | mov r4,a 469 | mov dptr,#Sun2ATxlte0 470 | movc a,@a+dptr 471 | mov c,acc.0 472 | mov ATTXMasqF,c 473 | mov a,r4 474 | 475 | ; get AT scancode 476 | mov dptr,#Sun2ATxlt0 477 | movc a,@a+dptr 478 | 479 | ; save AT scancode 480 | mov OutputBuf,a 481 | 482 | ; clear received data flag 483 | clr MiscRXCompleteF 484 | 485 | ; keyboard disabled? 486 | jb ATKbdDisableF,TranslateToBufSunEnd 487 | 488 | ; check for 0xE0 escape code 489 | jnb ATTXMasqF,TranslateToBufSunNoEsc 490 | mov r2,#0E0h 491 | call RingBufCheckInsert 492 | 493 | TranslateToBufSunNoEsc: 494 | ; check for 0xF0 release / break code 495 | jnb ATTXBreakF,TranslateToBufSunNoRelease 496 | mov r2,#0F0h 497 | call RingBufCheckInsert 498 | 499 | TranslateToBufSunNoRelease: 500 | ; normal data byte 501 | mov r2, OutputBuf 502 | call RingBufCheckInsert 503 | 504 | TranslateToBufSunEnd: 505 | ret 506 | 507 | ;---------------------------------------------------------- 508 | ; Send data from the ring buffer 509 | ;---------------------------------------------------------- 510 | ; -- send ring buffer contents 511 | BufTX: 512 | ; check if data is present in the ring buffer 513 | clr c 514 | mov a,RingBufPtrIn 515 | subb a,RingBufPtrOut 516 | anl a,#RingBufSizeMask 517 | jz BufTXEnd 518 | 519 | ; inter-character delay 0.13ms 520 | call timer0_130u_init 521 | BufTXWaitDelay: 522 | jb MiscSleepT0F,BufTXWaitDelay 523 | 524 | ; -- get data from buffer 525 | mov a,RingBufPtrOut 526 | add a,#RingBuf 527 | mov r0,a 528 | mov a,@r0 529 | 530 | ; -- send data 531 | mov TXBuf,a ; 8 data bits 532 | mov c,p 533 | cpl c 534 | mov ATTXParF,c ; odd parity bit 535 | clr ATHostToDevF ; timer in TX mode 536 | setb ATTXActiveF ; diag: TX is active 537 | ; clr ex0 ; may diable input interrupt here, better is, better dont. 538 | ; clr ex1 539 | call timer0_init 540 | 541 | ; -- wait for completion 542 | BufTXWaitSent: 543 | jb ATTFModF,BufTXWaitSent 544 | ; setb ex1 ; enable external interupt 1 545 | ; setb ex0 ; enable external interupt 0 546 | clr ATTXActiveF ; diag 547 | jb ATCommAbort,BufTXEnd ; check on communication abort 548 | 549 | ; ; diag: send also on serial line 550 | ; mov a,@r0 551 | ; mov sbuf,a 552 | ; clr ti 553 | ;BufTXWaitDiagSend: 554 | ; jnb ti,BufTXWaitDiagSend 555 | 556 | ; -- store last transmitted word for resend-feature 557 | mov a,@r0 558 | mov ATRXResendBuf,a 559 | 560 | ; -- increment output pointer 561 | inc RingBufPtrOut 562 | anl RingBufPtrOut,#RingBufSizeMask 563 | 564 | BufTXEnd: 565 | ret 566 | 567 | ;---------------------------------------------------------- 568 | ; check and respond to received AT commands 569 | ; used bits: internal: ATCmdLedF, ATCmdScancodeF external ATCmdResetF 570 | ;---------------------------------------------------------- 571 | ATCmdProc: 572 | ; -- check for new data 573 | jb ATCmdReceivedF,ATCPGo 574 | ljmp ATCPDone 575 | 576 | ATCPGo: 577 | ; ; -- diag: send received AT command via serial line 578 | ; mov sbuf,ATRXBuf 579 | ; clr ti 580 | ;ATCPWait: 581 | ; jnb ti,ATCPWait 582 | 583 | ; -- get received AT command 584 | mov a,ATRXBuf 585 | clr ATCmdReceivedF 586 | 587 | ; -- argument for 0xed command: set keyboard LED 588 | jnb ATCmdLedF,ATCPNotLEDarg 589 | clr ATCmdLedF 590 | mov SunLEDBuf,#0 591 | 592 | ; -- process Sun-Keyboard LED data 593 | ; CapsLock: Sun-LED-Bit 3 594 | mov c,acc.2 595 | mov SunLEDBuf.3,c 596 | ; NumLock: Sun-LED-Bit 0 597 | mov c,acc.1 598 | mov SunLEDBuf.0,c 599 | ; ScrollLock: Sun-LED-Bit 2 600 | mov c,acc.0 601 | mov SunLEDBuf.2,c 602 | ; will send data later. not every PS2-Device will tolerate 2ms serial delay before the ACK. 603 | setb SunCtrlLedF 604 | setb SunSetLedF 605 | 606 | ; -- set build-in LEDs 607 | ; NumLock 608 | mov c,acc.1 609 | cpl c 610 | mov p1.5,c 611 | ; CapsLock 612 | mov c,acc.2 613 | cpl c 614 | mov p1.6,c 615 | ; ScrollLock 616 | mov c,acc.0 617 | cpl c 618 | mov p1.7,c 619 | 620 | ljmp ATCPSendAck 621 | 622 | ATCPNotLEDarg: 623 | ; -- argument for 0xf0 command: set scancode. 624 | jnb ATCmdScancodeF,ATCPNotF0Arg 625 | clr ATCmdScancodeF 626 | jnz ATCPSendAck 627 | ; -- Argument 0x0: send ACK and scancode 628 | mov r2,#0FAh 629 | call RingBufCheckInsert 630 | ; send 0x02, the default scancode 631 | mov r2,#02h 632 | call RingBufCheckInsert 633 | sjmp ATCPDone 634 | ATCPNotF0Arg: 635 | ; -- command 0xed: set keyboard LED command. set bit for next argument processing and send ACK 636 | cjne a,#0edh,ATCPNotED 637 | setb ATCmdLedF 638 | sjmp ATCPSendAck 639 | ATCPNotED: 640 | ; -- command 0xee: echo command. send 0xee 641 | cjne a,#0EEh,ATCPNotEE 642 | mov r2,#0EEh 643 | call RingBufCheckInsert 644 | sjmp ATCPDone 645 | ATCPNotEE: 646 | ; -- command 0xf0: scan code set. set bit for next argument processing and send ACK 647 | cjne a,#0f0h,ATCPNotF0 648 | setb ATCmdScancodeF 649 | sjmp ATCPSendAck 650 | ATCPNotF0: 651 | cjne a,#0f1h,ATCPNotF1 652 | sjmp ATCPSendAck 653 | ATCPNotF1: 654 | ; -- command 0xf2: keyboard model detection. send ACK,xab,x83 655 | cjne a,#0f2h,ATCPNotF2 656 | mov r2,#0FAh 657 | call RingBufCheckInsert 658 | mov r2,#0ABh 659 | call RingBufCheckInsert 660 | mov r2,#083h 661 | call RingBufCheckInsert 662 | sjmp ATCPDone 663 | ATCPNotF2: 664 | ; -- command 0xf3: typematic repeat rate. send ACK and ignore 665 | cjne a,#0f3h,ATCPNotF3 666 | sjmp ATCPSendAck 667 | ATCPNotF3: 668 | ; -- command 0xf4: keyboard enable. clear TX buffer, send ACK 669 | cjne a,#0f4h,ATCPNotF4 670 | mov RingBufPtrIn,#0 671 | mov RingBufPtrOut,#0 672 | clr ATKbdDisableF 673 | sjmp ATCPSendAck 674 | ATCPNotF4: 675 | ; -- command 0xf5: keyboard disable. send ACK and set ATKbdDisableF 676 | cjne a,#0f5h,ATCPNotF5 677 | setb ATKbdDisableF 678 | sjmp ATCPSendAck 679 | ATCPNotF5: 680 | ; -- command 0xf6: keyboard enable. clear TX buffer, send ACK 681 | cjne a,#0f6h,ATCPNotF6 682 | mov RingBufPtrIn,#0 683 | mov RingBufPtrOut,#0 684 | clr ATKbdDisableF 685 | sjmp ATCPSendAck 686 | ATCPNotF6: 687 | ; -- command 0xfe: resend last word 688 | cjne a,#0feh,ATCPNotFE 689 | mov r2,ATRXResendBuf 690 | call RingBufCheckInsert 691 | sjmp ATCPDone 692 | ATCPNotFE: 693 | ; -- command 0xff: keyboard reset 694 | cjne a,#0ffh,ATCPNotFF 695 | mov RingBufPtrIn,#0 696 | mov RingBufPtrOut,#0 697 | setb ATCmdResetF 698 | clr ATKbdDisableF 699 | sjmp ATCPSendAck 700 | ATCPNotFF: 701 | sjmp ATCPSendAck 702 | 703 | ATCPSendAck: 704 | mov r2,#0FAh 705 | call RingBufCheckInsert 706 | ; sjmp ATCPDone 707 | 708 | ATCPDone: 709 | ret 710 | 711 | ;---------------------------------------------------------- 712 | ; check if there is AT data to send 713 | ;---------------------------------------------------------- 714 | ATTX: 715 | ; -- Device-to-Host communication 716 | ; -- check if there is data to send, send data 717 | call BufTX 718 | 719 | ; -- keyboard reset/cold start: send AAh after some delay 720 | jnb ATCmdResetF,ATTXWaitDelayEnd 721 | clr ATCmdResetF 722 | ; -- optional delay after faked cold start 723 | ; yes, some machines will not boot without this, e.g. IBM PS/ValuePoint 433DX/D 724 | call timer0_20ms_init 725 | ATTXResetDelay: 726 | jb MiscSleepT0F,ATTXResetDelay 727 | ; -- send "self test passed" 728 | mov r2,#0AAh 729 | call RingBufCheckInsert 730 | ATTXWaitDelayEnd: 731 | ret 732 | 733 | ;---------------------------------------------------------- 734 | ; helper: delay clock line status change for 10 microseconds 735 | ; FIXME: this is X-tal frequency dependant 736 | ;---------------------------------------------------------- 737 | ATTX_delay_clk: 738 | nop 739 | nop 740 | nop 741 | nop 742 | 743 | ret 744 | 745 | ;---------------------------------------------------------- 746 | ; helper: delay clock release 747 | ; FIXME: this is X-tal frequency dependant 748 | ;---------------------------------------------------------- 749 | ATTX_delay_release: 750 | nop 751 | nop 752 | nop 753 | nop 754 | 755 | nop 756 | nop 757 | nop 758 | nop 759 | nop 760 | 761 | nop 762 | nop 763 | nop 764 | nop 765 | nop 766 | 767 | nop 768 | nop 769 | nop 770 | nop 771 | nop 772 | 773 | nop 774 | nop 775 | nop 776 | nop 777 | nop 778 | 779 | ret 780 | 781 | ;---------------------------------------------------------- 782 | ; init uart with timer 2 as baudrate generator 783 | ; note: this timer is not present on the AT89C2051 784 | ;---------------------------------------------------------- 785 | ;uart_timer2_init: 786 | ; mov scon, #050h ; uart mode 1 (8 bit), single processor 787 | ; 788 | ; orl t2con, #34h ; Timer 2: internal baudrate generate mode RX/TX 789 | ; mov rcap2h, #uart_t2h_9600_18432k 790 | ; mov rcap2l, #uart_t2l_9600_18432k 791 | ; clr es ; disable serial interrupt 792 | ; 793 | ; ret 794 | 795 | ;---------------------------------------------------------- 796 | ; init uart with timer 1 as baudrate generator 797 | ; need 1200BPS 798 | ;---------------------------------------------------------- 799 | uart_timer1_init: 800 | mov scon, #050h ; uart mode 1 (8 bit), single processor 801 | orl tmod, #020h ; M0,M1, bit4,5 in TMOD, timer 1 in mode 2, 8bit-auto-reload 802 | orl pcon, #080h ; SMOD, bit 7 in PCON 803 | mov th1, #uart_t1_1200_11059_2k 804 | mov tl1, #uart_t1_1200_11059_2k 805 | clr es ; disable serial interrupt 806 | setb tr1 807 | 808 | clr ri 809 | setb ti 810 | 811 | ret 812 | 813 | ;---------------------------------------------------------- 814 | ; init timer 0 for interval timing (fast 8 bit reload) 815 | ; need 75-85mus intervals 816 | ;---------------------------------------------------------- 817 | timer0_init: 818 | clr tr0 819 | anl tmod, #0f0h ; clear all lower bits 820 | orl tmod, #02h; ; 8-bit Auto-Reload Timer, mode 2 821 | mov th0, #interval_t0_85u_11059_2k 822 | mov tl0, #interval_t0_85u_11059_2k 823 | setb et0 ; (IE.1) enable timer 0 interrupt 824 | setb ATTFModF ; see timer 0 interrupt code 825 | clr ATCommAbort ; communication abort flag 826 | mov ATBitCount,#0 827 | setb tr0 ; go 828 | ret 829 | 830 | ;---------------------------------------------------------- 831 | ; init timer 0 in 16 bit mode for inter-char delay of 0.13ms 832 | ;---------------------------------------------------------- 833 | timer0_130u_init: 834 | clr tr0 835 | anl tmod, #0f0h ; clear all lower bits 836 | orl tmod, #01h; ; M0,M1, bit0,1 in TMOD, timer 0 in mode 1, 16bit 837 | mov th0, #interval_th_130u_11059_2k 838 | mov tl0, #interval_tl_130u_11059_2k 839 | setb et0 ; (IE.1) enable timer 0 interrupt 840 | clr ATTFModF ; see timer 0 interrupt code 841 | setb MiscSleepT0F 842 | setb tr0 ; go 843 | ret 844 | 845 | ;---------------------------------------------------------- 846 | ; init timer 0 in 16 bit mode for faked POST delay of of 20ms 847 | ;---------------------------------------------------------- 848 | timer0_20ms_init: 849 | clr tr0 850 | anl tmod, #0f0h ; clear all upper bits 851 | orl tmod, #01h; ; M0,M1, bit0,1 in TMOD, timer 0 in mode 1, 16bit 852 | mov th0, #interval_th_20m_11059_2k 853 | mov tl0, #interval_tl_20m_11059_2k 854 | setb et0 ; (IE.1) enable timer 0 interrupt 855 | clr ATTFModF ; see timer 0 interrupt code 856 | setb MiscSleepT0F 857 | setb tr0 ; go 858 | ret 859 | 860 | ;---------------------------------------------------------- 861 | ; Id 862 | ;---------------------------------------------------------- 863 | RCSId DB "$KbdBabel: kbdbabel_sun_ps2_8051.asm,v 1.10 2007/11/10 21:30:02 akurz Exp $" 864 | 865 | ;---------------------------------------------------------- 866 | ; main 867 | ;---------------------------------------------------------- 868 | Start: 869 | ; -- init the stack 870 | mov sp,#StackBottom 871 | ; -- init UART and timer0/1 872 | ; acall uart_timer2_init 873 | acall uart_timer1_init 874 | 875 | ; -- enable interrupts int0 876 | setb ea 877 | 878 | ; -- clear all flags 879 | mov B20,#0 880 | mov B21,#0 881 | mov B22,#0 882 | 883 | ; -- init the ring buffer 884 | mov RingBufPtrIn,#0 885 | mov RingBufPtrOut,#0 886 | 887 | ; -- cold start flag 888 | setb ATCmdResetF 889 | 890 | ; ---------------- 891 | Loop: 892 | ; -- check input receive status 893 | jb RI,LoopProcessSunData 894 | 895 | ; -- check on new AT data received 896 | jb ATCmdReceivedF,LoopProcessATcmd 897 | 898 | ; -- check if AT communication active. 899 | jb ATTFModF,Loop 900 | 901 | ; -- check AT line status, clock line must not be busy 902 | jnb p3.3,Loop 903 | 904 | ; -- check for AT RX data 905 | jnb p3.5,LoopATRX 906 | 907 | ; -- send data, if data is present 908 | call ATTX 909 | 910 | ; -- check if commands may be sent to Sun Keyboard 911 | jb SunSetLedF,LoopSunLED 912 | 913 | sjmp loop 914 | 915 | ;---------------------------------------------------------- 916 | ; helpers for the main loop 917 | ;---------------------------------------------------------- 918 | ; ---------------- 919 | LoopProcessSunData: 920 | ; -- input data received, process the received scancode into output ring buffer 921 | mov a,sbuf 922 | mov RawBuf,a 923 | clr RI 924 | cjne a,#07fh,LoopProcessSunDataNot7f ; ignore sun 7f scancodes 925 | sjmp Loop 926 | 927 | LoopProcessSunDataNot7f: 928 | jb ATCmdResetF, Loop 929 | setb MiscRXCompleteF 930 | call TranslateToBufSun 931 | sjmp Loop 932 | 933 | ; ----------------- 934 | LoopProcessATcmd: 935 | ; -- AT command processing 936 | call ATCmdProc 937 | sjmp loop 938 | 939 | ; ---------------- 940 | LoopATRX: 941 | ; -- Host-do-Device communication 942 | ; -- diag: host-do-dev ok 943 | setb p1.1 944 | 945 | ; -- receive data on the AT line 946 | mov ATRXCount,#0 947 | mov ATRXBuf,#0 948 | ; clr ATHostToDevIntF 949 | setb ATHostToDevF 950 | call timer0_init 951 | 952 | ; wait for completion 953 | LoopTXWaitSent: 954 | jb ATTFModF,LoopTXWaitSent 955 | LoopCheckATEnd: 956 | ljmp Loop 957 | 958 | ; ---------------- 959 | LoopSunLED: 960 | ; -- set sun keyboard LEDs 961 | ; sending two bytes of LED control code takes about 2ms due to 2 bytes @ 1200bps. 962 | ; some PS2-to-USB-adaptors do not tolerate this delay in AT communication. 963 | 964 | ; -- return if flag not set 965 | jnb SunSetLedF,LoopSunLEDEnd 966 | 967 | ; -- return if serial transmission is active 968 | jnb ti,LoopSunLEDEnd 969 | 970 | ; -- check control-code-or-argument-bit 971 | jnb SunCtrlLedF,LoopSunLEDSendArg 972 | 973 | ; -- send control code 974 | clr p1.4 975 | clr ti 976 | mov sbuf,#0eh 977 | clr SunCtrlLedF 978 | sjmp LoopSunLEDEnd 979 | 980 | LoopSunLEDSendArg: 981 | ; -- send argument 982 | clr p1.4 983 | clr ti 984 | mov sbuf,SunLEDBuf 985 | clr SunSetLedF 986 | 987 | LoopSunLEDEnd: 988 | setb p1.4 989 | ljmp Loop 990 | 991 | ;---------------------------------------------------------- 992 | ; Still space on the ROM left for the license? 993 | ;---------------------------------------------------------- 994 | LIC01 DB " Copyright 2006, 2007 by Alexander Kurz" 995 | LIC02 DB " " 996 | GPL01 DB " This program is free software; you can redistribute it and/or modify" 997 | GPL02 DB " it under the terms of the GNU General Public License as published by" 998 | GPL03 DB " the Free Software Foundation; either version 3, or (at your option)" 999 | GPL04 DB " any later version." 1000 | GPL05 DB " " 1001 | GPL06 DB " This program is distributed in the hope that it will be useful," 1002 | GPL07 DB " but WITHOUT ANY WARRANTY; without even the implied warranty of" 1003 | GPL08 DB " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the" 1004 | GPL09 DB " GNU General Public License for more details." 1005 | GPL10 DB " " 1006 | ; ---------------- 1007 | end 1008 | -------------------------------------------------------------------------------- /kbdbabel-kc85-ps2/kbdbabel_kc85_ps2_8051.asm: -------------------------------------------------------------------------------- 1 | ; --------------------------------------------------------------------- 2 | ; Robotron KC-85 to AT/PS2 keyboard transcoder for 8051 type processors 3 | ; 4 | ; $KbdBabel: kbdbabel_kc85_ps2_8051.asm,v 1.8 2007/08/01 09:28:52 akurz Exp $ 5 | ; 6 | ; Clock/Crystal: 12MHz. 7 | ; 8 | ; KC-85 Keyboard connect: 9 | ; Data - p3.2 (Pin 12 on DIL40, Pin 6 on AT89C2051 PDIP20, Int 0) 10 | ; 9V-generation - p3.0 (Pin 4 on DIL40, Pin 2 on AT89C2051 PDIP20) 11 | ; 12 | ; AT Host connect: 13 | ; DATA - p3.5 (Pin 15 on DIL40, Pin 9 on AT89C2051 PDIP20) 14 | ; CLOCK - p3.3 (Pin 13 on DIL40, Pin 7 on AT89C2051 PDIP20, Int 1) 15 | ; 16 | ; LED-Output connect: 17 | ; LEDs are connected with 470R to Vcc 18 | ; ScrollLock - p1.7 (Pin 8 on DIL40, Pin 19 on AT89C2051 PDIP20) 19 | ; CapsLock - p1.6 (Pin 7 on DIL40, Pin 18 on AT89C2051 PDIP20) 20 | ; NumLock - p1.5 (Pin 6 on DIL40, Pin 17 on AT89C2051 PDIP20) 21 | ; KC85 timer, bit valid - p1.4 22 | ; KC85 timer, bit - p1.3 23 | ; AT TX Communication abort - p1.2 24 | ; AT RX Communication abort - p1.1 25 | ; KC85 timer timeout - p1.0 26 | ; Int0 active - p3.7 27 | ; 28 | ; Build using the macroassembler by Alfred Arnold 29 | ; $ asl -L kbdbabel_kc85_ps2_8051.asm -o kbdbabel_kc85_ps2_8051.p 30 | ; $ p2bin -l \$ff -r 0-\$7ff kbdbabel_kc85_ps2_8051 31 | ; write kbdbabel_kc85_ps2_8051.bin on an empty 27C256 or AT89C2051 32 | ; 33 | ; Copyright 2007 by Alexander Kurz 34 | ; 35 | ; This is free software. 36 | ; You may copy and redistibute this software according to the 37 | ; GNU general public license version 3 or any later verson. 38 | ; 39 | ; --------------------------------------------------------------------- 40 | 41 | cpu 8052 42 | include stddef51.inc 43 | include kbdbabel_intervals.inc 44 | 45 | ;---------------------------------------------------------- 46 | ; Variables / Memory layout 47 | ;---------------------------------------------------------- 48 | ;------------------ octets 49 | B20 sfrb 20h ; bit adressable space 50 | B21 sfrb 21h 51 | B22 sfrb 22h 52 | B23 sfrb 23h 53 | InputBitBuf equ 24h ; Keyboard input bit buffer 54 | ATBitCount sfrb 28h ; AT scancode TX counter 55 | RawBuf equ 30h ; raw scancode 56 | OutputBuf equ 31h ; AT scancode 57 | TXBuf equ 32h ; AT scancode TX buffer 58 | RingBufPtrIn equ 33h ; Ring Buffer write pointer, starting with zero 59 | RingBufPtrOut equ 34h ; Ring Buffer read pointer, starting with zero 60 | ATRXBuf equ 35h ; AT host-to-dev buffer 61 | ATRXCount equ 36h 62 | ATRXResendBuf equ 37h ; for AT resend feature 63 | KC85ClockCount equ 38h ; KC-85 Clock counter 64 | KC85BitCount equ 39h ; KC-85 Bit counter 65 | KC85CodeStore equ 3ah ; Scancode-buffer 66 | 67 | ;------------------ bits 68 | ; bit B20.0 ; 69 | ; bit B20.1 ; 70 | ATKbdDisableF bit B20.2 ; Keyboard disable 71 | ATTXBreakF bit B20.3 ; Release/Break-Code flag 72 | ATTXMasqF bit B20.4 ; TX-AT-Masq-Char-Bit (send two byte scancode) 73 | ATTXParF bit B20.5 ; TX-AT-Parity bit 74 | TFModF bit B20.6 ; AT Timer modifier: alarm clock or clock driver 75 | MiscSleepT0F bit B20.7 ; sleep timer active flag, timer 0 76 | ATCommAbort bit B21.0 ; AT communication aborted 77 | ATHostToDevIntF bit B21.1 ; host-do-device init flag triggered by ex1 / unused. 78 | ATHostToDevF bit B21.2 ; host-to-device flag for timer 79 | ATTXActiveF bit B21.3 ; AT TX active 80 | ATCmdReceivedF bit B21.4 ; full and correct AT byte-received 81 | ATCmdResetF bit B21.5 ; reset 82 | ATCmdLedF bit B21.6 ; AT command processing: set LED 83 | ATCmdScancodeF bit B21.7 ; AT command processing: set scancode 84 | ; bit B22.0 85 | RXCompleteF bit B22.1 ; full and correct byte-received 86 | KC85DataBit bit B22.2 ; time dependant data bit, set by TF1-Handler, to be read by INT0 handler 87 | KC85DataBitValid bit B22.3 ; time dependant data valid bit, set by TF1-Handler 88 | KC85WordTimeoutF bit B22.4 ; Timeout for 7-bit words. 89 | KC85ClockTimeoutF bit B22.5 ; Maximum interval time expired. 90 | KC85ShiftF bit B22.6 ; An extra bit for Shift 91 | ATShiftF bit B22.7 ; stored AT shift state 92 | ;------------------ arrays 93 | RingBuf equ 40h 94 | RingBufSizeMask equ 0fh ; 16 byte ring-buffer size 95 | 96 | ;------------------ stack 97 | StackBottom equ 50h ; the stack 98 | 99 | ;---------------------------------------------------------- 100 | ; start 101 | ;---------------------------------------------------------- 102 | org 0 ; cold start 103 | ljmp Start 104 | ;---------------------------------------------------------- 105 | ; interrupt handlers 106 | ;---------------------------------------------------------- 107 | ;---------------------------- 108 | org 03h ; external interrupt 0 109 | ljmp HandleInt0 110 | ;---------------------------- 111 | org 0bh ; handle TF0 112 | ljmp HandleTF0 113 | ;---------------------------- 114 | org 13h ; Int 1 115 | ljmp HandleInt1 116 | ;---------------------------- 117 | org 1bh ; handle TF1 118 | ljmp HandleTF1 119 | ;---------------------------- 120 | ; org 23h ; RI/TI 121 | ; ljmp HandleRITI 122 | ;---------------------------- 123 | ; org 2bh ; handle TF2 124 | ; ljmp HandleTF2 125 | 126 | org 033h 127 | ;---------------------------------------------------------- 128 | ; int0 handler: 129 | ; Get Bits by rotation into InputBitBuf. 130 | ;---------------------------------------------------------- 131 | HandleInt0: 132 | push acc 133 | push psw 134 | clr p3.7 135 | 136 | ; --- check for the first pulse after inter-word timeout 137 | jnb KC85WordTimeoutF,Int0WordInProgress 138 | mov InputBitBuf,#0 139 | mov KC85BitCount,#0 140 | call timer1_init 141 | sjmp Int0Return 142 | 143 | Int0WordInProgress: 144 | ; --- ignore invalid intervals, FIXME 145 | jnb KC85DataBitValid,Int0Return 146 | mov a,InputBitBuf 147 | rr a 148 | mov c,KC85DataBit 149 | mov acc.6,c 150 | mov InputBitBuf,a 151 | 152 | mov KC85ClockCount,#0 153 | 154 | ; --- check bit number 155 | inc KC85BitCount 156 | mov a,KC85BitCount 157 | cjne a,#7,Int0Return 158 | 159 | ; --- full word received 160 | mov a,InputBitBuf 161 | mov RawBuf,a 162 | mov KC85CodeStore,a 163 | setb RXCompleteF 164 | ; sjmp Int0Return 165 | 166 | ; --------------------------- done 167 | Int0Return: 168 | setb p3.7 169 | pop psw 170 | pop acc 171 | reti 172 | 173 | ;---------------------------------------------------------- 174 | ; timer 1 int handler: 175 | ; KC-85 Keyboard interval timing. 176 | ; Using 125 microseconds as interval results in this state table: 177 | ; < 4.0ms < 32 cycles invalid 178 | ; 4.0-5.9ms 32-46 cycles valid 0 179 | ; 5.9-8.0ms 47-63 cycles valid 1 180 | ; 8.0-12.5 64-99 cycles invalid 181 | ; 12.5-17.5ms 100-140 cycles inter-character interval 182 | ; > 17.5ms > 140 cycles key-release timeout 183 | ;---------------------------------------------------------- 184 | HandleTF1: 185 | push acc 186 | push psw 187 | 188 | mov a,KC85ClockCount 189 | clr c 190 | ; --- check count < 32 191 | subb a,#32 192 | jc timer1StateInvalid 193 | ; --- check count < 47 194 | subb a,#15 195 | jc timer1StateValid0 196 | ; --- check count < 64 197 | subb a,#17 198 | jc timer1StateValid1 199 | ; --- check count < 100, state invalid 200 | subb a,#36 201 | jc timer1StateInvalid 202 | ; --- check count < 140 203 | subb a,#40 204 | jc timer1InterChar 205 | ; ----------------- 206 | ; --- Repeat-Timeout: Key released: do not inc the counter 207 | clr tr1 208 | setb KC85ClockTimeoutF 209 | sjmp timer1Return 210 | ; ----------------- 211 | ; --- inter-character timeout 212 | timer1InterChar: 213 | inc KC85ClockCount 214 | setb KC85WordTimeoutF 215 | setb p1.0 216 | clr KC85DataBitValid 217 | setb p1.4 218 | sjmp timer1Return 219 | 220 | ; ----------------- 221 | ; --- invalid timing: 222 | timer1StateInvalid: 223 | inc KC85ClockCount 224 | clr KC85DataBitValid 225 | setb p1.4 226 | sjmp timer1Return 227 | 228 | ; ----------------- 229 | ; --- valid timing with 0 bit value 230 | timer1StateValid0: 231 | inc KC85ClockCount 232 | clr KC85DataBit 233 | setb KC85DataBitValid 234 | clr p1.3 235 | clr p1.4 236 | sjmp timer1Return 237 | 238 | ; ----------------- 239 | ; --- valid timing with 1 bit value 240 | timer1StateValid1: 241 | inc KC85ClockCount 242 | setb KC85DataBit 243 | setb KC85DataBitValid 244 | clr p1.4 245 | setb p1.3 246 | sjmp timer1Return 247 | 248 | ; ----------------- 249 | ; --- done 250 | timer1Return: 251 | pop psw 252 | pop acc 253 | reti 254 | 255 | ;---------------------------------------------------------- 256 | ; int1 handler: 257 | ; trigger on host-do-device transmission signal 258 | ;---------------------------------------------------------- 259 | HandleInt1: 260 | setb ATHostToDevIntF 261 | reti 262 | 263 | ;---------------------------------------------------------- 264 | ; timer 0 int handler used for different purposes 265 | ; depending on TFModF and ATHostToDevF 266 | ; 267 | ; TFModF=0: 268 | ; timer is used as 16-bit alarm clock. 269 | ; Stop the timer after overflow, cleanup RX buffers 270 | ; and clear MiscSleepT0F 271 | ; RX timeout at 18.432MHz, set th0,tl0 to 272 | ; 0c0h,00h -> 10ms, 0e0h,00h -> 5ms, 0fah,00h -> 1ms 273 | ; 0fbh,0cdh -> 0.7ms, 0ffh,039h -> 0.12ms 274 | ; 275 | ; TFModF=1: 276 | ; timer is used in 8-bit-auto-reload-mode to generate 277 | ; the AT scancode clock with 2x40 microseconds timings. 278 | ; 40mus@18.432MHz -> th0 and tl0=0c3h or 61 processor cycles. 279 | ; 280 | ; TFModF=1, ATHostToDevF=0: 281 | ; device-to-host communication: send datagrams on the AT line. 282 | ; Each run in this mode will take 36 processor cycles. 283 | ; Extra nops between Data and Clock bit assignment for signal stabilization. 284 | ; 285 | ; TFModF=1, ATHostToDevF=1: 286 | ; host-do-device communication: receive datagrams on the AT line. 287 | ;---------------------------------------------------------- 288 | HandleTF0: 289 | jb TFModF,timerAsClockTimer ; 2,2 290 | 291 | ; --------------------------- timer is used as 16-bit alarm clock 292 | timerAsAlarmClock: 293 | ; -- stop timer 0 294 | clr tr0 295 | clr MiscSleepT0F 296 | reti 297 | 298 | ; --------------------------- AT clock driver, RX or TX 299 | timerAsClockTimer: 300 | push acc ; 2,4 301 | push psw ; 2,6 302 | jb ATHostToDevF,timerHostToDev ; 2,8 303 | 304 | ; --------------------------- device-to-host communication 305 | timerDevToHost: 306 | ; -- switch on bit-number 307 | ; ----------------- 308 | jb ATBitCount.0,timerTXClockRelease ; 2,10 309 | mov dptr,#timerDevToHostJT ; 2,12 310 | mov a,ATBitCount ; 1,13 311 | jmp @a+dptr ; 2,15 312 | 313 | timerDevToHostJT: 314 | sjmp timerTXStartBit ; 2,17 315 | sjmp timerTXDataBit 316 | sjmp timerTXDataBit 317 | sjmp timerTXDataBit 318 | sjmp timerTXDataBit 319 | sjmp timerTXDataBit 320 | sjmp timerTXDataBit 321 | sjmp timerTXDataBit 322 | sjmp timerTXDataBit 323 | sjmp timerTXParityBit 324 | sjmp timerTXStopBit 325 | sjmp timerTXStop ; safety 326 | 327 | ; ----------------- 328 | timerTXStartBit: 329 | ; -- set start bit (0) and pull down clock line 330 | jnb p3.3,timerTXClockBusy ; 2 331 | nop 332 | clr p3.5 ; 1 ; Data Startbit 333 | 334 | call nop20 335 | 336 | clr p3.3 ; 1 ; Clock 337 | sjmp timerTXEnd ; 2 338 | 339 | ; ----------------- 340 | timerTXDataBit: 341 | ; -- set data bit 0-7 and pull down clock line 342 | mov a,TXBuf ; 1 343 | rrc a ; 1 ; next data bit to c 344 | mov p3.5,c ; 2 345 | mov TXBuf,a ; 1 346 | 347 | call nop20 348 | 349 | clr p3.3 ; 1 ; Clock 350 | sjmp timerTXEnd 351 | 352 | ; ----------------- 353 | timerTXParityBit: 354 | ; -- set parity bit from ATTXParF and pull down clock line 355 | nop 356 | mov c,ATTXParF ; 1 ; parity bit 357 | mov p3.5,c ; 2 358 | 359 | call nop20 360 | 361 | clr p3.3 ; 1 ; Clock 362 | sjmp timerTXEnd ; 2 363 | 364 | ; ----------------- 365 | timerTXStopBit: 366 | ; -- set stop bit (1) and pull down clock line 367 | nop 368 | nop 369 | nop 370 | setb p3.5 ; 1 ; Data Stopbit 371 | 372 | call nop20 373 | 374 | clr p3.3 ; 1 ; Clock 375 | sjmp timerTXEnd ; 2 376 | 377 | ; ----------------- 378 | timerTXClockRelease: 379 | ; -- release clock line 380 | 381 | call nop20 382 | 383 | mov a,ATBitCount ; 1 384 | setb p3.3 ; 1 385 | cjne a,#21,timerTXCheckBusy ; 2 386 | setb p1.2 ; diag: data send 387 | ; end of TX sequence, not time critical 388 | sjmp timerTXStop 389 | 390 | timerTXCheckBusy: 391 | ; -- check if clock is released, but not after the stop bit. 392 | ; -- Host may pull down clock to abort communication at any time. 393 | jb p3.3,timerTXEnd 394 | 395 | timerTXClockBusy: 396 | ; -- clock is busy, abort communication 397 | setb ATCommAbort ; AT communication aborted flag 398 | clr p1.2 ; diag: data not send 399 | ; sjmp timerTXStop 400 | 401 | ; ----------------- 402 | timerTXStop: 403 | ; -- stop timer auto-reload 404 | clr TFModF 405 | clr tr0 406 | setb p3.5 ; just for safety, clean up data line state 407 | ; sjmp timerTXEnd 408 | 409 | ; --------------------------- done 410 | timerTXEnd: ; total 7 411 | ; -- done 412 | inc ATBitCount ; 1 413 | pop psw ; 2 414 | pop acc ; 2 415 | reti ; 2 416 | 417 | ; --------------------------- host-to-device communication 418 | timerHostToDev: 419 | ; -- switch on bit-number 420 | ; ----------------- 421 | jb ATBitCount.0,timerRXClockRelease ; 2,10 422 | mov dptr,#timerHostToDevJT ; 2,12 423 | mov a,ATBitCount ; 1,13 424 | jmp @a+dptr ; 2,15 425 | timerHostToDevJT: 426 | sjmp timerRXStartBit ; 2,17 427 | sjmp timerRXDataBit 428 | sjmp timerRXDataBit 429 | sjmp timerRXDataBit 430 | sjmp timerRXDataBit 431 | sjmp timerRXDataBit 432 | sjmp timerRXDataBit 433 | sjmp timerRXDataBit 434 | sjmp timerRXDataBit 435 | sjmp timerRXParityBit 436 | sjmp timerRXACKBit 437 | sjmp timerRXCleanup 438 | sjmp timerRXClockBusy ; safety 439 | 440 | ; ----------------- 441 | timerRXStartBit: 442 | ; -- check start bit, must be zero 443 | jb p3.5,timerRXClockBusy 444 | 445 | ; pull down clock line 446 | clr p3.3 ; 1 ; Clock 447 | sjmp timerRXEnd 448 | 449 | ; ----------------- 450 | timerRXDataBit: 451 | ; -- read bit 1-8 pull down clock line 452 | ; -- new data bit 453 | mov a,ATRXBuf 454 | mov c,p3.5 455 | rrc a 456 | mov ATRXBuf,a 457 | 458 | ; -- pull down clock line 459 | clr p3.3 ; 1 ; Clock 460 | sjmp timerRXEnd 461 | 462 | ; ----------------- 463 | timerRXParityBit: 464 | ; -- read and check parity bit 9 and pull down clock line 465 | ; -- check parity 466 | mov a,ATRXBuf 467 | jb p,timerRXParityBitPar 468 | jnb p3.5,timerRXClockBusy ; parity error 469 | ; -- pull down clock line 470 | clr p3.3 ; 1 ; Clock 471 | sjmp timerRXEnd 472 | 473 | timerRXParityBitPar: 474 | jb p3.5,timerRXClockBusy ; parity error 475 | ; -- pull down clock line 476 | clr p3.3 ; 1 ; Clock 477 | sjmp timerRXEnd 478 | 479 | ; ----------------- 480 | timerRXAckBit: 481 | ; -- check bit 10, stop-bit, must be 1. 482 | ; -- write ACK-bit and pull down clock line 483 | jnb p3.5,timerRXClockBusy 484 | 485 | ; ACK-Bit 486 | clr p3.5 ; 1 487 | nop 488 | nop 489 | nop 490 | clr p3.3 ; 1 ; Clock 491 | sjmp timerRXEnd ; 2 492 | 493 | ; ----------------- 494 | timerRXCleanup: 495 | ; -- end of RX clock sequence after 12 clock pulses 496 | clr TFModF 497 | 498 | ; -- release the data line 499 | setb p3.5 500 | 501 | ; -- datagram received, stop timer auto-reload 502 | setb ATCmdReceivedF ; full message received 503 | clr tr0 504 | sjmp timerRXEnd 505 | 506 | ; ----------------- 507 | timerRXClockRelease: 508 | ; -- release clock line 509 | nop 510 | nop 511 | nop 512 | mov a,ATBitCount ; 1 513 | setb p3.3 ; 1 514 | cjne a,#21,timerRXCheckBusy 515 | setb p1.1 ; diag: host-do-dev ok 516 | sjmp timerRXEnd 517 | 518 | timerRXCheckBusy: 519 | ; -- check if clock is released, but not after the last bit. 520 | ; -- Host may pull down clock to abort communication at any time. 521 | jb p3.3,timerRXEnd 522 | 523 | timerRXClockBusy: 524 | ; -- clock is busy, abort communication 525 | setb ATCommAbort ; AT communication aborted flag 526 | clr p1.1 ; diag: host-do-dev abort 527 | 528 | clr TFModF 529 | clr tr0 530 | setb p3.5 ; just for safety, clean up data line state 531 | ; sjmp timerRXEnd 532 | 533 | ; ----------------- 534 | timerRXEnd: ; total 7 535 | ; -- done 536 | inc ATBitCount ; 1 537 | pop psw ; 2 538 | pop acc ; 2 539 | reti ; 2 540 | 541 | ;---------------------------------------------------------- 542 | ; KC85 to AT translaton table 543 | ; using significant bits 1-6 only: anl a,#7e; rr a; 544 | ;---------------------------------------------------------- 545 | KC852ATxlt0 DB 1dh, 1ch, 1eh, 6bh, 6ch, 55h, 06h, 1ah 546 | KC852ATxlt1 DB 24h, 1bh, 26h, 0eh, 66h, 4eh, 04h, 22h 547 | KC852ATxlt2 DB 2ch, 2bh, 2eh, 4dh, 71h, 45h, 03h, 2ah 548 | KC852ATxlt3 DB 3ch, 33h, 3dh, 44h, 70h, 46h, 54h, 31h 549 | KC852ATxlt4 DB 43h, 3bh, 3eh, 29h, 42h, 41h, 5bh, 3ah 550 | KC852ATxlt5 DB 35h, 34h, 36h, 0h, 4bh, 49h, 0bh, 32h 551 | KC852ATxlt6 DB 2dh, 23h, 25h, 52h, 4ch, 4ah, 0ch, 21h 552 | KC852ATxlt7 DB 15h, 58h, 16h, 72h, 75h, 74h, 05h, 5ah 553 | 554 | ;---------------------------------------------------------- 555 | ; KC85 to AT translaton table 556 | ; Bit-Table for two-byte-AT-Scancodes 557 | ;---------------------------------------------------------- 558 | KC852ATxlte0 DB 00h, 00h, 00h, 01h, 01h, 00h, 00h, 00h 559 | KC852ATxlte1 DB 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h 560 | KC852ATxlte2 DB 00h, 00h, 00h, 00h, 01h, 00h, 00h, 00h 561 | KC852ATxlte3 DB 00h, 00h, 00h, 00h, 01h, 00h, 00h, 00h 562 | KC852ATxlte4 DB 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h 563 | KC852ATxlte5 DB 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h 564 | KC852ATxlte6 DB 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h 565 | KC852ATxlte7 DB 00h, 00h, 00h, 01h, 01h, 01h, 00h, 00h 566 | 567 | ;---------------------------------------------------------- 568 | ; ring buffer insertion helper. Input Data comes in r2 569 | ;---------------------------------------------------------- 570 | RingBufCheckInsert: 571 | ; check for ring buffer overflow 572 | mov a,RingBufPtrOut 573 | setb c 574 | subb a,RingBufPtrIn 575 | anl a,#RingBufSizeMask 576 | jz RingBufFull 577 | 578 | ; some space left, insert data 579 | mov a,RingBufPtrIn 580 | add a,#RingBuf 581 | mov r0,a 582 | mov a,r2 583 | mov @r0,a 584 | 585 | ; increment pointer 586 | inc RingBufPtrIn 587 | anl RingBufPtrIn,#RingBufSizeMask 588 | ret 589 | 590 | RingBufFull: 591 | ; error routine 592 | ; clr p1.0 593 | ret 594 | 595 | ;---------------------------------------------------------- 596 | ; Get received data and translate it into the ring buffer 597 | ; translate from KC85 to AT scancode 598 | ;---------------------------------------------------------- 599 | TranslateToBuf: 600 | ; --- check break-scancode 601 | jnb KC85ClockTimeoutF,TranslateToBufMake 602 | clr KC85ClockTimeoutF 603 | mov a,KC85CodeStore 604 | setb ATTXBreakF 605 | sjmp TranslateToBufMakeAndBreak 606 | 607 | TranslateToBufMake: 608 | ; --- regular scancode 609 | mov a,RawBuf 610 | ; clear received data flag 611 | clr RXCompleteF 612 | clr ATTXBreakF 613 | 614 | TranslateToBufMakeAndBreak: 615 | ; save shift bit 0 616 | mov c,acc.0 617 | cpl c 618 | mov KC85ShiftF,c 619 | 620 | ; ignore shift bit 0 621 | anl a,#0feh 622 | 623 | ; ignore obsolete bit 7 624 | anl a,#7fh 625 | rr a 626 | 627 | ; check for 2-byte AT-scancodes 628 | mov r4,a 629 | mov dptr,#KC852ATxlte0 630 | movc a,@a+dptr 631 | mov c,acc.0 632 | mov ATTXMasqF,c 633 | mov a,r4 634 | 635 | ; get AT scancode 636 | mov dptr,#KC852ATxlt0 637 | movc a,@a+dptr 638 | mov OutputBuf,a 639 | sjmp TranslateToBufGo 640 | 641 | TranslateToBufGo: 642 | ; send shift make code 643 | jnb KC85ShiftF,TranslateToBufMakeNoShift 644 | jb ATShiftF,TranslateToBufShiftDone 645 | mov r2,#012h 646 | call RingBufCheckInsert 647 | 648 | TranslateToBufMakeNoShift: 649 | ; send shift break code 650 | jnb ATShiftF,TranslateToBufShiftDone 651 | mov r2,#0F0h 652 | call RingBufCheckInsert 653 | mov r2,#012h 654 | call RingBufCheckInsert 655 | 656 | TranslateToBufShiftDone: 657 | ; keyboard disabled? 658 | jb ATKbdDisableF,TranslateToBufEnd 659 | 660 | ; check for 0xE0 escape code 661 | jnb ATTXMasqF,TranslateToBufNoEsc 662 | mov r2,#0E0h 663 | call RingBufCheckInsert 664 | 665 | TranslateToBufNoEsc: 666 | ; check for 0xF0 release / break code 667 | jnb ATTXBreakF,TranslateToBufNoRelease 668 | mov r2,#0F0h 669 | call RingBufCheckInsert 670 | 671 | TranslateToBufNoRelease: 672 | mov a,OutputBuf 673 | jz TranslateToBufIgnoreZero 674 | ; normal data byte 675 | mov r2, OutputBuf 676 | call RingBufCheckInsert 677 | 678 | TranslateToBufBreakNoShift: 679 | TranslateToBufIgnoreZero: 680 | TranslateToBufEnd: 681 | ; save shift state 682 | mov c,KC85ShiftF 683 | mov ATShiftF,c 684 | ret 685 | 686 | ;---------------------------------------------------------- 687 | ; Send data from the ring buffer 688 | ;---------------------------------------------------------- 689 | ; -- send ring buffer contents 690 | BufTX: 691 | ; check if data is present in the ring buffer 692 | clr c 693 | mov a,RingBufPtrIn 694 | subb a,RingBufPtrOut 695 | anl a,#RingBufSizeMask 696 | jz BufTXEnd 697 | 698 | ; -- get data from buffer 699 | mov a,RingBufPtrOut 700 | add a,#RingBuf 701 | mov r0,a 702 | mov a,@r0 703 | 704 | ; -- send data 705 | mov TXBuf,a ; 8 data bits 706 | mov c,p 707 | cpl c 708 | mov ATTXParF,c ; odd parity bit 709 | clr ATHostToDevF ; timer in TX mode 710 | setb ATTXActiveF ; diag: TX is active 711 | ; clr ex0 ; may diable input interrupt here, better is, better dont. 712 | ; clr ex1 713 | call timer0_init 714 | 715 | ; -- wait for completion 716 | BufTXWaitSent: 717 | jb TFModF,BufTXWaitSent 718 | ; setb ex1 ; enable external interupt 1 719 | ; setb ex0 ; enable external interupt 0 720 | clr ATTXActiveF ; diag 721 | jb ATCommAbort,BufTXEnd ; check on communication abort 722 | 723 | ; ; diag: send also on serial line 724 | ; mov a,@r0 725 | ; mov sbuf,a 726 | ; clr ti 727 | ;BufTXWaitDiagSend: 728 | ; jnb ti,BufTXWaitDiagSend 729 | 730 | ; -- store last transmitted word for resend-feature 731 | mov a,@r0 732 | mov ATRXResendBuf,a 733 | 734 | ; -- increment output pointer 735 | inc RingBufPtrOut 736 | anl RingBufPtrOut,#RingBufSizeMask 737 | 738 | BufTXEnd: 739 | ret 740 | 741 | ;---------------------------------------------------------- 742 | ; check and respond to received AT commands 743 | ; used bits: internal: ATCmdLedF, ATCmdScancodeF external ATCmdResetF 744 | ;---------------------------------------------------------- 745 | ATCmdProc: 746 | ; -- check for new data 747 | jb ATCmdReceivedF,ATCPGo 748 | ljmp ATCPDone 749 | 750 | ATCPGo: 751 | ; ; -- diag: send received AT command via serial line 752 | ; mov sbuf,ATRXBuf 753 | ; clr ti 754 | ;ATCPWait: 755 | ; jnb ti,ATCPWait 756 | 757 | ; -- get received AT command 758 | mov a,ATRXBuf 759 | clr ATCmdReceivedF 760 | 761 | ; -- argument for 0xed command: set keyboard LED 762 | jnb ATCmdLedF,ATCPNotEDarg 763 | clr ATCmdLedF 764 | ; NumLock 765 | mov c,acc.1 766 | cpl c 767 | mov p1.5,c 768 | ; CapsLock 769 | mov c,acc.2 770 | cpl c 771 | mov p1.6,c 772 | ; ScrollLock 773 | mov c,acc.0 774 | cpl c 775 | mov p1.7,c 776 | sjmp ATCPSendAck 777 | ATCPNotEDarg: 778 | ; -- argument for 0xf0 command: set scancode. 779 | jnb ATCmdScancodeF,ATCPNotF0Arg 780 | clr ATCmdScancodeF 781 | jnz ATCPSendAck 782 | ; -- Argument 0x0: send ACK and scancode 783 | mov r2,#0FAh 784 | call RingBufCheckInsert 785 | ; send 0x02, the default scancode 786 | mov r2,#02h 787 | call RingBufCheckInsert 788 | sjmp ATCPDone 789 | ATCPNotF0Arg: 790 | ; -- command 0xed: set keyboard LED command. set bit for next argument processing and send ACK 791 | cjne a,#0edh,ATCPNotED 792 | setb ATCmdLedF 793 | sjmp ATCPSendAck 794 | ATCPNotED: 795 | ; -- command 0xee: echo command. send 0xee 796 | cjne a,#0EEh,ATCPNotEE 797 | mov r2,#0EEh 798 | call RingBufCheckInsert 799 | sjmp ATCPDone 800 | ATCPNotEE: 801 | ; -- command 0xf0: scan code set. set bit for next argument processing and send ACK 802 | cjne a,#0f0h,ATCPNotF0 803 | setb ATCmdScancodeF 804 | sjmp ATCPSendAck 805 | ATCPNotF0: 806 | cjne a,#0f1h,ATCPNotF1 807 | sjmp ATCPSendAck 808 | ATCPNotF1: 809 | ; -- command 0xf2: keyboard model detection. send ACK,xab,x83 810 | cjne a,#0f2h,ATCPNotF2 811 | mov r2,#0FAh 812 | call RingBufCheckInsert 813 | mov r2,#0ABh 814 | call RingBufCheckInsert 815 | ; keyboard model MF2: x41h, PS2: x83h 816 | mov r2,#083h 817 | call RingBufCheckInsert 818 | sjmp ATCPDone 819 | ATCPNotF2: 820 | ; -- command 0xf3: typematic repeat rate. send ACK and ignore 821 | cjne a,#0f3h,ATCPNotF3 822 | sjmp ATCPSendAck 823 | ATCPNotF3: 824 | ; -- command 0xf4: keyboard enable. clear TX buffer, send ACK 825 | cjne a,#0f4h,ATCPNotF4 826 | mov RingBufPtrIn,#0 827 | mov RingBufPtrOut,#0 828 | clr ATKbdDisableF 829 | sjmp ATCPSendAck 830 | ATCPNotF4: 831 | ; -- command 0xf5: keyboard disable. send ACK and set ATKbdDisableF 832 | cjne a,#0f5h,ATCPNotF5 833 | setb ATKbdDisableF 834 | sjmp ATCPSendAck 835 | ATCPNotF5: 836 | ; -- command 0xf6: keyboard enable. clear TX buffer, send ACK 837 | cjne a,#0f6h,ATCPNotF6 838 | mov RingBufPtrIn,#0 839 | mov RingBufPtrOut,#0 840 | clr ATKbdDisableF 841 | sjmp ATCPSendAck 842 | ATCPNotF6: 843 | ; -- command 0xfe: resend last word 844 | cjne a,#0feh,ATCPNotFE 845 | mov r2,ATRXResendBuf 846 | call RingBufCheckInsert 847 | sjmp ATCPDone 848 | ATCPNotFE: 849 | ; -- command 0xff: keyboard reset 850 | cjne a,#0ffh,ATCPNotFF 851 | mov RingBufPtrIn,#0 852 | mov RingBufPtrOut,#0 853 | setb ATCmdResetF 854 | clr ATKbdDisableF 855 | sjmp ATCPSendAck 856 | ATCPNotFF: 857 | sjmp ATCPSendAck 858 | 859 | ATCPSendAck: 860 | mov r2,#0FAh 861 | call RingBufCheckInsert 862 | ; sjmp ATCPDone 863 | 864 | ATCPDone: 865 | ret 866 | 867 | ;---------------------------------------------------------- 868 | ; helper, waste 10 cpu cycles 869 | ; note: call and return takes 4 cycles 870 | ;---------------------------------------------------------- 871 | nop20: 872 | nop 873 | nop 874 | nop 875 | nop 876 | nop 877 | nop 878 | 879 | nop 880 | nop 881 | nop 882 | nop 883 | nop 884 | nop 885 | nop 886 | nop 887 | nop 888 | nop 889 | 890 | ret 891 | 892 | ;---------------------------------------------------------- 893 | ; init uart with timer 2 as baudrate generator 894 | ; 9600 BPS at 3.6864MHz -> ? 895 | ; 9600 BPS at 18.432MHz -> RCAP2H,RCAP2L=#0FFh,#0c4h 896 | ;---------------------------------------------------------- 897 | uart_timer2_init: 898 | mov scon, #050h ; uart mode 1 (8 bit), single processor 899 | 900 | orl t2con, #34h ; Timer 2: internal baudrate generate mode RX/TX 901 | mov rcap2h,#0FFh 902 | mov rcap2l,#0C4h 903 | clr es ; disable serial interrupt 904 | 905 | ret 906 | 907 | ;---------------------------------------------------------- 908 | ; init timer 1 for interval timing (fast 8 bit reload) 909 | ; interval is 125 microseconds 910 | ;---------------------------------------------------------- 911 | timer1_init: 912 | clr tr1 913 | anl tmod, #0fh ; clear all lower bits 914 | orl tmod, #20h; ; 8-bit Auto-Reload Timer, mode 2 915 | mov th1, #interval_t1_125u_12M 916 | mov tl1, #interval_t1_125u_12M 917 | setb et1 ; (IE.3) enable timer 1 interrupt 918 | clr KC85ClockTimeoutF 919 | clr KC85WordTimeoutF 920 | clr p1.0 921 | clr KC85DataBitValid 922 | setb p1.4 923 | mov KC85ClockCount,#0 924 | setb tr1 ; go 925 | ret 926 | 927 | ;---------------------------------------------------------- 928 | ; init timer 0 for interval timing (fast 8 bit reload) 929 | ; need 40-50mus intervals 930 | ;---------------------------------------------------------- 931 | timer0_init: 932 | clr tr0 933 | anl tmod, #0f0h ; clear all lower bits 934 | orl tmod, #02h; ; 8-bit Auto-Reload Timer, mode 2 935 | mov th0, #interval_t0_45u_12M 936 | mov tl0, #interval_t0_45u_12M 937 | setb et0 ; (IE.1) enable timer 0 interrupt 938 | setb TFModF ; see timer 0 interrupt code 939 | clr ATCommAbort ; communication abort flag 940 | mov ATBitCount,#0 941 | setb tr0 ; go 942 | ret 943 | 944 | ;---------------------------------------------------------- 945 | ; init timer 0 in 16 bit mode for inter-char delay of 0.13ms 946 | ;---------------------------------------------------------- 947 | timer0_diag_init: 948 | clr tr0 949 | anl tmod, #0f0h ; clear all lower bits 950 | orl tmod, #01h ; M0,M1, bit0,1 in TMOD, timer 0 in mode 1, 16bit 951 | mov th0, #interval_th_128u_12M 952 | mov tl0, #interval_tl_128u_12M 953 | setb et0 ; (IE.1) enable timer 0 interrupt 954 | clr TFModF ; see timer 0 interrupt code 955 | setb MiscSleepT0F 956 | setb tr0 ; go 957 | ret 958 | 959 | ;---------------------------------------------------------- 960 | ; init timer 0 in 16 bit mode for faked POST delay of of 20ms 961 | ;---------------------------------------------------------- 962 | timer0_20ms_init: 963 | clr tr0 964 | anl tmod, #0f0h ; clear all upper bits 965 | orl tmod, #01h ; M0,M1, bit0,1 in TMOD, timer 0 in mode 1, 16bit 966 | mov th0, #interval_th_20m_12M 967 | mov tl0, #interval_tl_20m_12M 968 | setb et0 ; (IE.1) enable timer 0 interrupt 969 | clr TFModF ; see timer 0 interrupt code 970 | setb MiscSleepT0F 971 | setb tr0 ; go 972 | ret 973 | 974 | ;---------------------------------------------------------- 975 | ; Id 976 | ;---------------------------------------------------------- 977 | RCSId DB "$Id: kbdbabel_kc85_ps2_8051.asm,v 1.4 2007/08/01 20:38:49 akurz Exp $" 978 | 979 | ;---------------------------------------------------------- 980 | ; main 981 | ;---------------------------------------------------------- 982 | Start: 983 | ; -- init the stack 984 | mov sp,#StackBottom 985 | 986 | ; -- enable interrupts 987 | setb ea 988 | 989 | ; -- some delay of 500ms to eleminate stray data sent by the PC/XT-Keyboard on power-up 990 | mov r0,#25 991 | InitResetDelayLoop: 992 | call timer0_20ms_init 993 | InitResetDelay: 994 | jb MiscSleepT0F,InitResetDelay 995 | djnz r0,InitResetDelayLoop 996 | 997 | ; -- init UART and timer0/1 998 | ; acall uart_timer2_init 999 | acall timer0_diag_init 1000 | 1001 | ; -- enable interrupts int0 1002 | setb ex0 ; external interupt 0 enable 1003 | setb it0 ; falling edge trigger for int 0 1004 | 1005 | ; -- clear all flags 1006 | mov B20,#0 1007 | mov B21,#0 1008 | mov B22,#0 1009 | mov B23,#0 1010 | 1011 | ; -- init the ring buffer 1012 | mov RingBufPtrIn,#0 1013 | mov RingBufPtrOut,#0 1014 | 1015 | ; -- cold start flag 1016 | setb ATCmdResetF 1017 | 1018 | ; ---------------- 1019 | Loop: 1020 | ; --- 9V generation with software 1021 | cpl p3.0 1022 | 1023 | ; -- check Keyboard receive status 1024 | jb RXCompleteF,LoopProcessData 1025 | 1026 | ; -- check Keyboard timeout, for Break-Code generation 1027 | jb KC85ClockTimeoutF,LoopProcessData 1028 | 1029 | ; -- check on new AT data received 1030 | jb ATCmdReceivedF,LoopProcessATcmd 1031 | 1032 | ; -- check if AT communication active. 1033 | jb TFModF,Loop 1034 | 1035 | ; -- check AT line status, clock line must not be busy 1036 | jnb p3.3,Loop 1037 | 1038 | ; -- check data line for RX or TX status 1039 | jb p3.5,LoopATTX 1040 | sjmp LoopATRX 1041 | 1042 | ;---------------------------------------------------------- 1043 | ; helpers for the main loop 1044 | ;---------------------------------------------------------- 1045 | ; --- Keyboard data received, process the received scancode into output ring buffer 1046 | LoopProcessData: 1047 | call TranslateToBuf 1048 | sjmp Loop 1049 | 1050 | ; ----------------- 1051 | LoopProcessATcmd: 1052 | ; -- AT command processing 1053 | call ATCmdProc 1054 | sjmp loop 1055 | 1056 | ; ---------------- 1057 | LoopATRX: 1058 | ; -- Host-do-Device communication 1059 | ; -- diag: host-do-dev ok 1060 | setb p1.1 1061 | 1062 | ; -- receive data on the AT line 1063 | mov ATRXCount,#0 1064 | mov ATRXBuf,#0 1065 | ; clr ATHostToDevIntF 1066 | setb ATHostToDevF 1067 | call timer0_init 1068 | 1069 | ; wait for completion 1070 | LoopTXWaitSent: 1071 | jb TFModF,LoopTXWaitSent 1072 | LoopCheckATEnd: 1073 | ljmp Loop 1074 | 1075 | ; ---------------- 1076 | LoopATTX: 1077 | ; -- Device-to-Host communication 1078 | ; -- send data on the AT line 1079 | ; some delay 0.15ms 1080 | call timer0_diag_init 1081 | LoopTXWaitDelay: 1082 | jb MiscSleepT0F,LoopTXWaitDelay 1083 | 1084 | LoopSendData: 1085 | ; send data 1086 | call BufTX 1087 | 1088 | ; -- keyboard reset/cold start: send AAh after some delay 1089 | jnb ATCmdResetF,LoopTXWaitDelayEnd 1090 | clr ATCmdResetF 1091 | ; -- optional delay after faked cold start 1092 | ; yes, some machines will not boot without this, e.g. IBM PS/ValuePoint 433DX/D 1093 | call timer0_20ms_init 1094 | LoopTXResetDelay: 1095 | jb MiscSleepT0F,LoopTXResetDelay 1096 | # -- send "self test passed" 1097 | mov r2,#0AAh 1098 | call RingBufCheckInsert 1099 | LoopTXWaitDelayEnd: 1100 | ljmp Loop 1101 | 1102 | ;---------------------------------------------------------- 1103 | ; Still space on the ROM left for the license? 1104 | ;---------------------------------------------------------- 1105 | LIC01 DB " Copyright 2007 by Alexander Kurz" 1106 | LIC02 DB " " 1107 | GPL01 DB " This program is free software; you can redistribute it and/or modify" 1108 | GPL02 DB " it under the terms of the GNU General Public License as published by" 1109 | GPL03 DB " the Free Software Foundation; either version 3, or (at your option)" 1110 | GPL04 DB " any later version." 1111 | GPL05 DB " " 1112 | GPL06 DB " This program is distributed in the hope that it will be useful," 1113 | GPL07 DB " but WITHOUT ANY WARRANTY; without even the implied warranty of" 1114 | GPL08 DB " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the" 1115 | GPL09 DB " GNU General Public License for more details." 1116 | GPL10 DB " " 1117 | ; ---------------- 1118 | end 1119 | --------------------------------------------------------------------------------