1696 lines
54 KiB
Text
1696 lines
54 KiB
Text
IBM 4704 Keyboard Analysis - 6019284(62-key)
|
|
============================================
|
|
2013/02/09, 2019/07/12
|
|
|
|
IBM 4704 Keyboard
|
|
=================
|
|
IBM capacitive switch models:
|
|
6019273 Model 100 50-key (grid layout) http://kishy.ca/?p=894
|
|
6019284 Model 200 62-key Alpha(60% layout) http://kishy.ca/?p=894
|
|
6019303 Model 300 77-key Expanded Alpha http://deskthority.net/photos-f62/ibm-6019303-t8502.html
|
|
6020218 Model 400 107-key Full key http://kishy.ca/?p=894
|
|
|
|
Alps switch(vintage Green) models:
|
|
5954339 Japanese 102-key http://deskthority.net/post87127.html#p87127
|
|
6112883 Japanese 102-key http://geekhack.org/index.php?topic=52888.msg1194489#msg1194489
|
|
6112884 Japanese 102-key http://geekhack.org/index.php?topic=50437.msg1193047#msg1193047
|
|
6341739 Chinese 102-key http://geekhack.org/index.php?topic=52888.msg1176566#msg1176566
|
|
|
|
|
|
|
|
Resourse
|
|
--------
|
|
The IBM 4704: lots of pictures and info
|
|
http://kishy.ca/?p=894
|
|
http://imgur.com/a/LaABs
|
|
|
|
Brochure:
|
|
http://ed-thelen.org/comp-hist/IBM-ProdAnn/4700.pdf
|
|
|
|
|
|
|
|
4704 Keyboard Protocol
|
|
======================
|
|
On powering up keyboard sends keyboard ID; A3h for 6019284(62-key), for example.
|
|
After that the keyboard enters FC command mode and waits for parameter data from host
|
|
so that it doesn't send any scancode until you send 'FF'(End of FC command mode).
|
|
|
|
|
|
Keyboard ID
|
|
-------------------------------
|
|
Model 100 50-key A2h
|
|
Model 200 62-key A3h
|
|
Model 300 77-key A4h
|
|
Model 400 107-key A5h
|
|
Japanese/Chinese 102-key A6h
|
|
|
|
|
|
Connector
|
|
---------
|
|
Keyboard Plug from front
|
|
|
|
DSUB-9
|
|
-------------
|
|
\ N 2 3 4 5 /
|
|
\ N N N N /
|
|
---------
|
|
2 GND
|
|
3 VCC 5V
|
|
4 DATA
|
|
5 CLOCK
|
|
N No connection/No pin.
|
|
|
|
|
|
Keyboard to Host
|
|
----------------
|
|
Data bits are LSB first and Pairty is odd. Clock has around 60us high and 30us low part.
|
|
|
|
____ __ __ __ __ __ __ __ __ __ _______
|
|
Clock \_____/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/
|
|
____ ____ ____ ____ ____ ____ ____ ____ ____ ____
|
|
Data ____/ X____X____X____X____X____X____X____X____X____X________
|
|
Start 0 1 2 3 4 5 6 7 P Stop
|
|
|
|
Start bit: can be long as 300-350us.
|
|
Inhibit: Pull Data line down to inhibit keyboard to send.
|
|
Timing: Host reads bit while Clock is hi.(rising edge)
|
|
Stop bit: Keyboard pulls down Data line to lo after 9th clock.
|
|
|
|
|
|
|
|
Host to Keyboard
|
|
----------------
|
|
Data bits are LSB first and Pairty is odd. Clock has around 60us high and 30us low part.
|
|
|
|
____ __ __ __ __ __ __ __ __ __ ________
|
|
Clock \______/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/
|
|
^ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ___
|
|
Data ____|__/ X____X____X____X____X____X____X____X____X____X \___
|
|
| Start 0 1 2 3 4 5 6 7 P Stop
|
|
Request by host
|
|
|
|
Start bit: can be long as 300-350us during start up and upto 2500us while key scanning
|
|
Request: Host pulls Clock line down to request to send a command.
|
|
Timing: After Request keyboard pull up Data and down Clock line to low for start bit.
|
|
After request host release Clock line once Data line becomes hi.
|
|
Host wirtes a bit while Clock is hi and Keyboard reads while low.
|
|
Stop bit: Host releases or pulls up Data line to hi after 9th clock and waits for keybaord pull down the line to lo.
|
|
|
|
|
|
|
|
Scancodes
|
|
---------
|
|
Keyboard doesn't send Break code for all keys except for Alt by default.
|
|
|
|
6019284 62-key:
|
|
,-----------------------------------------------------------.
|
|
| `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|**1|BS |
|
|
|-----------------------------------------------------------|
|
|
|Tab | Q| W| E| R| T| Y| U| I| O| P| ¢| \| PD2|
|
|
|-----------------------------------------------------------|
|
|
|Ctrl | A| S| D| F| G| H| J| K| L| ;| '| {}| PD3|
|
|
|-----------------------------------------------------------|
|
|
|Shif| <>| Z| X| C| V| B| N| M| ,| ,| /|**2|Shift |
|
|
|-----------------------------------------------------------|
|
|
|Reset|blk|Alt | Space |Alt |blk|Enter|
|
|
`-----------------------------------------------------------'
|
|
+----------+---------------------+----------+----------+
|
|
|` 00|PD1 04|Caps 20|LShift 30|Reset 31|
|
|
|1 18|q 05|a 21|<> 3E|Rblank 41|
|
|
|2 19|w 06|s 22|z 32|Alt 3F|
|
|
|3 1A|e 13|d 23|x 33|Space 40|
|
|
|4 10|r 14|f 24|c 34|Alt 3F|
|
|
|5 11|t 15|g 25|v 35|Lblank 42|
|
|
|6 12|y 16|h 26|b 36|Enter 2F|
|
|
|7 08|u 17|j 27|n 37| |
|
|
|8 09|i 01|k 28|m 38| |
|
|
|9 0A|o 02|l 29|, 39| |
|
|
|0 0F|p 03|; 2A|. 3A| |
|
|
|- 1F|¢ 1B|' 2B|/ 3B| |
|
|
|= 0D|\ 1C|{} 2C|**2 3C| |
|
|
|**1 0C|PD2 1D|PD3 2D|RShift 3D| |
|
|
|BS 0E| | | | |
|
|
+----------+---------------------+----------+----------+
|
|
Bit7 is 'press flag' which set 1 on press and 0 on release when break code is enabled.
|
|
|
|
NOTE: When break code is enabled the key sends scancode with setting 7th bit on press
|
|
and without it on release. That is, '`' sends 80h on press and 00h on release.
|
|
|
|
|
|
Keyboard command
|
|
----------------
|
|
Keyboard accepts these commands from host.
|
|
|
|
Description Entry point
|
|
-----------------------------------------------------------
|
|
FF Soft Reset 0008h
|
|
FE Resend 00e8h
|
|
FD Buzzer(emits a short beep) 00edh
|
|
FC Set Key Flag 00f6h
|
|
FB Soft Reset 0008h
|
|
FA Reset 0000h
|
|
|
|
|
|
Keyboard response
|
|
-----------------
|
|
Keyobard sends these bytes to host.
|
|
|
|
Description Entry point
|
|
-----------------------------------------------------------
|
|
FE Overflow(key event/receive data) 00c5h, 0346h
|
|
Memory test error 0224h
|
|
FD Command out of bound 00d8h
|
|
Key out of bound
|
|
7E Read/Parity error in receive from host 00bch
|
|
80-FB? scan code(make)
|
|
00-7B? scan code(break)
|
|
note: Alps model spits scan code 7B(FB) at least.
|
|
|
|
|
|
Set Key Flag command(FC)
|
|
------------------------
|
|
After 'Power on Reset' firmware enters this command mode and waits for data from host,
|
|
so that you don't need to send 'FC' and it doesn't send any scancode until you send 'FF' to exit this mode.
|
|
With Alps models you need to send 'FC' command to enter this mode.
|
|
|
|
Data sent from host:
|
|
|
|
bit: 7 6 ... 0
|
|
en | |
|
|
| `-----`--- scan code
|
|
`------------- enable bit(0: enable repeat, 1: enable break)
|
|
|
|
00-7B Enable repeat
|
|
80-FB Enable break
|
|
FE Resend(011ah) no need to use
|
|
FF End(0114h) exits FC command mode.
|
|
|
|
Response from keyboard:
|
|
FD Out of bound - Invalid scancode
|
|
-- OK - No response means that command is accepted.
|
|
|
|
Examples:
|
|
To enable break code of all keys you have to send following commands.
|
|
|
|
FC 80 81 ... FB FF
|
|
|
|
|
|
|
|
4704 Hardware
|
|
=============
|
|
Power consumption
|
|
-----------------
|
|
This keyboard is very power greedy, it consumes around 170mA
|
|
and USB port may not be able to supply enough current.
|
|
|
|
5.061V - No load. Power from Powered USB Hub.
|
|
4.946V 133.6mA max without Buzzer
|
|
4.911V 171.0mA max with Buzzer
|
|
|
|
|
|
Controller Board
|
|
----------------
|
|
NOTE: TWO BOLTS OF CONTROLLER BOARD IS CRITICAL.
|
|
Controller PCB and tab of bottom plate of key assembly with two hex bolts, these
|
|
connect between controller ground to the metal bottom plate of key switch assembly.
|
|
This connection is very critical to sense key state, keys will not be registered
|
|
unless they are tightened up with the bolts
|
|
|
|
Controller: 8048 DIP40 with 1KB ROM and 64B RAM(8748H?)
|
|
Clock: ??MHz Resonator? TODO: machine cycle: ??us
|
|
Buffer: 7917 hex buffer
|
|
Sensor: IBM custom chip for capacitive sense
|
|
|
|
|
|
8048 Pin configuration
|
|
----------------------
|
|
Bus:
|
|
bit: D7 D6 D5 D4 D3 D2 D1 D0
|
|
use: BZ CLK DAT ??? G S2 S1 S0
|
|
|
|
use dir description
|
|
----------------------------------------------------------------------
|
|
S0 out Sensor select
|
|
S1 out Sensor select
|
|
S2 out Sensor select
|
|
G out Sensor strobe?
|
|
??? Sensor state out(drive/charge? via 7917 buffer)
|
|
DAT out Data via buffer logic with 2K pull up resistor
|
|
CLK out Clock via buffer logic with 2K pull up resistor
|
|
BZ out Drive Buzzer via 7917 buffer with 2KOhm pull up resistor(H:on/L:off)
|
|
T0:
|
|
input of Sensor state(H:on/L:off)
|
|
T1:
|
|
input of Clock line with 1KOhm pull up resistor
|
|
INT:
|
|
input of Data line with 1KOhm pull down resistor
|
|
PORT1:
|
|
P10-P17 matrix row0-7
|
|
PORT2:
|
|
P20 matrix row8 or I(keyboard identity bits row)
|
|
|
|
|
|
Connections
|
|
-----------
|
|
8048 Sensor
|
|
-----------------------------
|
|
D0-2 ====/===== S0-2(Sensor)
|
|
D3 ---------- STR(Sensor)
|
|
7917 buffer
|
|
D4 --|>--+--- OUT(Sensor)
|
|
T0 ------'
|
|
|
|
8048 line
|
|
-----------------------------
|
|
Vcc Vcc
|
|
| |
|
|
R 1K R 2K
|
|
T1 ---+-<|-+- CLK
|
|
D6 ---|>---'
|
|
Vcc
|
|
|
|
|
R 2K
|
|
D6 ---|>---+- DAT
|
|
T1 -+---<|-'
|
|
R 1K
|
|
|
|
|
GND
|
|
Vcc
|
|
|
|
|
R 2K
|
|
D7 ---|>---+- BZ
|
|
|
|
|
|
Interruption
|
|
------------
|
|
I disable at 0015h
|
|
TCNTI disable at 0014h
|
|
|
|
|
|
IBM Capacitive sensor chip
|
|
--------------------------
|
|
Silver canned package
|
|
|
|
Pin Connection Desciption
|
|
----------------------------------------------------------------
|
|
Input(C0-7) Matrix Col0-7 8 column line inputs
|
|
Col select(S0-2)8048:D0-D2 Select column line to sense
|
|
Strobe(STR) 8048:D3 Strobe
|
|
Output(OUT) 848:T0 Read Key state(0:pressed/1:released)
|
|
|
|
Pinout from bottom:
|
|
+-----------++------+-------+-------+-------+
|
|
| 1 2 3 4 5 ||1:LCL |6:LCC |B:S0 |G:C5 |
|
|
| 6 7 8 9 ||2:GND |7:LCM |C:? |H:C4 |
|
|
| A B ||3:Out |8:S2 |D:C6 |I:C3 |
|
|
| C D E F ||4:STR |9:S1 |E:C0 |J:C2 |
|
|
| G H I J K ||5:VCC |A:C7 |F:? |K:C1 |
|
|
+-----------++------+-------+-------+-------+
|
|
|
|
8048 Sensor
|
|
D0-2 ====/===== S0-2
|
|
D3 ---------- STR
|
|
7917 buffer
|
|
D4 --|>--+--- OUT
|
|
T0 ------'
|
|
|
|
Speculation: 8048:D4 is used to prepare to sense capacitance.(charge key capcitor?)
|
|
|
|
Procedure:
|
|
at 030dh:
|
|
D0-2=<column> ; select column S0-2
|
|
D4=1 ; Prepare sensor(Charge?)
|
|
P1/P2=<row> ; select row
|
|
D0-4=<default> ; 00010(bus=c2h)
|
|
D3=1 ; Strobe
|
|
P1/P2=0 ; unselect row
|
|
read T0 ; see key state
|
|
|
|
at 01afh:
|
|
D0-2=<column>
|
|
D4=1
|
|
D0-2=2(010) ; select col2
|
|
P2=01h ; select row
|
|
D3=1 ; Strobe
|
|
P2=00h ; unselect row
|
|
read T0
|
|
|
|
|
|
Keyswitch Matrix
|
|
----------------
|
|
6019284(62-key):
|
|
|0 1 2 3 4 5 6 7
|
|
-|--------------------------------------------------------------
|
|
0|Enter RShift JIS_ PD3 PD2 \| LofBS BS
|
|
1|RAlt RBlank /? '" {} Cent! - =
|
|
2|, . l ; o p 9 0
|
|
3|m n k j u i 7 8
|
|
4|Spc b g h t y 5 6
|
|
5|v c d f e r 3 4
|
|
6|LAlt z x s a w q 2
|
|
7|Reset LBlank ISO\ LShift CapLock PD1 `~ 1
|
|
8|_ x _ _ x x _ _ (Identity bits: 32h)
|
|
|
|
Two 15-line flat cables shown from bttom of PCB:
|
|
|
|
Flatcable A Flatcable B
|
|
/ \/ \
|
|
0123456789ABCDE0123456789ABCDE
|
|
--8-----01234567----76543210--
|
|
Id row col -:GND
|
|
|
|
|
|
Keyboard Identity Bits
|
|
----------------------
|
|
4704 keyboards has its identity bit marks on PCB matrix and it is readable
|
|
from firmware so that it can select key layout depending on this.
|
|
|
|
PCB pictures:
|
|
Model 100:
|
|
http://kishy.dyndns.org/wp-content/uploads/2013/02/6019273_0011.jpg
|
|
Model 200:
|
|
http://kishy.dyndns.org/wp-content/uploads/2013/02/6019284_0020_capacitive-pcb-top.jpg
|
|
Model 300:
|
|
http://kbtalking.cool3c.com/article/23272
|
|
Model 400:
|
|
http://kishy.dyndns.org/wp-content/uploads/2011/09/6020218_distrib_0019.jpg
|
|
|
|
|
|
|
|
4704 Firmware
|
|
=============
|
|
|
|
Startup sequence
|
|
----------------
|
|
Power on Reset(0000h):
|
|
Short Buzzer
|
|
turns Buzzer(BZ=L) on at 0002h
|
|
turns Buzzer(BZ=H) off at 01adh
|
|
Initialize all memory(3fh-00h)
|
|
Initialize other registers
|
|
Read keyboard id and set default parameter at 01afh
|
|
set break flag for Alt key by default
|
|
Test and clear memory(3fh..00h) at 0202h
|
|
Test program memory at 0214h
|
|
r4=($21&07h)|50h at 0020h
|
|
Send test result at 022dh
|
|
sends [a0h | (keyboard id&f0h)>>4] on success
|
|
6019284 seneds a3h on success
|
|
Wait for data from host - it expects FC command data followed by ffh(end)
|
|
Main loop
|
|
|
|
Soft Reset(0008h):
|
|
Initialize all memory(20h-00h) It retains parameter memory.
|
|
Initialize other registers
|
|
r4=($21&07h)|50h at 0020h
|
|
Main loop
|
|
|
|
|
|
Memory Map
|
|
----------
|
|
RAM(64 bytes):
|
|
$01-07 *Bank0* Registers r0-r7
|
|
r0 temporary use
|
|
r1 temporary use
|
|
r2 temporary use
|
|
r3 row mask of scan 024dh, 0257h
|
|
r4 bus default value
|
|
7 6 5 4 3 2 1 0
|
|
| | | | | | | |
|
|
| | | | | `-`-`------ Sensor column select
|
|
| | | | `------------ Sensor strobe?
|
|
| | | `-------------- Sensor column set?
|
|
| | `---------------- Data
|
|
| `------------------ Clock
|
|
`-------------------- Buzzer control(L:on/H:off)023ch
|
|
=$21&07h|50h: call 0020h at 001ch soft reset (52h=0101 0010)
|
|
=$21&07h|50h: call 0020h at 0109h command FC (52h=0101 0010)
|
|
=r4|80h: at 00f4h(FD command)
|
|
=r4&7fh: at 023ch(Main)
|
|
=r4&f0h: at 0200h
|
|
r5 repeat dealy/interval
|
|
used at 02d7h
|
|
=07h at 02d9h
|
|
=28h at 02ddh
|
|
=28h at 02e1h
|
|
*r6 0bh at 00edh(FD command)
|
|
used at 0232h
|
|
r7 received data from host
|
|
temporary use at 01afh
|
|
temporary use at 005dh
|
|
=r4&c0h(current bus value?) 0247h
|
|
$08-17 8-level stack(2*8)
|
|
$0E
|
|
: last key state(1:pressed/0:released)
|
|
$15 (0E-15)=8*8=64 matrix(for 50-key and 62-key?)
|
|
$16
|
|
: last key state(1:pressed/0:released)
|
|
$1C (16-1C)=7*8=56 (extension for 77-key?)
|
|
|
|
$18-1F *Bank1* Registers 0-r7
|
|
Outgoing buffer of data sent to host
|
|
$1D r5 outgoing buffer top
|
|
$1E r6 outgoing buffer
|
|
$1F r7 outgoing buffer bottom
|
|
|
|
|
|
$20 Resend buffer: code last sent used by 'Resend'(FE)
|
|
|
|
$21 Keyboard identity bits
|
|
0011 0010 (6019284: 32h read from Row(I))
|
|
||| ||||
|
|
||| |```- Sensor chip control(bus value)??
|
|
||| `---- ???
|
|
```------ keyboard model id
|
|
|
|
set at 01fah on Power on Reset: 32h from row8(I)(6019284)
|
|
got at 0020h on Soft Reset:
|
|
got at 034eh on translate into scan code:
|
|
got at 0125h on command FC:
|
|
set from scan 8(I) row at 01fdh
|
|
|
|
Keyboard model id:
|
|
Model 100 6019273 50-key (grid layout): 22h(from picture)
|
|
Model 200 6019284 62-key Alpha(60% layout): 32h
|
|
Model 300 6019303 77-key Expanded Alpha: 42h?(from dump list)
|
|
Model 400 6020218 107-key Full key: no identity
|
|
Looks like this firmware does not support 107-key.
|
|
|
|
IBM 4704 keyboards:
|
|
It seems Model 100, 200 and 300 keyboards share one firmware code and
|
|
have small square copper patterns on righ side of PCB to identify
|
|
its layout. See following pictures. Model 400 may use another firmware.
|
|
|
|
$22-3F 30-byte Parameter RAM(Repeat and Break flags)
|
|
Parameter byte is comprised of four flag pairs. Flags occupies two bits each a key.
|
|
Parameter RAM can have flags for 120(4*30) keys.
|
|
|
|
Parameter byte and flags:
|
|
bit 7 6 5 4 3 2 1 0
|
|
3r 3b 2r 2b 1r 1b 0r 0b
|
|
:
|
|
$3F End of Memory(64 bytes)
|
|
|
|
|
|
|
|
|
|
Entry points
|
|
------------
|
|
0020 Soft Reset r4=($21&07h)|50h = (32h&07h)|50h=52h
|
|
0029 r1=r1+(a), a=r0 (page 0)
|
|
002c (F0=0: send or receive data with 'interpret command mode')
|
|
002d Receive data or Send scan code
|
|
0035 Send scan code
|
|
return: F1=1
|
|
0082 Receive data from host
|
|
condition: F0==0 interpret command
|
|
F0==1 return receive data(a)
|
|
return: F1=1(ERROR) 00c7 (Receive ACK/Parity Error) 00b6,00ce
|
|
F1=0?
|
|
a=recieve data, (with F0=0 00dc) F0==0 means 'data received'
|
|
00bc push 7f(error) into outgoing buffer
|
|
00be push data/response into outgoing buffer(r5,r6,r7)
|
|
00d2 interpret keyboard command
|
|
00de calculate parity
|
|
|
|
01a4 r1=r1+(a), a=r0 (page 1)
|
|
01a5 r1=r1+a, a=r0
|
|
01a9 Buzzer and Scan row8(*) and set param: call from Power on Reset 0018h
|
|
01af Read keyboard identity bits from row8(I) and set param: - call from command FC 0107h
|
|
0202 Memory Test(Power on Reset)
|
|
|
|
0230 Main loop: send, receive data and scan
|
|
send/receive: call 002c
|
|
0263 **Scan matrix**(F1==0): F1=1, r1=15h, r2=3fh, r3=01h
|
|
0287 **Scan matrix**(F1==1): F1=0, r1=1ch, r2=77h, r3=02h
|
|
0325 get key configure flags(a=-----rb; where r:repeat enable, b:break enable)
|
|
0339 queue data at bottom of outgoing buffer
|
|
034e translate into scan code
|
|
scan code table1/table2
|
|
|
|
|
|
Keyboard command entry points
|
|
-----------------------------
|
|
FF: jump_table0 Soft Reset(008h)
|
|
FE: jump_table1 Resend(return content of $20)
|
|
FD: jump_table2 Short beep BZ
|
|
FC: jump_table3 parameter configuration(100h)
|
|
FB: jump_table4 Soft Reset(008h)
|
|
FA: jump_table5 Reset(000h)
|
|
|
|
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;
|
|
; 8048 Disassembly of IBM 6019284 ROM dump
|
|
;
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
; label mnemonic ; address comment
|
|
;-------------------------------------------------------------------------------------
|
|
org 000h
|
|
; jump_table:5 Hard Reset/Power on Reset
|
|
mov a,#07fh ; 0000 - a=7f Power on Reset
|
|
outl bus,a ; 0002 - BZ=L(off), others=H
|
|
mov r0,#03fh ; 0003 - r0=3fh
|
|
clr f1 ; 0005 - F1=0
|
|
jmp X000c ; 0006 -
|
|
; jump_table:0,4 Soft Reset
|
|
mov r0,#020h ; 0008 - r0=20h $20=resend buffer
|
|
clr f1 ; 000a -
|
|
cpl f1 ; 000b - F1=1
|
|
|
|
;;;;;;;;;;;;;;;;;;
|
|
; initialize memory
|
|
; hard reset clear 3f-00h F1=0
|
|
; soft reset clear 20-00h F1=1
|
|
X000c: clr f0 ; 000c - F0=0
|
|
clr a ; 000d - a=0
|
|
X000e: mov @r0,a ; 000e - @r0=0 r0=$3f(hard)/$20(soft)
|
|
djnz r0,X000e ; 000f - clear RAM 3f/20h to $00
|
|
mov psw,a ; 0011 - psw=0
|
|
outl p1,a ; 0012 - p1=0
|
|
outl p2,a ; 0013 - p2=0
|
|
dis tcnti ; 0014 - disable timer overflow
|
|
dis i ; 0015 - disable INT
|
|
jf1 X001c ; 0016 - jump if F1==1(Soft Reset?)
|
|
|
|
; F1==0 Power on Reset
|
|
call X01a9 ; 0018 - read keyboard id and set default parameter
|
|
jmp X0202 ; 001a - Memory Test and go to Main
|
|
|
|
; F1==1 Soft Reset
|
|
X001c: call X0020 ; 001c - ; r4=$21&07h|50h(52h?), a=r4
|
|
jmp X0230 ; 001e - ; go to Main
|
|
|
|
;;;;;;;;;;;;;;;;;;
|
|
; Set r4
|
|
: INPUT: r4???
|
|
: RETURN: a=r4(original)
|
|
; r4=$21&07h|50h
|
|
;
|
|
X0020: mov r0,#021h ; 0020 - r0=21h(keyboad identity bits)
|
|
mov a,@r0 ; 0022 - a=($21)
|
|
anl a,#007h ; 0023 - a=a&07h
|
|
orl a,#050h ; 0025 - a=a|50h
|
|
xch a,r4 ; 0027 - swap a,r4
|
|
ret ; 0028 -
|
|
|
|
; read program memory @page0
|
|
; INPUT: a:address
|
|
; OUTPUT: a=(a)@page0
|
|
X0029: movp a,@a ; 0029 -
|
|
jmp X01a5 ; 002a - r1=r1+a, a=r0
|
|
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;
|
|
; Receive data or Send scan code
|
|
; INPUT: F0=0:interpret command/1:retern data used in Receive command/data
|
|
; OUTPUT: F0=0(received)/1(not received)
|
|
; DONE: a=0, F1=1, buffer rotate
|
|
X002c: clr f0 ; 002c - F0=0
|
|
X002d: jnt1 X0082 ; 002d - go to receive if T1(CLK)==L
|
|
sel rb1 ; 002f - switch to bank1
|
|
mov a,r5 ; 0030 - a=r5(bank1) r5(bank1): scan code buffer
|
|
sel rb0 ; 0031 - switch to bank0
|
|
jnz X0035 ; 0032 - jump if r5(bank1)!=0
|
|
retr ; 0034 - return if r5(bank1)==0 buffer empty
|
|
|
|
;;;;;;;;;;;;;;;;;;
|
|
; Send scan code
|
|
; INPUT: a=data
|
|
; OUTPUT: F1=1:Sent,Rotate,Data ready/0:???
|
|
X0035: dec a ; 0035 - a--
|
|
clr c ; 0036 - c=0
|
|
call X00de ; 0037 - c=parity calc
|
|
jnt1 X0082 ; 0039 - go to receive if T1(CLK)=L
|
|
; Start bit
|
|
anl bus,#0bfh ; 003b - [CLK=L]
|
|
orl bus,#020h ; 003d - [DATA=H] [[[Start bit]]]
|
|
mov r0,#010h ; 003f - r0=10h
|
|
|
|
|
|
; check inhibited(DATA==L) - check DATA line released by host
|
|
X0041: jni X0047 ; 0041 - jump if DATA==L LOOP>
|
|
jni X0049 ; 0043 - jump if DATA==L
|
|
jmp X0054 ; 0045 - cont. if DATA==H
|
|
X0047: jmp X0049 ; 0047 -
|
|
X0049: djnz r0,X0041 ; 0049 - <LOOP timeout?
|
|
; time out - end
|
|
orl bus,#040h ; 004b - [CLK=H]
|
|
anl bus,#0dfh ; 004d - [DATA=L] [[[idle state]]]
|
|
retr ; 004f - return send end(give up with inhibited)
|
|
|
|
|
|
; check data==7eh Keep data in 'Resend' buffer unless it is 7eh
|
|
X0050: xrl a,#07eh ; 0050 - revert a
|
|
jmp X005d ; 0052 -
|
|
|
|
X0054: mov r0,#020h ; 0054 - r0=20h 'Resend' Buffer
|
|
xrl a,#07eh ; 0056 - a=a^7eh(0111 1110)
|
|
jz X0050 ; 0058 - jump if a==7eh
|
|
; a!=7eh retain data to $20(resend buffer) if data is not 7eh
|
|
xrl a,#07eh ; 005a - revert a
|
|
mov @r0,a ; 005c - $20=a retain a to 'Resend' buffer
|
|
|
|
|
|
; Data bit0-7 and Parity(c)
|
|
; Pulse H:18/L:9??
|
|
X005d: mov r7,#009h ; 005d - r7=9
|
|
X005f: mov r0,#009h ; 005f - r0=9 LOOP>>
|
|
jb0 X0069 ; 0061 - jump if a:bit0==1
|
|
; a:bit0==0
|
|
; send DATA=0
|
|
anl bus,#0dfh ; 0063 - [DATA=L]
|
|
orl bus,#040h ; 0065 - [CLK=H]
|
|
jmp X006f ; 0067 -
|
|
; a:bit0==1
|
|
; send DATA=1
|
|
X0069: orl bus,#020h ; 0069 - [DATA=H]
|
|
orl bus,#040h ; 006b - [CLK=H]
|
|
jmp X006f ; 006d -
|
|
; hold CLK=H
|
|
X006f: djnz r0,X006f ; 006f - 9*2cycle delay (around 60us??)
|
|
anl bus,#0bfh ; 0071 - [CLK=L]
|
|
rrc a ; 0073 - a=a>>1, c=a:bit0
|
|
djnz r7,X005f ; 0074 - <<LOOP
|
|
; Stop bit
|
|
; a=0, F1=1, buffer rotate
|
|
anl bus,#0dfh ; 0076 - [DATA=L] [Idle] End
|
|
clr a ; 0078 - a=0
|
|
clr f1 ; 0079 -
|
|
cpl f1 ; 007a - F1=1 [Sent?]
|
|
orl bus,#040h ; 007b - [CLK=H] [Idle] End
|
|
; remove from outgoing buffer: r7=0, r6=r7, r5=r6
|
|
sel rb1 ; 007d - switch to bank1
|
|
xch a,r7 ; 007e -
|
|
xch a,r6 ; 007f -
|
|
xch a,r5 ; 0080 - 0->r7->r6->r5->a [Bank1 Buffer rotate]
|
|
retr ; 0081 - retr reverts to bank0
|
|
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;
|
|
; Receive command/data from host
|
|
; INPUT: F0=0:interpret command/1:return data(used by command)
|
|
; OUTPUT: F0=0(received)/1(not received)
|
|
; F1=1:Error/0:OK
|
|
; a: data
|
|
; c: parity
|
|
; F1: 0: Receive or Send 1: Receive
|
|
;
|
|
X0082: jf1 X0086 ; 0082 - jump if F1==1
|
|
; F1==0
|
|
jmp X002d ; 0084 - Can't recevie, do 'Receive or Send' again
|
|
; F1==1
|
|
X0086: mov r0,#006h ; 0086 - r0=6h
|
|
X0088: djnz r0,X0088 ; 0088 - 6*2cycle dealy
|
|
jt1 X00cb ; 008a - return if T1(CLK)==H
|
|
anl bus,#0bfh ; 008c - [CLK=L]
|
|
orl bus,#020h ; 008e - [DATA=H] [Start bit]
|
|
mov r0,#011h ; 0090 -
|
|
X0092: djnz r0,X0092 ; 0092 - 11*2cycle delay
|
|
mov r7,#009h ; 0094 - r7=9h
|
|
X0096: orl bus,#040h ; 0096 - LOOP>[CLK=H] [Clock up for receive]
|
|
mov r0,#008h ; 0098 -
|
|
X009a: djnz r0,X009a ; 009a - 8*2cycle delay
|
|
anl bus,#0bfh ; 009c - [CLK=L] [Clock down]
|
|
jni X00a9 ; 009e - jump if INT(DATA)==L [Read bit] Read twice for debounce?
|
|
; DATA==H
|
|
orl a,#001h ; 00a0 - a:bit0=1
|
|
jni X00ad ; 00a2 - jump if INT(DATA)==L
|
|
; DATA==H
|
|
X00a4: rrc a ; 00a4 - a=a>>1 with carry [Next bit]
|
|
djnz r7,X0096 ; 00a5 - <LOOP
|
|
jmp X00b0 ; 00a7 - [go to Stop]
|
|
; DATA==L
|
|
X00a9: anl a,#0feh ; 00a9 - a:bit0=0
|
|
jni X00a4 ; 00ab - jump if INT(DATA)==L
|
|
; DATA==H
|
|
X00ad: clr f1 ; 00ad - F1=0 [Receive Error]
|
|
jmp X00a4 ; 00ae -
|
|
|
|
|
|
; wait for Stop/ACK (DATA=H)
|
|
; F0: 0=jump table, 1=return(with F0=0)
|
|
X00b0: orl bus,#040h ; 00b0 - [CLK=H] [Idle] End
|
|
mov r0,#004h ; 00b2 -
|
|
X00b4: djnz r0,X00b4 ; 00b4 - 4*2cycle? 8*0.2us=1.6us?
|
|
jni X00c7 ; 00b6 - jump if INT(DATA)==L [Stop Error] *no error response?
|
|
; DATA==H
|
|
anl bus,#0dfh ; 00b8 - [DATA=L] [Idle] End
|
|
jf1 X00cc ; 00ba - jump if F1==1
|
|
; F1==0 [Receive Error]
|
|
|
|
|
|
; push 7eh into outgoing buffer (Receive Error at 00bah/Parity Error at 00ceh)
|
|
X00bc: mov a,#07eh ; 00bc - 7eh: error response
|
|
|
|
; push data into top of outgoing buffer(Error response)
|
|
; a:data
|
|
; r5=a, r6=r5, r7=r6
|
|
X00be: sel rb1 ; 00be - switch to bank1
|
|
inc a ; 00bf - a++
|
|
xch a,r5 ; 00c0 - a->r5->r6->r7->a
|
|
xch a,r6 ; 00c1 -
|
|
xch a,r7 ; 00c2 -
|
|
jz X00cb ; 00c3 - jump if a==0
|
|
mov r7,#0ffh ; 00c5 - r7=ffh overflow [Over flow:FE]
|
|
|
|
X00c7: anl bus,#0dfh ; 00c7 - [DATA=L] [Idle] End
|
|
clr f1 ; 00c9 -
|
|
cpl f1 ; 00ca - F1=1 [Error flag]
|
|
X00cb: retr ; 00cb -
|
|
|
|
|
|
|
|
; check parity of recieve data
|
|
; F1==1
|
|
X00cc: call X00de ; 00cc - call parity calc
|
|
jc X00bc ; 00ce - jump if carryflag=1 (Parity ERROR)
|
|
; parity OK
|
|
jf0 X00dc ; 00d0 - jump if F0==1
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;
|
|
; F0==0
|
|
; Interpret command
|
|
;
|
|
cpl a ; 00d2 - compliment a ffh-a(command)
|
|
add a,#jump_table ; 00d3 - a=a+#jump_table
|
|
jc X00d8 ; 00d5 -
|
|
jmpp @a ; 00d7 - jump table [Keyboard command]
|
|
; Command Out bound Error
|
|
X00d8: mov a,#0fdh ; 00d8 - error response: FD
|
|
jmp X00be ; 00da -
|
|
|
|
;;;;;;;;;;;;;;;;;
|
|
; F0==1
|
|
; Return data
|
|
X00dc: cpl f0 ; 00dc - F0=~F0(=0)
|
|
ret ; 00dd -
|
|
;
|
|
; recieve data/command
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;
|
|
; calculate parity: 'c' depends on number of '1' in 'a'
|
|
; INPUT: a=data
|
|
; OUTPUT: c(carry flag)
|
|
X00de: mov r0,#008h ; 00de - b8 08 8. r0=8h
|
|
X00e0: rr a ; 00e0 - 77 w a=a>>1
|
|
jb0 X00e4 ; 00e1 - 12 e4 .d jump if a:bit0==1
|
|
cpl c ; 00e3 - a7 ' compliment carry flag
|
|
X00e4: djnz r0,X00e0 ; 00e4 - e8 e0 h` jump if --r0!=0
|
|
cpl c ; 00e6 - a7 '
|
|
ret ; 00e7 - 83 .
|
|
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;
|
|
; Keyboard command jump table
|
|
;
|
|
; jump_table:1 FE Resend(return content of $20)
|
|
X00e8: mov r0,#020h ; 00e8 - $20
|
|
mov a,@r0 ; 00ea - a=$20 get from resend buffer
|
|
jmp X00be ; 00eb - push into outogoing buffer
|
|
|
|
; jump_table:2 FD r6=0bh, r4=r4|80h
|
|
mov r6,#00bh ; 00ed - r6=0bh BZ duration(scan cycles)?
|
|
orl bus,#080h ; 00ef - BZ=H(on)
|
|
mov a,r4 ; 00f1 -
|
|
orl a,#080h ; 00f2 - BZ=H
|
|
mov r4,a ; 00f4 - r4=r4|80h BZ=H(on) bus-default
|
|
retr ; 00f5 -
|
|
|
|
; jump_table:3 FC
|
|
mov r1,#01eh ; 00f6 - r1=1eh
|
|
jmp X0100 ; 00f8 -
|
|
|
|
;
|
|
; keyboard commands:
|
|
;
|
|
; FF: jump_table0 Soft Reset(008h)
|
|
; FE: jump_table1 Resend(return content of $20)
|
|
; FD: jump_table2 BZ set BZ=H(on) to bus and r4(bus-default), duration to r6
|
|
; FC: jump_table3 Set key configuration
|
|
; FB: jump_table4 Soft Reset(008h)
|
|
; FA: jump_table5 Reset(000h)
|
|
;
|
|
jump_table: db 008h,0e8h,0edh,0f6h,008h,000h ; 00fa .hmv..
|
|
;
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;
|
|
; command FC parameter configuration
|
|
; clear $22-3f, then set data received from host
|
|
;
|
|
; r4:
|
|
; set to $21&07h|50h
|
|
; r7: received data
|
|
; r7=data|7fh
|
|
; F0=0 if data:bit7=1
|
|
; F0=1 if data:bit7=0
|
|
;
|
|
; data received(r7):
|
|
; FF End(0114h)
|
|
; FE Resend and receive again(011ah)
|
|
; FF-80 F0=0 if bit7 of r7 is set
|
|
; 7F-00 F0=1 if bit7 of r7 is reset
|
|
;
|
|
;
|
|
|
|
;;;;;;;;;;;;;;;;;;
|
|
; clear parameter configuration RAM $3f..22
|
|
; INPUT: r1=1eh=30
|
|
; called at 00f6h
|
|
X0100: clr a ; 0100 - a=0
|
|
mov r0,#03fh ; 0101 - r0=3f
|
|
X0103: mov @r0,a ; 0103 - $3f=a
|
|
dec r0 ; 0104 - r0--
|
|
djnz r1,X0103 ; 0105 -
|
|
call X01af ; 0107 - Read keyboar id and set parameter flags
|
|
call X0020 ; 0109 - r4=($21 & 07h | 50h) =52h
|
|
|
|
;;;;;;;;;;;;;;;;;;
|
|
; data receive from host
|
|
;
|
|
X010b: clr f0 ; 010b - LOOP>>
|
|
cpl f0 ; 010c - F0=1
|
|
X010d: call X002d ; 010d - receive/send data with F0=1
|
|
jf0 X010d ; 010f - LOOP while F0==1
|
|
|
|
|
|
; received data from host(F0==0)
|
|
mov r7,a ; 0111 - r7=data received
|
|
cpl c ; 0112 - c=~c
|
|
cpl a ; 0113 - a=~a
|
|
|
|
;;;;;;;;;;;;;;;;;
|
|
; a==FF *End*
|
|
jz X013b ; 0114 - return if a==FF
|
|
xrl a,#001h ; 0116 -
|
|
jnz X011e ; 0118 - jump if a!=FE
|
|
|
|
;;;;;;;;;;;;;;;;;
|
|
; a==FE *Resend*
|
|
call X00e8 ; 011a - Resend and continue...
|
|
jmp X010b ; 011c - <<LOOP Send/Receive loop again
|
|
|
|
;;;;;;;;;;;;;;;;;
|
|
; else *Set flag*
|
|
; data:bit7=1:enable break/0:enable repeat
|
|
X011e: mov a,r7 ; 011e - a=r7(data received)
|
|
jb7 X0122 ; 011f - jump if a:bit7==1 (1xxx xxxx)
|
|
cpl f0 ; 0121 - F0=~F0=1 if a:bit7==0 [F0=1 means data:bit7==0]
|
|
X0122: anl a,#07fh ; 0122 - a=a&7fh [data:bit6-0=scan code]
|
|
mov r7,a ; 0124 - r7=a
|
|
|
|
|
|
; identify keybaord from $21=keyboar identity bits
|
|
mov r1,#021h ; 0125 - r1=21h
|
|
mov a,@r1 ; 0127 - a=($21)
|
|
anl a,#0f0h ; 0128 - a=a&f0h
|
|
xrl a,#020h ; 012a - a=a^20h
|
|
jz X013c ; 012c - jump if $21==0010 xxxx 6019273 50-key?
|
|
xrl a,#010h ; 012e - a=a^10h
|
|
jz X0142 ; 0130 - jump if $21==0011 xxxx *6019284 62-key*
|
|
xrl a,#070h ; 0132 - a=a^70h
|
|
jz X0148 ; 0134 - jump if $21==0100 xxxx 6019303 77-key?
|
|
|
|
; Unknown keyboard
|
|
mov a,r7 ; 0136 - a=r7(received data)
|
|
call X015f ; 0137 - [Set flag]
|
|
jmp X010b ; 0139 - <<LOOP receive again
|
|
|
|
; End
|
|
X013b: retr ; 013b -
|
|
|
|
|
|
|
|
; Set 'index' and 'size' scan code table for each keyboard model
|
|
; r1: end of scan code table(index)
|
|
; r2: number of scan code table(size)
|
|
; 6019273 50-key?
|
|
X013c: mov r1,#0afh ; 013c - r1=afh address@page3 03afh(table1)
|
|
mov r2,#038h ; 013e - r2=38h 0011 10(00) 56keys
|
|
jmp X014c ; 0140 -
|
|
|
|
; *6019284 62-key*
|
|
X0142: mov r1,#0efh ; 0142 - r1=efh address@page3 03efh(table2)
|
|
mov r2,#040h ; 0144 - r2=40h 0100 00(00) 64keys
|
|
jmp X014c ; 0146 -
|
|
|
|
; 6019303 77-key?
|
|
X0148: mov r1,#0ffh ; 0148 - r1=ffh address@page3 03ffh(table2)
|
|
mov r2,#050h ; 014a - r2=50h 0101 00(00) 80keys
|
|
|
|
|
|
|
|
; get scancode from table and test loop
|
|
LOOP>>
|
|
X014c: mov a,r1 ; 014c - a=r1
|
|
movp3 a,@a ; 014d - a=(r1) read scan code table
|
|
xrl a,r7 ; 014e - a=a^r7 a==r7(received scan code)
|
|
jnz X0156 ; 014f -
|
|
|
|
; scan code(a) == received data(r7)
|
|
dec r2 ; 0151 - r2--
|
|
mov a,r2 ; 0152 - a=r2
|
|
call X015f ; 0153 - call [Set flag]
|
|
inc r2 ; 0155 - r2++
|
|
|
|
; check next scan code
|
|
X0156: dec r1 ; 0156 - r1-- r1: address of table
|
|
djnz r2,X014c ; 0157 - <<LOOP while --r2 r2: number of table
|
|
|
|
jnc X015d ; 0159 - jump if r1>=0
|
|
call X00d8 ; 015b - Error: FD and cont. [Out of bound Error: FD]
|
|
X015d: jmp X010b ; 015d - <<LOOP Receive next data
|
|
;;;
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
; Set flag routine
|
|
;
|
|
; INPUT: a=table index(number of table)
|
|
; a: AAAA AAFF(AAAAAA:index of parameter RAM, FF: flag position(0-3))
|
|
;
|
|
X015f: clr c ; 015f - c=0
|
|
; calculate RAM address
|
|
mov r2,a ; 0160 - r2=a r2=data
|
|
rr a ; 0161 - a=a>>1
|
|
rr a ; 0162 - a=a>>1 a/4(four keys per a parameter byte)
|
|
add a,#022h ; 0163 - a=a+22h start of parameter bytes
|
|
mov r0,a ; 0165 - r0=a r0=parameter address
|
|
|
|
mov a,r2 ; 0166 - a=r2
|
|
anl a,#003h ; 0167 - a=a&03h [a=flag position]
|
|
jz X017e ; 0169 - if FF==0b00
|
|
dec a ; 016b - a--
|
|
jz X018a ; 016c - if FF==0b01
|
|
dec a ; 016e - a--
|
|
jz X0197 ; 016f - if FF==0b10
|
|
|
|
;
|
|
; Parameter byte and configure flags
|
|
; bit 7 6 5 4 3 2 1 0
|
|
; 3r 3b 2r 2b 1r 1b 0r 0b
|
|
|
|
;;;;;;;;;;;;;;;;;;
|
|
; FF==11b: 3r/3b
|
|
mov a,@r0 ; 0171 - a=(r0) r0=parameter address
|
|
anl a,#03fh ; 0172 - a=a&0011 1111b clear 3r/3b
|
|
jf0 X017a ; 0174 - jump if F0==1
|
|
; F0==0(received data:bit7==1)
|
|
; a=a|40h
|
|
orl a,#040h ; 0176 - a=a|0100 0000b 3b: break enabled
|
|
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;
|
|
; store to RAM and return
|
|
X0178: mov @r0,a ; 0178 - (r0)=a store parameter to RAM
|
|
ret ; 0179 - return a: command/received data
|
|
; End of Set flag
|
|
;;;;;;;;;;;;;;;;;;
|
|
|
|
|
|
|
|
; F0==1 (data:bit7==0)
|
|
; a=a|80h
|
|
X017a: orl a,#080h ; 017a - a=a|1000 0000b 3r: repeat enabled
|
|
jmp X0178 ; 017c -
|
|
;;;
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;
|
|
; FF==00b: 0r/0b
|
|
X017e: mov a,@r0 ; 017e - a=(r0)
|
|
anl a,#0fch ; 017f - a=a & 1111 1100b clear 0r/0b
|
|
jf0 X0186 ; 0181 - jump if F0==1
|
|
; F0==0(data:bit==1)
|
|
inc a ; 0183 - a++ 0b: break enabled
|
|
jmp X0178 ; 0184 -
|
|
; F0==1(data:bit==0)
|
|
X0186: orl a,#002h ; 0186 - 0r: repeat enabled
|
|
jmp X0178 ; 0188 -
|
|
;;;
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;
|
|
; FF==01b: 1r/1b
|
|
X018a: mov a,@r0 ; 018a -
|
|
anl a,#0f3h ; 018b - clear 1r/1b
|
|
jf0 X0193 ; 018d -
|
|
; F0==0(data:bit==1)
|
|
orl a,#004h ; 018f - 1b: break enabled
|
|
jmp X0178 ; 0191 -
|
|
; F0==1(data:bit==0)
|
|
X0193: orl a,#008h ; 0193 - 1r: repeat enabled
|
|
jmp X0178 ; 0195 -
|
|
;;;
|
|
|
|
|
|
;;;;;;;;
|
|
; FF==10b parameter|10h / parameter|20h
|
|
X0197: mov a,@r0 ; 0197 -
|
|
anl a,#0cfh ; 0198 - clear 2r/2b
|
|
jf0 X01a0 ; 019a -
|
|
; F0==0(data:bit==1)
|
|
orl a,#010h ; 019c - 2b: break enabled
|
|
jmp X0178 ; 019e -
|
|
; F0==1(data:bit==0)
|
|
X01a0: orl a,#020h ; 01a0 - 2r: repeat enabled
|
|
jmp X0178 ; 01a2 -
|
|
;;;
|
|
|
|
|
|
;
|
|
; End of command FC
|
|
;
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;
|
|
; read program memory @page1
|
|
; INPUT: a=address of program memory
|
|
X01a4: movp a,@a ; 01a4 - a=(a)@page1
|
|
|
|
; OUTPUT: r1=r1+a, a=r0
|
|
; r1=r1+a,a=r0
|
|
X01a5: add a,r1 ; 01a5 -
|
|
mov r1,a ; 01a6 - r1=a+r1
|
|
mov a,r0 ; 01a7 - a=r0
|
|
ret ; 01a8 -
|
|
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;
|
|
; Scan row8(I) and set parameter flags(on Power on Reset)
|
|
;
|
|
; call from hard reset 0018h with a=0, r0=0, r1=0?
|
|
; INPUT: r0, r1: for wait loop
|
|
; OUTPUT: $21=keybaord identity bits, r4=$21&f0h
|
|
;
|
|
|
|
;;;;;;;;;;;;;;;;;;
|
|
; delay to make Buzzer audible when powering up??
|
|
X01a9: djnz r0,X01a9 ; 01a9 - r0*2cycle
|
|
djnz r1,X01a9 ; 01ab - r1*(r0*2cycle+2cycle) 256*(256*2+2)=131584(2us?/cycle) around 260ms??
|
|
anl bus,#0c0h ; 01ad - BZ=_,CLK=_,DATA=L line is idle
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;
|
|
;
|
|
; Read keyboard identity bits from row8(I) and set parameter flags(on command FC)
|
|
; INPUT: a=0
|
|
; OUTPUT: r4=a=scanned data of row8(I)=keyboard identity bits
|
|
;
|
|
; F0: 1:read(frist)/0:read(second)&settle
|
|
; It needs to read same value twice to settle.
|
|
;
|
|
; Keyboar id bit pattern on PCB:
|
|
; mark: 1
|
|
; brank: 0
|
|
; Sensor value meaning:
|
|
; Sensor: 0 1
|
|
; Kbd id: 1(mark) 0(blank)
|
|
; Key: 1(pressed) 0(released)
|
|
;
|
|
; called from command FC 0107h
|
|
X01af: mov r7,#008h ; 01af - r7=08h [column]
|
|
X01b1: rl a ; 01b1 - a=a<<1 LOOP_0{ [next column]
|
|
X01b2: mov r4,a ; 01b2 - LOOP{ r4=a [data]
|
|
cpl f0 ; 01b3 - F0=~F0 toggle F0 [read twice to debounce]
|
|
mov a,r7 ; 01b4 - a=r7
|
|
dec a ; 01b5 - a--
|
|
orl a,#0c0h ; 01b6 - col(7-0)|c0h = c7-c0h BZ=H:on [Beep during FC command]
|
|
outl bus,a ; 01b8 - [Select column]
|
|
orl bus,#010h ; 01b9 - D4=1 [charge sensor out=H?]
|
|
mov a,#0d2h ; 01bb - 1101 0010
|
|
outl bus,a ; 01bd - bus=d2h D4-0=10010 select column 2?
|
|
|
|
;
|
|
orl p2,#001h ; 01be - P2:0=1 [select row8(I)]
|
|
mov a,r4 ; 01c0 - a=r4(data)
|
|
orl bus,#008h ; 01c1 - bus=d2h|08h=dah D4=1 [Strobe?](1101 1010)
|
|
anl p2,#000h ; 01c3 - P2:0=L [unselect row8(I)]
|
|
|
|
; check sensor out(T0)
|
|
jt0 X01d5 ; 01c5 - jump if T0==H
|
|
jf0 X01cd ; 01c7 - jump if F0==1
|
|
jb0 X01d9 ; 01c9 - jump if a:bit0==1 [Settle]
|
|
; TO(sensor)==0 && F0==0 && a:bit0==0
|
|
jmp X01b2 ; 01cb - }LOOP
|
|
|
|
; record 1(a=a|01h) when key is on(T0=L) and F0==1
|
|
; T0(sensor)==L(off) && F0==1 (from 01c7)
|
|
X01cd: orl a,#001h ; 01cd - a=a|1 [Set a:bit0=H]
|
|
jmp X01b2 ; 01cf - LOOP
|
|
|
|
; record 0(a=a&feh) when key is off(T0=H) and F0==0
|
|
; T0(sensor)==H(on) && F0==0 && a:bit0==1(off) (from 01d7)
|
|
X01d1: anl a,#0feh ; 01d1 - a=a&feh [Set a:bit0=L]
|
|
jmp X01b2 ; 01d3 - LOOP
|
|
|
|
; scan LOOP again
|
|
; T0(sensor)==H(on) && F0==1 (from 01c5)
|
|
X01d5: jf0 X01b2 ; 01d5 - LOOP while F0==1
|
|
|
|
; T0(sensor)==H(on) && F0==0
|
|
jb0 X01d1 ; 01d7 - jump if a:bit0==1 [need to change r4(a) to 0]
|
|
|
|
; next column
|
|
; T0(sensor)==H && F0==0 && a:bit0==0 OR
|
|
; T0(sensor)==L && F0==0 && a:bit0==1 (from 01c9)
|
|
X01d9: djnz r7,X01b1 ; 01d9 - }LOOP_0 while --r7>0 [Next column]
|
|
mov r4,a ; 01db - r4=a a=r4=scanned data of Row8(I)
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;
|
|
; Set parameters from scanned data of row 8(I)
|
|
;
|
|
; INPUT: a=r4=keyboard identity bits
|
|
; OUTPUT: $21=keybaord identity bits, r4=$21&f0h
|
|
;
|
|
anl a,#0f0h ; 01dc - a=a&f0h
|
|
xrl a,#020h ; 01de - a=a^20h (a==0010 xxxx) 6019273
|
|
jz X01ec ; 01e0 - jump if a==0
|
|
xrl a,#010h ; 01e2 - a=a^10h (a==0011 xxxx) *6019284 when power on reset
|
|
jz X01f2 ; 01e4 - jump if a==0
|
|
xrl a,#070h ; 01e6 - a=a^70h (a==0100 xxxx) 6019303
|
|
jz X01f2 ; 01e8 - jump if a==0
|
|
jmp X01fa ; 01ea -
|
|
|
|
; $21==(0010 xxxx) for 6019273(50-key)
|
|
; set break enalbe flag for Reset(or on other layout?)
|
|
X01ec: mov r0,#022h ; 01ec -
|
|
mov @r0,#001h ; 01ee - $22=1 $22:bit0=break enable falg of ????
|
|
jmp X01fa ; 01f0 -
|
|
|
|
; $21==(0011 0010 | 0100 xxxx) for 6019284(62-key) or 6019303(77-key) layout
|
|
; set break enable flag for LAlt and RAlt *6019284
|
|
X01f2: mov r0,#02eh ; 01f2 -
|
|
mov @r0,#001h ; 01f4 - $2e=1 $2e:bit0=break enable flag of LAlt
|
|
mov r0,#024h ; 01f6 -
|
|
mov @r0,#001h ; 01f8 - $24=1 $24:bit0=break enable flag of RAlt
|
|
|
|
; set $21 to scanned data of row 8(I) [keyboard identity bits]
|
|
X01fa: mov r0,#021h ; 01fa -
|
|
mov a,r4 ; 01fc -
|
|
mov @r0,a ; 01fd - ($21)=r4 $21: r4=identity bits(row 8(I))
|
|
anl a,#0f0h ; 01fe -
|
|
mov r4,a ; 0200 - r4=r4&f0h
|
|
ret ; 0201 -
|
|
;
|
|
; End of Scan row8(I)
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;
|
|
; Test and clear memory(3fh..00h) on Power on Reset
|
|
;
|
|
X0202: mov r0,#03fh ; 0202 - $3f
|
|
X0204: mov a,@r0 ; 0204 - LOOP>>
|
|
mov r1,a ; 0205 - r1=(r0) r0=3f..00
|
|
mov a,#0ffh ; 0206 - a=ffh
|
|
mov @r0,a ; 0208 - (r0)=ffh
|
|
xrl a,@r0 ; 0209 - a=a^ffh =0??
|
|
jnz X0224 ; 020a - jump if a!=ffh *always should be a=zero*
|
|
mov @r0,a ; 020c - (r0)=a (=0)
|
|
mov a,@r0 ; 020d - a=(r0)
|
|
jnz X0224 ; 020e - jump if a!=ffh *always should be a=zero*
|
|
mov a,r1 ; 0210 - a=r1
|
|
mov @r0,a ; 0211 - (r0)=a (revert to origin value)
|
|
djnz r0,X0204 ; 0212 - <<LOOP --r0
|
|
|
|
;
|
|
; Test program memory(0,255..1 @page0,1,2,3)
|
|
;
|
|
; INPUT: r0=0 r4=??
|
|
; OUTPUT: r4=$21&07h|50h, a=swapHL(r4(original)) or feh
|
|
X0214: mov a,r0 ; 0214 - LOOP>> a=r0=0
|
|
call X0029 ; 0215 - r1=r1+(a), a=r0 (page0)
|
|
call X01a4 ; 0217 - r1=r1+(a), a=r0 (page1)
|
|
movp a,@a ; 0219 -
|
|
call X01a5 ; 021a - r1=r1+(a), a=r0 (page2)
|
|
movp3 a,@a ; 021c -
|
|
call X01a5 ; 021d - r1=r1+(a), a=r0 (page3)
|
|
djnz r0,X0214 ; 021f - <<LOOP --r0
|
|
mov a,r1 ; 0221 - a=r1 sum of program memory data
|
|
jz X0226 ; 0222 - sum of program memory data != 0 if no error ???
|
|
|
|
; Send FE on error and r4 on success
|
|
X0224: mov r4,#0efh ; 0224 - r4=efh Memory error
|
|
X0226: call X0020 ; 0226 - r4=$21&07h|50h, a=r4(keyboard id or efh)
|
|
swap a ; 0228 - swap a:h<->a:l
|
|
orl a,#0a0h ; 0229 - a=a|a0h(1010 iiii) i:keyboard id(hi-bits)
|
|
call X0339 ; 022b - queue data(a) to buffer
|
|
call X010b ; 022d - send kbd ID and wait for data from host [FC command]
|
|
strt t ; 022f - start timer
|
|
; Usually first data form keyboard at startup is A3h(sum of program memory?).
|
|
; FEh for memory error??
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;
|
|
; Main??
|
|
;
|
|
; check scan code buffer to send
|
|
X0230: call X002c ; 0230 - receive/send data
|
|
mov a,r6 ; 0232 - a=r6 set by command FD Short Beep(0bh at 00edh)
|
|
jz X023d ; 0233 -
|
|
djnz r6,X023d ; 0235 - r6--
|
|
; Buzzer off
|
|
anl bus,#07fh ; 0237 - BZ=L(off) when get to r6==0 [Short Beep ends]
|
|
mov a,r4 ; 0239 -
|
|
anl a,#07fh ; 023a -
|
|
mov r4,a ; 023c - r4=r4&7fh(BZ=L:off) r4=bus-default
|
|
|
|
; delay for scan 192*32cycle?
|
|
X023d: mov a,t ; 023d - a=t(timer)
|
|
add a,#064h ; 023e - a=a+64h
|
|
jnc X023d ; 0240 - delay for scan
|
|
clr a ; 0242 - a=0
|
|
mov t,a ; 0243 - t=0 timer clear
|
|
|
|
; Start matrix scan
|
|
; r7=r4&c0h
|
|
X0244: mov a,r4 ; 0244 - a=r4
|
|
anl a,#0c0h ; 0245 - a=a&c0h BZ=_,CLK=_,DAT=L:
|
|
mov r7,a ; 0247 - r7=r4&c0h r7=bus-current
|
|
jf1 X0253 ; 0248 - jump if F1==1 (p1/p2)
|
|
|
|
; F1==0
|
|
cpl f1 ; 024a - F1=1(=~F1)
|
|
mov r2,#03fh ; 024b - r2=3fh scan code seed
|
|
mov r3,#001h ; 024d - r3=01h row mask
|
|
mov r1,#015h ; 024f - r1=15h last key state
|
|
jmp X0263 ; 0251 - scan matrix p1 row
|
|
|
|
; F1==1
|
|
X0253: clr f0 ; 0253 - F0=0
|
|
clr f1 ; 0254 - F1=0
|
|
mov r2,#077h ; 0255 - r2=77h scan code seed
|
|
mov r3,#002h ; 0257 - r3=02h
|
|
mov r1,#01ch ; 0259 - r1=1ch last key state
|
|
jmp X0287 ; 025b - Scan matrix p2 row
|
|
;
|
|
; INPUT: F1=0
|
|
X025d: cpl f1 ; 025d - F1=~F1=1
|
|
call X002c ; 025e - receive/send data
|
|
clr f1 ; 0260 - F1=0
|
|
jmp X0244 ; 0261 -
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;
|
|
; scan matrix p1 row
|
|
; INPUT: F1=1, r1=15h, r2=3fh, r3=01h, r7=r4&c0h
|
|
; (r1): last state
|
|
;
|
|
; r0:col, r7:bus-current, r3:row(drive H), r4=bus-default
|
|
;
|
|
; $15: bit7
|
|
;
|
|
; bus: xxxS Gccc
|
|
;
|
|
X0263: mov a,#008h ; 0263 - a=8 LOOP>>>
|
|
mov r0,a ; 0265 - r0=08h =column
|
|
orl a,r7 ; 0266 - a=08h|r7
|
|
mov r7,a ; 0267 - r7=a =xxxx 1ccc(G:1 column:ccc) r7=P1 value
|
|
X0268: dec r7 ; 0268 - LOOP>> r7--
|
|
mov a,r7 ; 0269 - a=r7
|
|
outl bus,a ; 026a - [select column]
|
|
orl bus,#010h ; 026b - sensor out=H [sensor clamp=H]???
|
|
mov a,r3 ; 026d - a=r3 current row
|
|
outl p1,a ; 026e - drive line with H [select row]
|
|
mov a,r4 ; 026f - a=r4 bus default value
|
|
outl bus,a ; 0270 - [revert bus default]
|
|
orl bus,#008h ; 0271 - D3:H sensor-G [strobe]??? hold? clean Sensor?
|
|
anl p1,#000h ; 0273 - [unselect row]
|
|
|
|
jnt0 X02ab ; 0275 - sensor out==0
|
|
; Sensor==1[key is on]
|
|
mov a,@r1 ; 0277 - a=$(r1); r1=15... last key state
|
|
jb7 X02e5 ; 0278 - jump if a:bit7==1(off) press
|
|
; a:bit7==0(last key state is on) same as last
|
|
;On->On
|
|
|
|
|
|
; Go to next column
|
|
X027a: rl a ; 027a - a=a<<1
|
|
mov @r1,a ; 027b - (r1)=a; (r1)=(r1)<<1 next col of last key state
|
|
X027c: dec r2 ; 027c - r2-- [key index of scan code table]
|
|
djnz r0,X0268 ; 027d - <<LOOP(8) [next col]
|
|
|
|
dec r1 ; 027f - r1-- 15,14,13,12,11,10,0F,0E? [last key state]
|
|
mov a,r3 ; 0280 -
|
|
rl a ; 0281 -
|
|
mov r3,a ; 0282 - r3=r3<<1 next row
|
|
jb0 X0230 ; 0283 - jump if a:bit0==1 scan end(goto Main loop)
|
|
jmp X0263 ; 0285 - <<<LOOP [next row]
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;
|
|
; Scan matrix p2 row(F1==1)
|
|
; INPUT: F0=0, F1=0, r1=1ch, r2=77h, r3=02h, r7=bus-current, r4=bus-default
|
|
;
|
|
; r0:col, r7:bus-current, r3:row(drive H), r4=bus-default
|
|
; key index: 77h-
|
|
X0287: mov a,#008h ; 0287 - a=8 LOOP>>
|
|
mov r0,a ; 0289 - r0=8
|
|
orl a,r7 ; 028a - a=a|r7
|
|
mov r7,a ; 028b - r7=a
|
|
X028c: dec r7 ; 028c - r7-- LOOP>>
|
|
mov a,r7 ; 028d - a=r7
|
|
outl bus,a ; 028e - [select column]
|
|
mov a,r4 ; 0293 - bus default value
|
|
outl bus,a ; 0294 - [revert bus default]
|
|
orl bus,#008h ; 0295 - [strobe]
|
|
anl p2,#000h ; 0297 - p2=00h [unselect row]
|
|
jnt0 X02ab ; 0299 - jump if sensor out==0(key is on)
|
|
; sensor==1(key is off)
|
|
mov a,@r1 ; 029b - a=(r1) [last key state]
|
|
jb7 X02e5 ; 029c - jump if a:bit7==1(off) press
|
|
|
|
; a:bit7==0(last key state is on)
|
|
X029e: rl a ; 029e - a=a<<1
|
|
mov @r1,a ; 029f - (r1)=a [next last key bit]
|
|
X02a0: dec r2 ; 02a0 - r2--(77h)
|
|
djnz r0,X028c ; 02a1 - jump if r0--!=0 <<LOOP(8)
|
|
dec r1 ; 02a3 - r1-- [next last key byte]
|
|
mov a,r3 ; 02a4 -
|
|
rl a ; 02a5 -
|
|
mov r3,a ; 02a6 - r3=r3<<1 [next row]??
|
|
jb0 X025d ; 02a7 -
|
|
jmp X0287 ; 02a9 - <<LOOP
|
|
|
|
;
|
|
; debouncing and change last key state
|
|
;
|
|
; sensor out==0(press; key is on)
|
|
;
|
|
; debouncing
|
|
X02ab: call X030d ; 02ab - a=0(sensor out=1), ffh(sensor out=0) [Sense key]
|
|
jz X02f8 ; 02ad - if a==0(key is off)
|
|
call X030d ; 02af - [Sense key]
|
|
jz X02f8 ; 02b1 - if a==0(key is off)
|
|
|
|
; Sensor==0(a=ffh; press)
|
|
mov a,@r1 ; 02b3 - a=(r1) last key state????
|
|
jb7 X02ca ; 02b4 -
|
|
|
|
;
|
|
; [release](off->on)
|
|
;
|
|
; last:bit7==0(off) && sensor=0(on)
|
|
orl a,#080h ; 02b6 - 0:on 1:off
|
|
rl a ; 02b8 -
|
|
mov @r1,a ; 02b9 - (r1)=(r1)<<1 next column
|
|
call X0325 ; 02ba - key configure flag
|
|
; (a:bit1=repeat enable, a:bit0=break enable)
|
|
; if keyconf:bit0==1 then set release flag
|
|
jb0 X02fd ; 02bc - r2=r2|80h [press flag]
|
|
; if keyconf:bit1==1 then set repeat
|
|
jb1 X02e1 ; 02be - r5=repeat delay [repeat]
|
|
|
|
; get scan code and queue it into buffer
|
|
X02c0: call translate034E ; 02c0 - a=scancode
|
|
call X0339 ; 02c2 - queue data to buffer
|
|
call X0303 ; 02c4 - [r1=a=address of last key state]
|
|
X02c6: jf1 X027c ; 02c6 - next col(F1==1)
|
|
jmp X02a0 ; 02c8 - next col(F1==0)
|
|
|
|
;
|
|
; [hold key]
|
|
;
|
|
; last key is on and sensor==0(on) (on->on)
|
|
X02ca: rl a ; 02ca -
|
|
mov @r1,a ; 02cb - (r1)=(r1)<<1
|
|
call X0325 ; 02cc - key configure flag
|
|
; (a:bit1=repeat enable, a:bit0=break enable)
|
|
; repeat:flag
|
|
jb1 X02d4 ; 02ce - [repeat]
|
|
|
|
; if repeat:flag(bit1)==0 (no repeat)
|
|
X02d0: call X0303 ; 02d0 - r1=r2&0fh+0eh address of last key state
|
|
jmp X02c6 ; 02d2 - goto next col
|
|
|
|
; if flag:bit1==1 (repeat)
|
|
X02d4: jf0 X02dd ; 02d4 -
|
|
|
|
; F0==0
|
|
cpl f0 ; 02d6 - F0=~F0=1
|
|
djnz r5,X02d0 ; 02d7 -
|
|
mov r5,#007h ; 02d9 - r5=07h repeat interval
|
|
jmp X02c0 ; 02db - send scan code
|
|
|
|
; F0==1
|
|
X02dd: mov r5,#028h ; 02dd - r5=28h repeat delay(for first repeat)
|
|
jmp X02d0 ; 02df -
|
|
;
|
|
X02e1: mov r5,#028h ; 02e1 - r5=28h repeat delay(for first repeat)
|
|
jmp X02c0 ; 02e3 - send scan code
|
|
|
|
|
|
;
|
|
; debouncing and change last key state: press
|
|
;
|
|
; INPUT: (r1): last key status
|
|
;
|
|
; (r1):bit7==1(last key is on) && Sensor==1(key is off) [release]
|
|
X02e5: call X030d ; 02e5 - a=0(sensor out=1), ffh(sensor out=0) [Sense key]
|
|
jnz X02f8 ; 02e7 -
|
|
call X030d ; 02e9 - [Sense key]
|
|
jnz X02f8 ; 02eb - \_debouncing
|
|
; Sensor==1(a=0) [Debounced]
|
|
|
|
;
|
|
; on->off [release]
|
|
;
|
|
mov a,@r1 ; 02ed - a=(r1) RAM
|
|
anl a,#07fh ; 02ee - a=a&7fh last state=0(0:on 1:off)
|
|
rl a ; 02f0 - a=a<<1
|
|
mov @r1,a ; 02f1 - (r1)=a
|
|
;
|
|
call X0325 ; 02f2 - key configure flag
|
|
; (a:bit1=repeat enable, a:bit0=break enable)
|
|
jb0 X02c0 ; 02f4 - goto translate if a:bit0==1
|
|
jmp X02d0 ; 02f6 -
|
|
|
|
; go to next col scan Sensor==1
|
|
X02f8: mov a,@r1 ; 02f8 -
|
|
jf1 X027a ; 02f9 - goto next col scan(p1) if F1==1 [Next column]
|
|
jmp X029e ; 02fb - goto next col scan(p2) else [Next column]
|
|
|
|
;
|
|
; add press flag(bit8)
|
|
; r2=key index
|
|
X02fd: mov a,r2 ; 02fd - [key index]
|
|
orl a,#080h ; 02fe -
|
|
mov r2,a ; 0300 - r2=r2|80h **press flag**
|
|
jmp X02c0 ; 0301 -
|
|
|
|
; Address of last key state
|
|
; INPUT: r2=key index
|
|
; OUTPUT: r1=(r2>>3)&0fh+0eh = address of last key state
|
|
X0303: mov a,r2 ; 0303 - a=r2 key index
|
|
rr a ; 0304 -
|
|
rr a ; 0305 -
|
|
rr a ; 0306 - a= a>>3
|
|
anl a,#00fh ; 0307 - a= a & 0fh
|
|
add a,#00eh ; 0309 - a= a + 0eh
|
|
mov r1,a ; 030b - r1=a
|
|
ret ; 030c -
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;
|
|
; Sense key
|
|
; INPUT: r7: bus-current, F1:0(p2),1(p1) r4=bus-default, r3=row
|
|
; RETURN: a=0xff(sensor out=0, press), 0(sensor out=1, release)
|
|
;
|
|
X030d: mov a,r7 ; 030d - r7: bus-current
|
|
outl bus,a ; 030e - [Select column]
|
|
orl bus,#010h ; 030f - [Charge: D4]
|
|
mov a,r3 ; 0311 - r3: row(drive) select p1(F1=1)/p2(F1=0) setting
|
|
jf1 X0317 ; 0312 -
|
|
; F1==0
|
|
outl p2,a ; 0314 - set p2 [Select row]
|
|
jmp X0318 ; 0315 -
|
|
; F1==1
|
|
X0317: outl p1,a ; 0317 - set p1 [Select row]
|
|
|
|
X0318: mov a,r4 ; 0318 - r4: bus-default
|
|
outl bus,a ; 0319 - set bus
|
|
clr a ; 031a - a=0
|
|
orl bus,#008h ; 031b - [Strobe: D3]
|
|
anl p1,#000h ; 031d - clear p1 [Unselect row]
|
|
anl p2,#000h ; 031f - clear p2 [Unselect row]
|
|
|
|
jt0 X0324 ; 0321 - sensor out==1
|
|
sensor out==0
|
|
cpl a ; 0323 - a=0xff [press(on)]
|
|
sensor out==1
|
|
X0324: ret ; 0324 - a=0 [release(off)]
|
|
;
|
|
; End of Main
|
|
;
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;
|
|
; key configure flags
|
|
;
|
|
; INPUT: r2=key index(p1:-3fh, p2:-77h) (aaaaaaii)
|
|
: OUTPUT: a=Key configure 2-bit flags; bit0 and 1 are only valid. (------rb)
|
|
;
|
|
: Key configure flags are retained in RAM($22-3F) and
|
|
; Key configure flags use 2bit per key so that a byte can has flags of four key like:
|
|
; bit 7 6 5 4 3 2 1 0
|
|
; 3r 3b 2r 2b 1r 1b 0r 0b
|
|
; where r=repeat enable, b=break code(release) eanble
|
|
;
|
|
X0325: mov a,r2 ; 0325 - a=r2 index
|
|
rr a ; 0326 -
|
|
rr a ; 0327 - a=a>>2 bit7-2 of index(aaaaaa)
|
|
add a,#022h ; 0328 - a=a+22h $22+aaaaaa
|
|
mov r1,a ; 032a - r1=a
|
|
mov a,@r1 ; 032b - a=(r1) $22-3F(ignored bit7,bit6)
|
|
mov r1,a ; 032c - r1=a r1=($22-3F) ????
|
|
mov a,r2 ; 032d - a=r2 index
|
|
anl a,#003h ; 032e - a=a&03h a=bit0,bit1 of index
|
|
xch a,r1 ; 0330 - a<->r1 r1=bit0,bit1 of index, a=($22-3F)
|
|
inc r1 ; 0331 - r1++ =1-4
|
|
X0332: djnz r1,X0335 ; 0332 - while --r1>0
|
|
ret ; 0334 -
|
|
|
|
; place flags of the key on bit0 and 1
|
|
X0335: rr a ; 0335 -
|
|
rr a ; 0336 - a=a>>2; a=$22-3F
|
|
jmp X0332 ; 0337 -
|
|
|
|
;
|
|
; Queue data to bottom of outgoing buffer(bank1:r5,r6,r7)
|
|
; INPUT: a=data, r2=???
|
|
; OUTPUT: r2=r2&07h
|
|
; a->r5->r6->r7
|
|
X0339: sel rb1 ; 0339 - switch to bank1
|
|
inc a ; 033a - a++
|
|
xch a,r5 ; 033b - a<->r5
|
|
jz X0348 ; 033c -
|
|
xch a,r5 ; 033e -
|
|
xch a,r6 ; 033f -
|
|
jz X0348 ; 0340 -
|
|
xch a,r6 ; 0342 -
|
|
xch a,r7 ; 0343 -
|
|
jz X0348 ; 0344 -
|
|
mov r7,#0ffh ; 0346 - buffer overflow
|
|
X0348: sel rb0 ; 0348 - switch to bank0
|
|
mov a,r2 ; 0349 - a=r2
|
|
anl a,#07fh ; 034a - a=a&7fh
|
|
mov r2,a ; 034c - r2=a
|
|
ret ; 034d -
|
|
;
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;
|
|
; Translate key index into scancode
|
|
;
|
|
; INPUT: r2=keyindex [bit7:release flag(1:release/0:press), bit6-0:index]
|
|
; OUTPUT: a=scancode
|
|
translate034E:
|
|
mov r1,#021h ; 034e -
|
|
mov a,@r1 ; 0350 - a=$21 $21:bit6,5,4 = traslate table
|
|
anl a,#0f0h ; 0351 - a=a & f0h
|
|
xrl a,#020h ; 0353 - a=a ^ 20h $21:bit5(0010 0000) 0010 xxxx => table1
|
|
jz X0361 ; 0355 - if a==0 read table1 (6019273 50-key)
|
|
xrl a,#010h ; 0357 - a=a ^ 10h $21:bit4(0001 0000) 0011 xxxx => table2
|
|
jz X0370 ; 0359 - read table2 (6019284 62-key)
|
|
xrl a,#070h ; 035b - a=a & 70h $21:bit6(0111 0000) 0100 xxxx => table2
|
|
jz X0370 ; 035d - read table2 (6019303 77-key)
|
|
mov a,r2 ; 035f - else use r2(keyindex) instead of scancode
|
|
ret ; 0360 -
|
|
; table1(8x7=56)
|
|
X0361: mov a,r2 ; 0361 - keyindex
|
|
anl a,#07fh ; 0362 -
|
|
add a,#078h ; 0364 - table1
|
|
; read table
|
|
X0366: movp3 a,@a ; 0366 - read scancode from table a=scan code
|
|
xch a,r2 ; 0367 - a=keyindex, r2=scancode
|
|
jb7 X036c ; 0368 - if keyindex:bit7==1 [relase event]
|
|
xch a,r2 ; 036a - a=scancode, r2=keyindex
|
|
ret ; 036b -
|
|
; release flag
|
|
X036c: xch a,r2 ; 036c -
|
|
orl a,#080h ; 036d - [[[[[release flag(bit7)]]]]]
|
|
ret ; 036f - a: scan code
|
|
; table2(8X10=80)
|
|
X0370: mov a,r2 ; 0370 -
|
|
anl a,#07fh ; 0371 -
|
|
add a,#0b0h ; 0373 - table2
|
|
jmp X0366 ; 0375 - read table
|
|
|
|
|
|
; maybe 'salt' to make sum of program memory 'zero'(at 0222h)
|
|
db 0b6h ; 0377 6
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;
|
|
;
|
|
; Scancode table
|
|
;
|
|
|
|
;;;;;;;;;;;;;;;;;;
|
|
; Used for 6019273 Add Key Parameter RAM
|
|
table1: db 03fh,037h,03ah,036h,02ah,035h,022h,023h ; 0378
|
|
db 03bh,02bh,039h,031h,032h,029h,021h,0ffh ; 0380
|
|
db 033h,038h,0ffh,030h,028h,0ffh,020h,0ffh ; 0388
|
|
db 017h,01dh,01ch,015h,00ch,00dh,004h,005h ; 0390
|
|
db 00fh,01fh,01bh,013h,014h,00bh,003h,0ffh ; 0398
|
|
db 00eh,01ah,019h,012h,009h,00ah,001h,002h ; 03a0
|
|
db 016h,01eh,018h,010h,011h,008h,000h,0ffh ; 03a8
|
|
|
|
;;;;;;;;;;;;;;;;;;
|
|
; Used for 6019284 and 6019303 Add Key Parameter RAM
|
|
table2: db 02fh,03dh,03ch,02dh,01dh,01ch,00ch,00eh ; 03b0 Enter ... BS $22, $23
|
|
db 03fh,042h,03bh,02bh,02ch,01bh,01fh,00dh ; 03b8 RAlt ... $24, $25
|
|
db 039h,03ah,029h,02ah,002h,003h,00ah,00fh ; 03c0 ... $26, $27
|
|
db 038h,037h,028h,027h,017h,001h,008h,009h ; 03c8 ... $28, $29
|
|
db 040h,036h,025h,026h,015h,016h,011h,012h ; 03d0 ... $2a, $2b
|
|
db 035h,034h,023h,024h,013h,014h,01ah,010h ; 03d8 ... $2c, $2d
|
|
db 03fh,032h,033h,022h,021h,006h,005h,019h ; 03e0 LAlt ... $2e, $2f
|
|
db 031h,041h,03eh,030h,020h,004h,000h,018h ; 03e8 Reset ... 1 $30, $31
|
|
db 071h,076h,075h,066h,055h,056h,045h,046h ; 03f0 Used for 77-key $32, $33
|
|
db 077h,067h,074h,064h,065h,054h,0ffh,044h ; 03f8 Used for 77-key $34, $35
|
|
;
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
|
|
|
;
|
|
; symbol equates
|
|
;
|
|
; these are symbols from the control
|
|
; file that are referenced in the code
|
|
;
|
|
jump_table equ 0fah
|
|
;
|
|
end
|