]> git.friedersdorff.com Git - max/tmk_keyboard.git/blob - converter/ibm4704_usb/ibm4704.txt
ibmpc_usb: Add prebuilt firmware files
[max/tmk_keyboard.git] / converter / ibm4704_usb / ibm4704.txt
1 IBM 4704 Keyboard Analysis - 6019284(62-key)
2 ============================================
3 2013/02/09, 2019/07/12
4
5 IBM 4704 Keyboard
6 =================
7 IBM capacitive switch models:
8     6019273 Model 100 50-key (grid layout)      http://kishy.ca/?p=894
9     6019284 Model 200 62-key Alpha(60% layout)  http://kishy.ca/?p=894
10     6019303 Model 300 77-key Expanded Alpha     http://deskthority.net/photos-f62/ibm-6019303-t8502.html
11     6020218 Model 400 107-key Full key          http://kishy.ca/?p=894
12
13 Alps switch(vintage Green) models:
14     5954339 Japanese 102-key    http://deskthority.net/post87127.html#p87127
15     6112883 Japanese 102-key    http://geekhack.org/index.php?topic=52888.msg1194489#msg1194489
16     6112884 Japanese 102-key    http://geekhack.org/index.php?topic=50437.msg1193047#msg1193047
17     6341739 Chinese 102-key     http://geekhack.org/index.php?topic=52888.msg1176566#msg1176566
18
19
20
21 Resourse
22 --------
23 The IBM 4704: lots of pictures and info
24 http://kishy.ca/?p=894
25 http://imgur.com/a/LaABs
26
27 Brochure:
28 http://ed-thelen.org/comp-hist/IBM-ProdAnn/4700.pdf
29
30
31
32 4704 Keyboard Protocol
33 ======================
34 On powering up keyboard sends keyboard ID; A3h for 6019284(62-key), for example.
35 After that the keyboard enters FC command mode and waits for parameter data from host
36 so that it doesn't send any scancode until you send 'FF'(End of FC command mode).
37
38
39     Keyboard                    ID
40     -------------------------------
41     Model 100 50-key            A2h
42     Model 200 62-key            A3h
43     Model 300 77-key            A4h
44     Model 400 107-key           A5h
45     Japanese/Chinese 102-key    A6h
46
47
48 Connector
49 ---------
50     Keyboard Plug from front
51
52     DSUB-9
53     -------------
54     \ N 2 3 4 5 /
55      \ N N N N /
56       ---------
57     2   GND
58     3   VCC 5V
59     4   DATA
60     5   CLOCK
61     N   No connection/No pin.
62
63
64 Keyboard to Host
65 ----------------
66 Data bits are LSB first and Pairty is odd. Clock has around 60us high and 30us low part.
67
68             ____       __   __   __   __   __   __   __   __   __   _______
69     Clock       \_____/  \_/  \_/  \_/  \_/  \_/  \_/  \_/  \_/  \_/
70                  ____ ____ ____ ____ ____ ____ ____ ____ ____ ____
71     Data    ____/    X____X____X____X____X____X____X____X____X____X________
72                 Start   0    1    2    3    4    5    6    7    P  Stop
73
74 Start bit:  can be long as 300-350us.
75 Inhibit:    Pull Data line down to inhibit keyboard to send.
76 Timing:     Host reads bit while Clock is hi.(rising edge)
77 Stop bit:   Keyboard pulls down Data line to lo after 9th clock.
78
79
80
81 Host to Keyboard
82 ----------------
83 Data bits are LSB first and Pairty is odd. Clock has around 60us high and 30us low part.
84
85             ____        __   __   __   __   __   __   __   __   __   ________
86     Clock       \______/  \_/  \_/  \_/  \_/  \_/  \_/  \_/  \_/  \_/
87                 ^   ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ___
88     Data    ____|__/    X____X____X____X____X____X____X____X____X____X   \___
89                 |  Start   0    1    2    3    4    5    6    7    P   Stop
90                 Request by host
91
92 Start bit:  can be long as 300-350us during start up and upto 2500us while key scanning
93 Request:    Host pulls Clock line down to request to send a command.
94 Timing:     After Request keyboard pull up Data and down Clock line to low for start bit.
95             After request host release Clock line once Data line becomes hi.
96             Host wirtes a bit while Clock is hi and Keyboard reads while low.
97 Stop bit:   Host releases or pulls up Data line to hi after 9th clock and waits for keybaord pull down the line to lo.
98
99
100
101 Scancodes
102 ---------
103 Keyboard doesn't send Break code for all keys except for Alt by default.
104
105     6019284 62-key:
106     ,-----------------------------------------------------------.
107     |  `|  1|  2|  3|  4|  5|  6|  7|  8|  9|  0|  -|  =|**1|BS |
108     |-----------------------------------------------------------|
109     |Tab  |  Q|  W|  E|  R|  T|  Y|  U|  I|  O|  P| ¢|  \|  PD2|
110     |-----------------------------------------------------------|
111     |Ctrl  |  A|  S|  D|  F|  G|  H|  J|  K|  L|  ;|  '| {}| PD3|
112     |-----------------------------------------------------------|
113     |Shif| <>|  Z|  X|  C|  V|  B|  N|  M|  ,|  ,|  /|**2|Shift |
114     |-----------------------------------------------------------|
115     |Reset|blk|Alt  |         Space             |Alt  |blk|Enter|
116     `-----------------------------------------------------------'
117     +----------+---------------------+----------+----------+
118     |`       00|PD1     04|Caps    20|LShift  30|Reset   31|
119     |1       18|q       05|a       21|<>      3E|Rblank  41|
120     |2       19|w       06|s       22|z       32|Alt     3F|
121     |3       1A|e       13|d       23|x       33|Space   40|
122     |4       10|r       14|f       24|c       34|Alt     3F|
123     |5       11|t       15|g       25|v       35|Lblank  42|
124     |6       12|y       16|h       26|b       36|Enter   2F|
125     |7       08|u       17|j       27|n       37|          |
126     |8       09|i       01|k       28|m       38|          |
127     |9       0A|o       02|l       29|,       39|          |
128     |0       0F|p       03|;       2A|.       3A|          |
129     |-       1F|¢      1B|'       2B|/       3B|          |
130     |=       0D|\       1C|{}      2C|**2     3C|          |
131     |**1     0C|PD2     1D|PD3     2D|RShift  3D|          |
132     |BS      0E|          |          |          |          |
133     +----------+---------------------+----------+----------+
134     Bit7 is 'press flag' which set 1 on press and 0 on release when break code is enabled.
135
136 NOTE: When break code is enabled the key sends scancode with setting 7th bit on press
137 and without it on release. That is, '`' sends 80h on press and 00h on release.
138
139
140 Keyboard command
141 ----------------
142 Keyboard accepts these commands from host.
143
144         Description                             Entry point
145     -----------------------------------------------------------
146     FF  Soft Reset                              0008h
147     FE  Resend                                  00e8h
148     FD  Buzzer(emits a short beep)              00edh
149     FC  Set Key Flag                            00f6h
150     FB  Soft Reset                              0008h
151     FA  Reset                                   0000h
152
153
154 Keyboard response
155 -----------------
156 Keyobard sends these bytes to host.
157
158         Description                             Entry point
159     -----------------------------------------------------------
160     FE  Overflow(key event/receive data)        00c5h, 0346h
161         Memory test error                       0224h
162     FD  Command out of bound                    00d8h
163         Key out of bound
164     7E  Read/Parity error in receive from host  00bch
165     80-FB? scan code(make)
166     00-7B? scan code(break)
167     note: Alps model spits scan code 7B(FB) at least.
168
169
170 Set Key Flag command(FC)
171 ------------------------
172 After 'Power on Reset' firmware enters this command mode and waits for data from host,
173 so that you don't need to send 'FC' and it doesn't send any scancode until you send 'FF' to exit this mode.
174 With Alps models you need to send 'FC' command to enter this mode.
175
176 Data sent from host:
177
178     bit: 7   6 ... 0
179          en  |     |
180          |   `-----`--- scan code
181          `------------- enable bit(0: enable repeat, 1: enable break)
182
183     00-7B   Enable repeat
184     80-FB   Enable break
185     FE      Resend(011ah) no need to use
186     FF      End(0114h) exits FC command mode.
187
188 Response from keyboard:
189     FD      Out of bound - Invalid scancode
190     --      OK - No response means that command is accepted.
191
192 Examples:
193     To enable break code of all keys you have to send following commands.
194
195     FC 80 81 ... FB FF
196
197
198
199 4704 Hardware
200 =============
201 Power consumption
202 -----------------
203 This keyboard is very power greedy, it consumes around 170mA
204 and USB port may not be able to supply enough current.
205
206     5.061V  -               No load. Power from Powered USB Hub.
207     4.946V  133.6mA max     without Buzzer
208     4.911V  171.0mA max     with Buzzer
209
210
211 Controller Board
212 ----------------
213 NOTE: TWO BOLTS OF CONTROLLER BOARD IS CRITICAL.
214 Controller PCB and tab of bottom plate of key assembly with two hex bolts, these
215 connect between controller ground to the metal bottom plate of key switch assembly.
216 This connection is very critical to sense key state, keys will not be registered
217 unless they are tightened up with the bolts
218
219     Controller: 8048 DIP40 with 1KB ROM and 64B RAM(8748H?)
220     Clock:      ??MHz   Resonator? TODO: machine cycle: ??us
221     Buffer:     7917 hex buffer
222     Sensor:     IBM custom chip for capacitive sense
223
224
225 8048 Pin configuration
226 ----------------------
227 Bus:
228     bit: D7  D6  D5  D4  D3  D2  D1  D0
229     use: BZ  CLK DAT ??? G   S2  S1  S0
230
231     use dir     description
232     ----------------------------------------------------------------------
233     S0  out     Sensor select
234     S1  out     Sensor select
235     S2  out     Sensor select
236     G   out     Sensor strobe?
237     ???         Sensor state out(drive/charge? via 7917 buffer)
238     DAT out     Data via buffer logic with 2K pull up resistor
239     CLK out     Clock via buffer logic with 2K pull up resistor
240     BZ  out     Drive Buzzer via 7917 buffer with 2KOhm pull up resistor(H:on/L:off)
241 T0:
242     input of Sensor state(H:on/L:off)
243 T1:
244     input of Clock line with 1KOhm pull up resistor
245 INT:
246     input of Data line with 1KOhm pull down resistor
247 PORT1:
248     P10-P17 matrix row0-7
249 PORT2:
250     P20     matrix row8 or I(keyboard identity bits row)
251
252
253 Connections
254 -----------
255     8048            Sensor
256     -----------------------------
257     D0-2 ====/===== S0-2(Sensor)
258     D3   ---------- STR(Sensor)
259            7917 buffer
260     D4   --|>--+--- OUT(Sensor)
261     T0   ------'
262
263     8048            line
264     -----------------------------
265            Vcc  Vcc
266             |    |
267             R 1K R 2K
268     T1   ---+-<|-+- CLK
269     D6   ---|>---'
270                 Vcc
271                  |
272                  R 2K
273     D6   ---|>---+- DAT
274     T1   -+---<|-'
275           R 1K
276           |
277          GND
278                 Vcc
279                  |
280                  R 2K
281     D7   ---|>---+- BZ
282
283
284 Interruption
285 ------------
286 I       disable at 0015h
287 TCNTI   disable at 0014h
288
289
290 IBM Capacitive sensor chip
291 --------------------------
292 Silver canned package
293
294     Pin             Connection      Desciption
295     ----------------------------------------------------------------
296     Input(C0-7)     Matrix Col0-7   8 column line inputs
297     Col select(S0-2)8048:D0-D2      Select column line to sense
298     Strobe(STR)     8048:D3         Strobe
299     Output(OUT)     848:T0          Read Key state(0:pressed/1:released)
300
301     Pinout from bottom:
302     +-----------++------+-------+-------+-------+
303     | 1 2 3 4 5 ||1:LCL |6:LCC  |B:S0   |G:C5   |
304     | 6 7   8 9 ||2:GND |7:LCM  |C:?    |H:C4   |
305     | A       B ||3:Out |8:S2   |D:C6   |I:C3   |
306     | C D   E F ||4:STR |9:S1   |E:C0   |J:C2   |
307     | G H I J K ||5:VCC |A:C7   |F:?    |K:C1   |
308     +-----------++------+-------+-------+-------+
309
310     8048            Sensor
311     D0-2 ====/===== S0-2
312     D3   ---------- STR
313            7917 buffer
314     D4   --|>--+--- OUT
315     T0   ------'
316
317     Speculation: 8048:D4 is used to prepare to sense capacitance.(charge key capcitor?)
318
319 Procedure:
320     at 030dh:
321     D0-2=<column>   ; select column S0-2
322     D4=1            ; Prepare sensor(Charge?)
323     P1/P2=<row>     ; select row
324     D0-4=<default>  ; 00010(bus=c2h)
325     D3=1            ; Strobe
326     P1/P2=0         ; unselect row
327     read T0         ; see key state
328
329     at 01afh:
330     D0-2=<column>
331     D4=1
332     D0-2=2(010)     ; select col2
333     P2=01h          ; select row
334     D3=1            ; Strobe
335     P2=00h          ; unselect row
336     read T0
337
338
339 Keyswitch Matrix
340 ----------------
341 6019284(62-key):
342      |0       1       2       3       4       5       6       7
343     -|--------------------------------------------------------------
344     0|Enter   RShift  JIS_    PD3     PD2     \|      LofBS   BS
345     1|RAlt    RBlank  /?      '"      {}      Cent!   -       =
346     2|,       .       l       ;       o       p       9       0
347     3|m       n       k       j       u       i       7       8
348     4|Spc     b       g       h       t       y       5       6
349     5|v       c       d       f       e       r       3       4
350     6|LAlt    z       x       s       a       w       q       2
351     7|Reset   LBlank  ISO\    LShift  CapLock PD1     `~      1
352     8|_       x       _       _       x       x       _       _ (Identity bits: 32h)
353
354     Two 15-line flat cables shown from bttom of PCB:
355
356           Flatcable A    Flatcable B
357         /             \/             \
358         0123456789ABCDE0123456789ABCDE
359         --8-----01234567----76543210--
360           Id    row         col         -:GND
361
362
363 Keyboard Identity Bits
364 ----------------------
365 4704 keyboards has its identity bit marks on PCB matrix and it is readable
366 from firmware so that it can select key layout depending on this.
367
368 PCB pictures:
369     Model 100:
370         http://kishy.dyndns.org/wp-content/uploads/2013/02/6019273_0011.jpg
371     Model 200:
372         http://kishy.dyndns.org/wp-content/uploads/2013/02/6019284_0020_capacitive-pcb-top.jpg
373     Model 300:
374         http://kbtalking.cool3c.com/article/23272
375     Model 400:
376         http://kishy.dyndns.org/wp-content/uploads/2011/09/6020218_distrib_0019.jpg
377
378
379
380 4704 Firmware
381 =============
382
383 Startup sequence
384 ----------------
385 Power on Reset(0000h):
386     Short Buzzer
387         turns Buzzer(BZ=L) on at 0002h
388         turns Buzzer(BZ=H) off at 01adh
389     Initialize all memory(3fh-00h)
390     Initialize other registers
391     Read keyboard id and set default parameter at 01afh
392         set break flag for Alt key by default
393     Test and clear memory(3fh..00h) at 0202h
394     Test program memory at 0214h
395     r4=($21&07h)|50h at 0020h
396     Send test result at 022dh
397         sends [a0h | (keyboard id&f0h)>>4] on success
398         6019284 seneds a3h on success
399     Wait for data from host - it expects FC command data followed by ffh(end)
400     Main loop
401
402 Soft Reset(0008h):
403     Initialize all memory(20h-00h) It retains parameter memory.
404     Initialize other registers
405     r4=($21&07h)|50h at 0020h
406     Main loop
407
408
409 Memory Map
410 ----------
411 RAM(64 bytes):
412 $01-07  *Bank0* Registers r0-r7
413         r0  temporary use
414         r1  temporary use
415         r2  temporary use
416         r3  row mask of scan 024dh, 0257h
417         r4  bus default value
418             7 6 5 4 3 2 1 0
419             | | | | | | | |
420             | | | | | `-`-`------ Sensor column select
421             | | | | `------------ Sensor strobe?
422             | | | `-------------- Sensor column set?
423             | | `---------------- Data
424             | `------------------ Clock
425             `-------------------- Buzzer control(L:on/H:off)023ch
426             =$21&07h|50h: call 0020h at 001ch soft reset (52h=0101 0010)
427             =$21&07h|50h: call 0020h at 0109h command FC (52h=0101 0010)
428             =r4|80h: at 00f4h(FD command)
429             =r4&7fh: at 023ch(Main)
430             =r4&f0h: at 0200h
431         r5  repeat dealy/interval
432             used at 02d7h
433             =07h at 02d9h
434             =28h at 02ddh
435             =28h at 02e1h
436        *r6  0bh at 00edh(FD command)
437             used at 0232h
438         r7  received data from host
439             temporary use at 01afh
440             temporary use at 005dh
441             =r4&c0h(current bus value?) 0247h
442 $08-17  8-level stack(2*8)
443     $0E
444     :       last key state(1:pressed/0:released)
445     $15     (0E-15)=8*8=64 matrix(for 50-key and 62-key?)
446     $16
447     :       last key state(1:pressed/0:released)
448     $1C     (16-1C)=7*8=56 (extension for 77-key?)
449
450 $18-1F  *Bank1* Registers 0-r7
451     Outgoing buffer of data sent to host
452     $1D     r5      outgoing buffer top
453     $1E     r6      outgoing buffer
454     $1F     r7      outgoing buffer bottom
455
456
457 $20     Resend buffer: code last sent used by 'Resend'(FE)
458
459 $21     Keyboard identity bits
460         0011 0010  (6019284: 32h read from Row(I))
461          ||| ||||
462          ||| |```- Sensor chip control(bus value)??
463          ||| `---- ???
464          ```------ keyboard model id
465
466         set at 01fah on Power on Reset:  32h from row8(I)(6019284)
467         got at 0020h on Soft Reset:
468         got at 034eh on translate into scan code:
469         got at 0125h on command FC:
470         set from scan 8(I) row at 01fdh
471
472         Keyboard model id:
473             Model 100 6019273 50-key (grid layout):     22h(from picture)
474             Model 200 6019284 62-key Alpha(60% layout): 32h
475             Model 300 6019303 77-key Expanded Alpha:    42h?(from dump list)
476             Model 400 6020218 107-key Full key:         no identity
477                 Looks like this firmware does not support 107-key.
478
479         IBM 4704 keyboards:
480             It seems Model 100, 200 and 300 keyboards share one firmware code and
481             have small square copper patterns on righ side of PCB to identify
482             its layout. See following pictures. Model 400 may use another firmware.
483
484 $22-3F  30-byte Parameter RAM(Repeat and Break flags)
485         Parameter byte is comprised of four flag pairs. Flags occupies two bits each a key.
486         Parameter RAM can have flags for 120(4*30) keys.
487
488         Parameter byte and flags:
489             bit 7   6   5   4   3   2   1   0
490                 3r  3b  2r  2b  1r  1b  0r  0b
491 :
492 $3F     End of Memory(64 bytes)
493
494
495
496
497 Entry points
498 ------------
499 0020    Soft Reset  r4=($21&07h)|50h = (32h&07h)|50h=52h
500 0029    r1=r1+(a), a=r0 (page 0)
501 002c    (F0=0: send or receive data with 'interpret command mode')
502 002d    Receive data or Send scan code
503 0035    Send scan code
504         return: F1=1
505 0082    Receive data from host
506         condition: F0==0   interpret command
507                    F0==1   return receive data(a)
508         return:    F1=1(ERROR) 00c7 (Receive ACK/Parity Error) 00b6,00ce
509                    F1=0?
510                    a=recieve data, (with F0=0 00dc) F0==0 means 'data received'
511 00bc    push 7f(error) into outgoing buffer
512 00be    push data/response into outgoing buffer(r5,r6,r7)
513 00d2    interpret keyboard command
514 00de    calculate parity
515
516 01a4    r1=r1+(a), a=r0 (page 1)
517 01a5    r1=r1+a, a=r0
518 01a9    Buzzer and Scan row8(*) and set param: call from Power on Reset 0018h
519 01af    Read keyboard identity bits from row8(I) and set param: - call from command FC 0107h
520 0202    Memory Test(Power on Reset)
521
522 0230    Main loop:  send, receive data and scan
523         send/receive: call 002c
524 0263    **Scan matrix**(F1==0): F1=1, r1=15h, r2=3fh, r3=01h
525 0287    **Scan matrix**(F1==1): F1=0, r1=1ch, r2=77h, r3=02h
526 0325    get key configure flags(a=-----rb; where r:repeat enable, b:break enable)
527 0339    queue data at bottom of outgoing buffer
528 034e    translate into scan code
529         scan code table1/table2
530
531
532 Keyboard command entry points
533 -----------------------------
534 FF: jump_table0   Soft Reset(008h)
535 FE: jump_table1   Resend(return content of $20)
536 FD: jump_table2   Short beep BZ
537 FC: jump_table3   parameter configuration(100h)
538 FB: jump_table4   Soft Reset(008h)
539 FA: jump_table5   Reset(000h)
540
541
542
543
544 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
545 ;
546 ;  8048 Disassembly of IBM 6019284 ROM dump
547 ;
548 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
549 ; label mnemonic                ; address   comment
550 ;-------------------------------------------------------------------------------------
551         org     000h
552 ; jump_table:5  Hard Reset/Power on Reset
553         mov     a,#07fh         ; 0000 - a=7f        Power on Reset
554         outl    bus,a           ; 0002 - BZ=L(off), others=H
555         mov     r0,#03fh        ; 0003 - r0=3fh
556         clr     f1              ; 0005 - F1=0
557         jmp     X000c           ; 0006 -
558 ; jump_table:0,4 Soft Reset
559         mov     r0,#020h        ; 0008 - r0=20h      $20=resend buffer
560         clr     f1              ; 000a -
561         cpl     f1              ; 000b - F1=1
562
563 ;;;;;;;;;;;;;;;;;;
564 ;   initialize memory
565 ;       hard reset  clear 3f-00h    F1=0
566 ;       soft reset  clear 20-00h    F1=1
567 X000c:  clr     f0              ; 000c - F0=0
568         clr     a               ; 000d - a=0
569 X000e:  mov     @r0,a           ; 000e - @r0=0   r0=$3f(hard)/$20(soft)
570         djnz    r0,X000e        ; 000f - clear RAM 3f/20h to $00
571         mov     psw,a           ; 0011 - psw=0
572         outl    p1,a            ; 0012 - p1=0
573         outl    p2,a            ; 0013 - p2=0
574         dis     tcnti           ; 0014 - disable timer overflow
575         dis     i               ; 0015 - disable INT
576         jf1     X001c           ; 0016 - jump if F1==1(Soft Reset?)
577
578 ; F1==0 Power on Reset
579         call    X01a9           ; 0018 - read keyboard id and set default parameter
580         jmp     X0202           ; 001a - Memory Test and go to Main
581
582 ; F1==1 Soft Reset
583 X001c:  call    X0020           ; 001c - ; r4=$21&07h|50h(52h?), a=r4
584         jmp     X0230           ; 001e - ; go to Main
585
586 ;;;;;;;;;;;;;;;;;;
587 ; Set r4
588 : INPUT:    r4???
589 : RETURN:   a=r4(original)
590 ;           r4=$21&07h|50h
591 ;
592 X0020:  mov     r0,#021h        ; 0020 -  r0=21h(keyboad identity bits)
593         mov     a,@r0           ; 0022 -  a=($21)
594         anl     a,#007h         ; 0023 -  a=a&07h
595         orl     a,#050h         ; 0025 -  a=a|50h
596         xch     a,r4            ; 0027 -  swap a,r4
597         ret                     ; 0028 -
598
599 ; read program memory @page0
600 ; INPUT: a:address
601 ; OUTPUT: a=(a)@page0
602 X0029:  movp    a,@a            ; 0029 -
603         jmp     X01a5           ; 002a - r1=r1+a, a=r0
604
605
606
607 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
608 ;
609 ; Receive data or Send scan code
610 ; INPUT:    F0=0:interpret command/1:retern data            used in Receive command/data
611 ; OUTPUT:   F0=0(received)/1(not received)
612 ; DONE: a=0, F1=1, buffer rotate
613 X002c:  clr     f0              ; 002c - F0=0
614 X002d:  jnt1    X0082           ; 002d - go to receive if T1(CLK)==L
615         sel     rb1             ; 002f - switch to bank1
616         mov     a,r5            ; 0030 - a=r5(bank1)            r5(bank1): scan code buffer
617         sel     rb0             ; 0031 - switch to bank0
618         jnz     X0035           ; 0032 - jump if r5(bank1)!=0
619         retr                    ; 0034 - return if r5(bank1)==0 buffer empty
620
621 ;;;;;;;;;;;;;;;;;;
622 ; Send scan code
623 ; INPUT:    a=data
624 ; OUTPUT:   F1=1:Sent,Rotate,Data ready/0:???
625 X0035:  dec     a               ; 0035 - a--
626         clr     c               ; 0036 - c=0
627         call    X00de           ; 0037 - c=parity calc
628         jnt1    X0082           ; 0039 - go to receive if T1(CLK)=L
629 ; Start bit
630         anl     bus,#0bfh       ; 003b - [CLK=L]
631         orl     bus,#020h       ; 003d - [DATA=H]        [[[Start bit]]]
632         mov     r0,#010h        ; 003f - r0=10h
633
634
635 ; check inhibited(DATA==L) - check DATA line released by host
636 X0041:  jni     X0047           ; 0041 - jump if DATA==L LOOP>
637         jni     X0049           ; 0043 - jump if DATA==L
638         jmp     X0054           ; 0045 - cont. if DATA==H
639 X0047:  jmp     X0049           ; 0047 -
640 X0049:  djnz    r0,X0041        ; 0049 - <LOOP  timeout?
641 ; time out - end
642         orl     bus,#040h       ; 004b - [CLK=H]
643         anl     bus,#0dfh       ; 004d - [DATA=L]       [[[idle state]]]
644         retr                    ; 004f - return send end(give up with inhibited)
645
646
647 ; check data==7eh   Keep data in 'Resend' buffer unless it is 7eh
648 X0050:  xrl     a,#07eh         ; 0050 - revert a
649         jmp     X005d           ; 0052 -
650
651 X0054:  mov     r0,#020h        ; 0054 - r0=20h 'Resend' Buffer
652         xrl     a,#07eh         ; 0056 - a=a^7eh(0111 1110)
653         jz      X0050           ; 0058 - jump if a==7eh
654 ; a!=7eh        retain data to $20(resend buffer) if data is not 7eh
655         xrl     a,#07eh         ; 005a - revert a
656         mov     @r0,a           ; 005c - $20=a  retain a to 'Resend' buffer
657
658
659 ; Data bit0-7 and Parity(c)
660 ; Pulse H:18/L:9??
661 X005d:  mov     r7,#009h        ; 005d - r7=9
662 X005f:  mov     r0,#009h        ; 005f - r0=9 LOOP>>
663         jb0     X0069           ; 0061 - jump if a:bit0==1
664 ; a:bit0==0
665 ; send DATA=0
666         anl     bus,#0dfh       ; 0063 - [DATA=L]
667         orl     bus,#040h       ; 0065 - [CLK=H]
668         jmp     X006f           ; 0067 -
669 ; a:bit0==1
670 ; send DATA=1
671 X0069:  orl     bus,#020h       ; 0069 - [DATA=H]
672         orl     bus,#040h       ; 006b - [CLK=H]
673         jmp     X006f           ; 006d -
674 ; hold CLK=H
675 X006f:  djnz    r0,X006f        ; 006f - 9*2cycle delay (around 60us??)
676         anl     bus,#0bfh       ; 0071 - [CLK=L]
677         rrc     a               ; 0073 - a=a>>1, c=a:bit0
678         djnz    r7,X005f        ; 0074 - <<LOOP
679 ; Stop bit
680 ; a=0, F1=1, buffer rotate
681         anl     bus,#0dfh       ; 0076 - [DATA=L]           [Idle]  End
682         clr     a               ; 0078 - a=0
683         clr     f1              ; 0079 -
684         cpl     f1              ; 007a - F1=1               [Sent?]
685         orl     bus,#040h       ; 007b - [CLK=H]            [Idle]  End
686 ; remove from outgoing buffer: r7=0, r6=r7, r5=r6
687         sel     rb1             ; 007d - switch to bank1
688         xch     a,r7            ; 007e -
689         xch     a,r6            ; 007f -
690         xch     a,r5            ; 0080 - 0->r7->r6->r5->a  [Bank1 Buffer rotate]
691         retr                    ; 0081 - retr reverts to bank0
692
693
694
695 ;;;;;;;;;;;;;;;;;;
696 ; Receive command/data from host
697 ; INPUT:    F0=0:interpret command/1:return data(used by command)
698 ; OUTPUT:   F0=0(received)/1(not received)
699 ;           F1=1:Error/0:OK
700 ; a: data
701 ; c: parity
702 ; F1: 0: Receive or Send 1: Receive
703 ;
704 X0082:  jf1     X0086           ; 0082 -  jump if F1==1
705 ; F1==0
706         jmp     X002d           ; 0084 -  Can't recevie, do 'Receive or Send' again
707 ; F1==1
708 X0086:  mov     r0,#006h        ; 0086 -  r0=6h
709 X0088:  djnz    r0,X0088        ; 0088 -  6*2cycle dealy
710         jt1     X00cb           ; 008a -  return if T1(CLK)==H
711         anl     bus,#0bfh       ; 008c -  [CLK=L]
712         orl     bus,#020h       ; 008e -  [DATA=H]                  [Start bit]
713         mov     r0,#011h        ; 0090 -
714 X0092:  djnz    r0,X0092        ; 0092 -  11*2cycle delay
715         mov     r7,#009h        ; 0094 -  r7=9h
716 X0096:  orl     bus,#040h       ; 0096 -  LOOP>[CLK=H]              [Clock up for receive]
717         mov     r0,#008h        ; 0098 -
718 X009a:  djnz    r0,X009a        ; 009a -  8*2cycle delay
719         anl     bus,#0bfh       ; 009c -  [CLK=L]                   [Clock down]
720         jni     X00a9           ; 009e -  jump if INT(DATA)==L      [Read bit] Read twice for debounce?
721 ; DATA==H
722         orl     a,#001h         ; 00a0 -  a:bit0=1
723         jni     X00ad           ; 00a2 -  jump if INT(DATA)==L
724 ; DATA==H
725 X00a4:  rrc     a               ; 00a4 -  a=a>>1 with carry         [Next bit]
726         djnz    r7,X0096        ; 00a5 -  <LOOP
727         jmp     X00b0           ; 00a7 -                            [go to Stop]
728 ; DATA==L
729 X00a9:  anl     a,#0feh         ; 00a9 - a:bit0=0
730         jni     X00a4           ; 00ab -  jump if INT(DATA)==L
731 ; DATA==H
732 X00ad:  clr     f1              ; 00ad -  F1=0                      [Receive Error]
733         jmp     X00a4           ; 00ae -
734
735
736 ; wait for Stop/ACK (DATA=H)
737 ; F0: 0=jump table, 1=return(with F0=0)
738 X00b0:  orl     bus,#040h       ; 00b0 - [CLK=H]                    [Idle] End
739         mov     r0,#004h        ; 00b2 -
740 X00b4:  djnz    r0,X00b4        ; 00b4 - 4*2cycle? 8*0.2us=1.6us?
741         jni     X00c7           ; 00b6 - jump if INT(DATA)==L       [Stop Error] *no error response?
742 ; DATA==H
743         anl     bus,#0dfh       ; 00b8 - [DATA=L]                   [Idle] End
744         jf1     X00cc           ; 00ba - jump if F1==1
745 ; F1==0                                                             [Receive Error]
746
747
748 ; push 7eh into outgoing buffer (Receive Error at 00bah/Parity Error at 00ceh)
749 X00bc:  mov     a,#07eh         ; 00bc - 7eh: error response
750
751 ; push data into top of outgoing buffer(Error response)
752 ; a:data
753 ; r5=a, r6=r5, r7=r6
754 X00be:  sel     rb1             ; 00be - switch to bank1
755         inc     a               ; 00bf - a++
756         xch     a,r5            ; 00c0 - a->r5->r6->r7->a
757         xch     a,r6            ; 00c1 -
758         xch     a,r7            ; 00c2 -
759         jz      X00cb           ; 00c3 - jump if a==0
760         mov     r7,#0ffh        ; 00c5 - r7=ffh overflow            [Over flow:FE]
761
762 X00c7:  anl     bus,#0dfh       ; 00c7 - [DATA=L]                   [Idle] End
763         clr     f1              ; 00c9 -
764         cpl     f1              ; 00ca - F1=1                       [Error flag]
765 X00cb:  retr                    ; 00cb -
766
767
768
769 ; check parity of recieve data
770 ; F1==1
771 X00cc:  call    X00de           ; 00cc - call parity calc
772         jc      X00bc           ; 00ce - jump if carryflag=1    (Parity ERROR)
773 ; parity OK
774         jf0     X00dc           ; 00d0 - jump if F0==1
775
776
777 ;;;;;;;;;;;;;;;;;
778 ; F0==0
779 ; Interpret command
780 ;
781         cpl     a               ; 00d2 - compliment a       ffh-a(command)
782         add     a,#jump_table   ; 00d3 - a=a+#jump_table
783         jc      X00d8           ; 00d5 -
784         jmpp    @a              ; 00d7 - jump table             [Keyboard command]
785 ; Command Out bound Error
786 X00d8:  mov     a,#0fdh         ; 00d8 -    error response: FD
787         jmp     X00be           ; 00da -
788
789 ;;;;;;;;;;;;;;;;;
790 ; F0==1
791 ; Return data
792 X00dc:  cpl     f0              ; 00dc - F0=~F0(=0)
793         ret                     ; 00dd -
794 ;
795 ; recieve data/command
796 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
797
798
799 ;;;;;;;;;;;;;;;;;;
800 ; calculate parity: 'c' depends on number of '1' in 'a'
801 ;   INPUT: a=data
802 ;   OUTPUT: c(carry flag)
803 X00de:  mov     r0,#008h        ; 00de - b8 08  8.  r0=8h
804 X00e0:  rr      a               ; 00e0 - 77     w   a=a>>1
805         jb0     X00e4           ; 00e1 - 12 e4  .d  jump if a:bit0==1
806         cpl     c               ; 00e3 - a7     '   compliment carry flag
807 X00e4:  djnz    r0,X00e0        ; 00e4 - e8 e0  h`  jump if --r0!=0
808         cpl     c               ; 00e6 - a7     '
809         ret                     ; 00e7 - 83     .
810
811
812
813 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
814 ;
815 ; Keyboard command  jump table
816 ;
817 ; jump_table:1 FE   Resend(return content of $20)
818 X00e8:  mov     r0,#020h        ; 00e8 -  $20
819         mov     a,@r0           ; 00ea -  a=$20 get from resend buffer
820         jmp     X00be           ; 00eb -  push into outogoing buffer
821
822 ; jump_table:2 FD   r6=0bh, r4=r4|80h
823         mov     r6,#00bh        ; 00ed -  r6=0bh  BZ duration(scan cycles)?
824         orl     bus,#080h       ; 00ef -  BZ=H(on)
825         mov     a,r4            ; 00f1 -
826         orl     a,#080h         ; 00f2 -  BZ=H
827         mov     r4,a            ; 00f4 -  r4=r4|80h BZ=H(on) bus-default
828         retr                    ; 00f5 -
829
830 ; jump_table:3 FC
831         mov     r1,#01eh        ; 00f6 -  r1=1eh
832         jmp     X0100           ; 00f8 -
833
834 ;
835 ; keyboard commands:
836 ;
837 ; FF: jump_table0   Soft Reset(008h)
838 ; FE: jump_table1   Resend(return content of $20)
839 ; FD: jump_table2   BZ set BZ=H(on) to bus and r4(bus-default), duration to r6
840 ; FC: jump_table3   Set key configuration
841 ; FB: jump_table4   Soft Reset(008h)
842 ; FA: jump_table5   Reset(000h)
843 ;
844 jump_table:     db      008h,0e8h,0edh,0f6h,008h,000h           ; 00fa .hmv..
845 ;
846 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
847
848
849
850 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
851 ;
852 ; command FC    parameter configuration
853 ;   clear $22-3f, then set data received from host
854 ;
855 ; r4:
856 ;   set to $21&07h|50h
857 ; r7: received data
858 ;   r7=data|7fh
859 ;       F0=0 if data:bit7=1
860 ;       F0=1 if data:bit7=0
861 ;
862 ; data received(r7):
863 ;   FF      End(0114h)
864 ;   FE      Resend and receive again(011ah)
865 ;   FF-80   F0=0    if bit7 of r7 is set
866 ;   7F-00   F0=1    if bit7 of r7 is reset
867 ;
868 ;
869
870 ;;;;;;;;;;;;;;;;;;
871 ; clear parameter configuration RAM $3f..22
872 ; INPUT: r1=1eh=30
873 ;   called at 00f6h
874 X0100:  clr     a               ; 0100 - a=0
875         mov     r0,#03fh        ; 0101 - r0=3f
876 X0103:  mov     @r0,a           ; 0103 - $3f=a
877         dec     r0              ; 0104 - r0--
878         djnz    r1,X0103        ; 0105 -
879         call    X01af           ; 0107 - Read keyboar id and set parameter flags
880         call    X0020           ; 0109 - r4=($21 & 07h | 50h) =52h
881
882 ;;;;;;;;;;;;;;;;;;
883 ; data receive from host
884 ;
885 X010b:  clr     f0              ; 010b - LOOP>>
886         cpl     f0              ; 010c - F0=1
887 X010d:  call    X002d           ; 010d - receive/send data with F0=1
888         jf0     X010d           ; 010f - LOOP while F0==1
889
890
891 ; received data from host(F0==0)
892         mov     r7,a            ; 0111 - r7=data received
893         cpl     c               ; 0112 - c=~c
894         cpl     a               ; 0113 - a=~a
895
896 ;;;;;;;;;;;;;;;;;
897 ; a==FF *End*
898         jz      X013b           ; 0114 - return if a==FF
899         xrl     a,#001h         ; 0116 -
900         jnz     X011e           ; 0118 - jump if a!=FE
901
902 ;;;;;;;;;;;;;;;;;
903 ; a==FE *Resend*
904         call    X00e8           ; 011a - Resend         and continue...
905         jmp     X010b           ; 011c - <<LOOP         Send/Receive loop again
906
907 ;;;;;;;;;;;;;;;;;
908 ; else  *Set flag*
909 ;   data:bit7=1:enable break/0:enable repeat
910 X011e:  mov     a,r7            ; 011e - a=r7(data received)
911         jb7     X0122           ; 011f - jump if a:bit7==1  (1xxx xxxx)
912         cpl     f0              ; 0121 - F0=~F0=1   if a:bit7==0    [F0=1 means data:bit7==0]
913 X0122:  anl     a,#07fh         ; 0122 - a=a&7fh                    [data:bit6-0=scan code]
914         mov     r7,a            ; 0124 - r7=a
915
916
917 ; identify keybaord from $21=keyboar identity bits
918         mov     r1,#021h        ; 0125 - r1=21h
919         mov     a,@r1           ; 0127 - a=($21)
920         anl     a,#0f0h         ; 0128 - a=a&f0h
921         xrl     a,#020h         ; 012a - a=a^20h
922         jz      X013c           ; 012c - jump if $21==0010 xxxx     6019273 50-key?
923         xrl     a,#010h         ; 012e - a=a^10h
924         jz      X0142           ; 0130 - jump if $21==0011 xxxx     *6019284 62-key*
925         xrl     a,#070h         ; 0132 - a=a^70h
926         jz      X0148           ; 0134 - jump if $21==0100 xxxx     6019303 77-key?
927
928 ; Unknown keyboard
929         mov     a,r7            ; 0136 - a=r7(received data)
930         call    X015f           ; 0137 -                                [Set flag]
931         jmp     X010b           ; 0139 - <<LOOP receive again
932
933 ; End
934 X013b:  retr                    ; 013b -
935
936
937
938 ; Set 'index' and 'size' scan code table for each keyboard model
939 ;   r1: end of scan code table(index)
940 ;   r2: number of scan code table(size)
941 ; 6019273 50-key?
942 X013c:  mov     r1,#0afh        ; 013c - r1=afh     address@page3   03afh(table1)
943         mov     r2,#038h        ; 013e - r2=38h     0011 10(00)     56keys
944         jmp     X014c           ; 0140 -
945
946 ; *6019284 62-key*
947 X0142:  mov     r1,#0efh        ; 0142 - r1=efh     address@page3   03efh(table2)
948         mov     r2,#040h        ; 0144 - r2=40h     0100 00(00)     64keys
949         jmp     X014c           ; 0146 -
950
951 ; 6019303 77-key?
952 X0148:  mov     r1,#0ffh        ; 0148 - r1=ffh     address@page3   03ffh(table2)
953         mov     r2,#050h        ; 014a - r2=50h     0101 00(00)     80keys
954
955
956
957 ; get scancode from table and test loop
958 LOOP>>
959 X014c:  mov     a,r1            ; 014c - a=r1
960         movp3   a,@a            ; 014d - a=(r1)     read scan code table
961         xrl     a,r7            ; 014e - a=a^r7     a==r7(received scan code)
962         jnz     X0156           ; 014f -
963
964 ; scan code(a) == received data(r7)
965         dec     r2              ; 0151 - r2--
966         mov     a,r2            ; 0152 - a=r2
967         call    X015f           ; 0153 - call                           [Set flag]
968         inc     r2              ; 0155 - r2++
969
970 ; check next scan code
971 X0156:  dec     r1              ; 0156 - r1--               r1: address of table
972         djnz    r2,X014c        ; 0157 - <<LOOP while --r2  r2: number of table
973
974         jnc     X015d           ; 0159 - jump if r1>=0
975         call    X00d8           ; 015b - Error: FD and cont.            [Out of bound Error: FD]
976 X015d:  jmp     X010b           ; 015d - <<LOOP Receive next data
977 ;;;
978
979
980 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
981 ; Set flag routine
982 ;
983 ; INPUT: a=table index(number of table)
984 ;        a: AAAA AAFF(AAAAAA:index of parameter RAM, FF: flag position(0-3))
985 ;
986 X015f:  clr     c               ; 015f - c=0
987                                 ; calculate RAM address
988         mov     r2,a            ; 0160 - r2=a       r2=data
989         rr      a               ; 0161 - a=a>>1
990         rr      a               ; 0162 - a=a>>1     a/4(four keys per a parameter byte)
991         add     a,#022h         ; 0163 - a=a+22h    start of parameter bytes
992         mov     r0,a            ; 0165 - r0=a       r0=parameter address
993
994         mov     a,r2            ; 0166 - a=r2
995         anl     a,#003h         ; 0167 - a=a&03h            [a=flag position]
996         jz      X017e           ; 0169 - if FF==0b00
997         dec     a               ; 016b - a--
998         jz      X018a           ; 016c - if FF==0b01
999         dec     a               ; 016e - a--
1000         jz      X0197           ; 016f - if FF==0b10
1001
1002 ;
1003 ; Parameter byte and configure flags
1004 ;   bit 7   6   5   4   3   2   1   0
1005 ;       3r  3b  2r  2b  1r  1b  0r  0b
1006
1007 ;;;;;;;;;;;;;;;;;;
1008 ; FF==11b:  3r/3b
1009         mov     a,@r0           ; 0171 - a=(r0)             r0=parameter address
1010         anl     a,#03fh         ; 0172 - a=a&0011 1111b     clear 3r/3b
1011         jf0     X017a           ; 0174 - jump if F0==1
1012 ; F0==0(received data:bit7==1)
1013 ; a=a|40h
1014         orl     a,#040h         ; 0176 - a=a|0100 0000b     3b: break enabled
1015
1016
1017
1018 ;;;;;;;;;;;;;;;;;;
1019 ; store to RAM and return
1020 X0178:  mov     @r0,a           ; 0178 - (r0)=a store parameter to RAM
1021         ret                     ; 0179 - return a: command/received data
1022 ; End of Set flag
1023 ;;;;;;;;;;;;;;;;;;
1024
1025
1026
1027 ; F0==1 (data:bit7==0)
1028 ; a=a|80h
1029 X017a:  orl     a,#080h         ; 017a - a=a|1000 0000b     3r: repeat enabled
1030         jmp     X0178           ; 017c -
1031 ;;;
1032
1033
1034 ;;;;;;;;;;;;;;;;;;
1035 ; FF==00b:  0r/0b
1036 X017e:  mov     a,@r0           ; 017e - a=(r0)
1037         anl     a,#0fch         ; 017f - a=a & 1111 1100b   clear 0r/0b
1038         jf0     X0186           ; 0181 - jump if F0==1
1039 ; F0==0(data:bit==1)
1040         inc     a               ; 0183 - a++                0b: break enabled
1041         jmp     X0178           ; 0184 -
1042 ; F0==1(data:bit==0)
1043 X0186:  orl     a,#002h         ; 0186 -                    0r: repeat enabled
1044         jmp     X0178           ; 0188 -
1045 ;;;
1046
1047
1048 ;;;;;;;;;;;;;;;;;;
1049 ; FF==01b:  1r/1b
1050 X018a:  mov     a,@r0           ; 018a -
1051         anl     a,#0f3h         ; 018b -                    clear 1r/1b
1052         jf0     X0193           ; 018d -
1053 ; F0==0(data:bit==1)
1054         orl     a,#004h         ; 018f -                    1b: break enabled
1055         jmp     X0178           ; 0191 -
1056 ; F0==1(data:bit==0)
1057 X0193:  orl     a,#008h         ; 0193 -                    1r: repeat enabled
1058         jmp     X0178           ; 0195 -
1059 ;;;
1060
1061
1062 ;;;;;;;;
1063 ; FF==10b   parameter|10h / parameter|20h
1064 X0197:  mov     a,@r0           ; 0197 -
1065         anl     a,#0cfh         ; 0198 -                    clear 2r/2b
1066         jf0     X01a0           ; 019a -
1067 ; F0==0(data:bit==1)
1068         orl     a,#010h         ; 019c -                    2b: break enabled
1069         jmp     X0178           ; 019e -
1070 ; F0==1(data:bit==0)
1071 X01a0:  orl     a,#020h         ; 01a0 -                    2r: repeat enabled
1072         jmp     X0178           ; 01a2 -
1073 ;;;
1074
1075
1076 ;
1077 ; End of command FC
1078 ;
1079 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1080
1081
1082
1083 ;;;;;;;;;;;;;;;;;;
1084 ; read program memory @page1
1085 ;   INPUT: a=address of program memory
1086 X01a4:  movp    a,@a            ; 01a4 - a=(a)@page1
1087
1088 ;   OUTPUT: r1=r1+a, a=r0
1089 ; r1=r1+a,a=r0
1090 X01a5:  add     a,r1            ; 01a5 -
1091         mov     r1,a            ; 01a6 - r1=a+r1
1092         mov     a,r0            ; 01a7 - a=r0
1093         ret                     ; 01a8 -
1094
1095
1096
1097 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1098 ;
1099 ; Scan row8(I) and set parameter flags(on Power on Reset)
1100 ;
1101 ; call from hard reset 0018h with a=0, r0=0, r1=0?
1102 ;   INPUT: r0, r1: for wait loop
1103 ;   OUTPUT: $21=keybaord identity bits, r4=$21&f0h
1104 ;
1105
1106 ;;;;;;;;;;;;;;;;;;
1107 ; delay to make Buzzer audible when powering up??
1108 X01a9:  djnz    r0,X01a9        ; 01a9 - r0*2cycle
1109         djnz    r1,X01a9        ; 01ab - r1*(r0*2cycle+2cycle) 256*(256*2+2)=131584(2us?/cycle) around 260ms??
1110         anl     bus,#0c0h       ; 01ad - BZ=_,CLK=_,DATA=L  line is idle
1111
1112
1113 ;;;;;;;;;;;;;;;;;;
1114 ;
1115 ; Read keyboard identity bits from row8(I) and set parameter flags(on command FC)
1116 ;   INPUT: a=0
1117 ;   OUTPUT: r4=a=scanned data of row8(I)=keyboard identity bits
1118 ;
1119 ;   F0: 1:read(frist)/0:read(second)&settle
1120 ;        It needs to read same value twice to settle.
1121 ;
1122 ;   Keyboar id bit pattern on PCB:
1123 ;       mark:       1
1124 ;       brank:      0
1125 ;   Sensor value meaning:
1126 ;       Sensor:     0           1
1127 ;       Kbd id:     1(mark)     0(blank)
1128 ;       Key:        1(pressed)  0(released)
1129 ;
1130 ; called from command FC 0107h
1131 X01af:  mov     r7,#008h        ; 01af - r7=08h                 [column]
1132 X01b1:  rl      a               ; 01b1 - a=a<<1 LOOP_0{         [next column]
1133 X01b2:  mov     r4,a            ; 01b2 - LOOP{  r4=a            [data]
1134         cpl     f0              ; 01b3 - F0=~F0     toggle F0   [read twice to debounce]
1135         mov     a,r7            ; 01b4 - a=r7
1136         dec     a               ; 01b5 - a--
1137         orl     a,#0c0h         ; 01b6 - col(7-0)|c0h = c7-c0h  BZ=H:on [Beep during FC command]
1138         outl    bus,a           ; 01b8 -                        [Select column]
1139         orl     bus,#010h       ; 01b9 - D4=1                   [charge sensor out=H?]
1140         mov     a,#0d2h         ; 01bb - 1101 0010
1141         outl    bus,a           ; 01bd - bus=d2h   D4-0=10010   select column 2?
1142
1143 ;
1144         orl     p2,#001h        ; 01be - P2:0=1                 [select row8(I)]
1145         mov     a,r4            ; 01c0 - a=r4(data)
1146         orl     bus,#008h       ; 01c1 - bus=d2h|08h=dah  D4=1  [Strobe?](1101 1010)
1147         anl     p2,#000h        ; 01c3 - P2:0=L                 [unselect row8(I)]
1148
1149 ; check sensor out(T0)
1150         jt0     X01d5           ; 01c5 - jump if T0==H
1151         jf0     X01cd           ; 01c7 - jump if F0==1
1152         jb0     X01d9           ; 01c9 - jump if a:bit0==1      [Settle]
1153         ; TO(sensor)==0 && F0==0 && a:bit0==0
1154         jmp     X01b2           ; 01cb -  }LOOP
1155
1156 ; record 1(a=a|01h) when key is on(T0=L) and F0==1
1157 ; T0(sensor)==L(off) && F0==1 (from 01c7)
1158 X01cd:  orl     a,#001h         ; 01cd - a=a|1                  [Set a:bit0=H]
1159         jmp     X01b2           ; 01cf - LOOP
1160
1161 ; record 0(a=a&feh) when key is off(T0=H) and F0==0
1162 ; T0(sensor)==H(on) && F0==0 && a:bit0==1(off) (from 01d7)
1163 X01d1:  anl     a,#0feh         ; 01d1 - a=a&feh                [Set a:bit0=L]
1164         jmp     X01b2           ; 01d3 - LOOP
1165
1166 ; scan LOOP again
1167 ; T0(sensor)==H(on) && F0==1 (from 01c5)
1168 X01d5:  jf0     X01b2           ; 01d5 - LOOP while F0==1
1169
1170 ; T0(sensor)==H(on) && F0==0
1171         jb0     X01d1           ; 01d7 - jump if a:bit0==1 [need to change r4(a) to 0]
1172
1173 ; next column
1174 ; T0(sensor)==H && F0==0 && a:bit0==0 OR
1175 ; T0(sensor)==L && F0==0 && a:bit0==1   (from 01c9)
1176 X01d9:  djnz    r7,X01b1        ; 01d9 - }LOOP_0 while --r7>0 [Next column]
1177         mov     r4,a            ; 01db - r4=a               a=r4=scanned data of Row8(I)
1178
1179
1180 ;;;;;;;;;;;;;;;;;;
1181 ;  Set parameters from scanned data of row 8(I)
1182 ;
1183 ;   INPUT:  a=r4=keyboard identity bits
1184 ;   OUTPUT: $21=keybaord identity bits, r4=$21&f0h
1185 ;
1186         anl     a,#0f0h         ; 01dc - a=a&f0h
1187         xrl     a,#020h         ; 01de - a=a^20h            (a==0010 xxxx)  6019273
1188         jz      X01ec           ; 01e0 - jump if a==0
1189         xrl     a,#010h         ; 01e2 - a=a^10h            (a==0011 xxxx) *6019284 when power on reset
1190         jz      X01f2           ; 01e4 - jump if a==0
1191         xrl     a,#070h         ; 01e6 - a=a^70h            (a==0100 xxxx)  6019303
1192         jz      X01f2           ; 01e8 - jump if a==0
1193         jmp     X01fa           ; 01ea -
1194
1195 ; $21==(0010 xxxx)  for 6019273(50-key)
1196 ; set break enalbe flag for Reset(or on other layout?)
1197 X01ec:  mov     r0,#022h        ; 01ec -
1198         mov     @r0,#001h       ; 01ee - $22=1      $22:bit0=break enable falg of ????
1199         jmp     X01fa           ; 01f0 -
1200
1201 ; $21==(0011 0010 | 0100 xxxx)  for 6019284(62-key) or 6019303(77-key) layout
1202 ; set break enable flag for LAlt and RAlt *6019284
1203 X01f2:  mov     r0,#02eh        ; 01f2 -
1204         mov     @r0,#001h       ; 01f4 - $2e=1      $2e:bit0=break enable flag of LAlt
1205         mov     r0,#024h        ; 01f6 -
1206         mov     @r0,#001h       ; 01f8 - $24=1      $24:bit0=break enable flag of RAlt
1207
1208 ; set $21 to scanned data of row 8(I)   [keyboard identity bits]
1209 X01fa:  mov     r0,#021h        ; 01fa -
1210         mov     a,r4            ; 01fc -
1211         mov     @r0,a           ; 01fd - ($21)=r4     $21: r4=identity bits(row 8(I))
1212         anl     a,#0f0h         ; 01fe -
1213         mov     r4,a            ; 0200 - r4=r4&f0h
1214         ret                     ; 0201 -
1215 ;
1216 ; End of Scan row8(I)
1217 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1218
1219
1220 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1221 ;
1222 ; Test and clear memory(3fh..00h) on Power on Reset
1223 ;
1224 X0202:  mov     r0,#03fh        ; 0202 -  $3f
1225 X0204:  mov     a,@r0           ; 0204 -  LOOP>>
1226         mov     r1,a            ; 0205 -  r1=(r0) r0=3f..00
1227         mov     a,#0ffh         ; 0206 -  a=ffh
1228         mov     @r0,a           ; 0208 -  (r0)=ffh
1229         xrl     a,@r0           ; 0209 -  a=a^ffh =0??
1230         jnz     X0224           ; 020a -  jump if a!=ffh    *always should be a=zero*
1231         mov     @r0,a           ; 020c -  (r0)=a    (=0)
1232         mov     a,@r0           ; 020d -  a=(r0)
1233         jnz     X0224           ; 020e -  jump if a!=ffh    *always should be a=zero*
1234         mov     a,r1            ; 0210 -  a=r1
1235         mov     @r0,a           ; 0211 -  (r0)=a (revert to origin value)
1236         djnz    r0,X0204        ; 0212 -  <<LOOP --r0
1237
1238 ;
1239 ; Test program memory(0,255..1 @page0,1,2,3)
1240 ;
1241 ; INPUT: r0=0 r4=??
1242 ; OUTPUT: r4=$21&07h|50h, a=swapHL(r4(original)) or feh
1243 X0214:  mov     a,r0            ; 0214 -  LOOP>>   a=r0=0
1244         call    X0029           ; 0215 -  r1=r1+(a), a=r0 (page0)
1245         call    X01a4           ; 0217 -  r1=r1+(a), a=r0 (page1)
1246         movp    a,@a            ; 0219 -
1247         call    X01a5           ; 021a -  r1=r1+(a), a=r0 (page2)
1248         movp3   a,@a            ; 021c -
1249         call    X01a5           ; 021d -  r1=r1+(a), a=r0 (page3)
1250         djnz    r0,X0214        ; 021f -  <<LOOP --r0
1251         mov     a,r1            ; 0221 -  a=r1  sum of program memory data
1252         jz      X0226           ; 0222 -  sum of program memory data != 0 if no error ???
1253
1254 ; Send FE on error and r4 on success
1255 X0224:  mov     r4,#0efh        ; 0224 -  r4=efh    Memory error
1256 X0226:  call    X0020           ; 0226 -  r4=$21&07h|50h, a=r4(keyboard id or efh)
1257         swap    a               ; 0228 -  swap a:h<->a:l
1258         orl     a,#0a0h         ; 0229 -  a=a|a0h(1010 iiii)    i:keyboard id(hi-bits)
1259         call    X0339           ; 022b -  queue data(a) to buffer
1260         call    X010b           ; 022d -  send kbd ID and wait for data from host   [FC command]
1261         strt    t               ; 022f -  start timer
1262 ; Usually first data form keyboard at startup is A3h(sum of program memory?).
1263 ; FEh for memory error??
1264 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1265
1266
1267
1268 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1269 ;
1270 ; Main??
1271 ;
1272 ; check scan code buffer to send
1273 X0230:  call    X002c           ; 0230 - receive/send data
1274         mov     a,r6            ; 0232 - a=r6 set by command FD Short Beep(0bh at 00edh)
1275         jz      X023d           ; 0233 -
1276         djnz    r6,X023d        ; 0235 - r6--
1277 ; Buzzer off
1278         anl     bus,#07fh       ; 0237 - BZ=L(off)   when get to r6==0  [Short Beep ends]
1279         mov     a,r4            ; 0239 -
1280         anl     a,#07fh         ; 023a -
1281         mov     r4,a            ; 023c - r4=r4&7fh(BZ=L:off) r4=bus-default
1282
1283 ; delay for scan    192*32cycle?
1284 X023d:  mov     a,t             ; 023d - a=t(timer)
1285         add     a,#064h         ; 023e - a=a+64h
1286         jnc     X023d           ; 0240 - delay for scan
1287         clr     a               ; 0242 - a=0
1288         mov     t,a             ; 0243 - t=0    timer clear
1289
1290 ; Start matrix scan
1291 ; r7=r4&c0h
1292 X0244:  mov     a,r4            ; 0244 - a=r4
1293         anl     a,#0c0h         ; 0245 - a=a&c0h        BZ=_,CLK=_,DAT=L:
1294         mov     r7,a            ; 0247 - r7=r4&c0h      r7=bus-current
1295         jf1     X0253           ; 0248 - jump if F1==1 (p1/p2)
1296
1297 ; F1==0
1298         cpl     f1              ; 024a - F1=1(=~F1)
1299         mov     r2,#03fh        ; 024b - r2=3fh         scan code seed
1300         mov     r3,#001h        ; 024d - r3=01h         row mask
1301         mov     r1,#015h        ; 024f - r1=15h         last key state
1302         jmp     X0263           ; 0251 - scan matrix p1 row
1303
1304 ; F1==1
1305 X0253:  clr     f0              ; 0253 - F0=0
1306         clr     f1              ; 0254 - F1=0
1307         mov     r2,#077h        ; 0255 - r2=77h         scan code seed
1308         mov     r3,#002h        ; 0257 - r3=02h
1309         mov     r1,#01ch        ; 0259 - r1=1ch         last key state
1310         jmp     X0287           ; 025b - Scan matrix p2 row
1311 ;
1312 ; INPUT:    F1=0
1313 X025d:  cpl     f1              ; 025d - F1=~F1=1
1314         call    X002c           ; 025e - receive/send data
1315         clr     f1              ; 0260 - F1=0
1316         jmp     X0244           ; 0261 -
1317
1318 ;;;;;;;;;;;;;;;;;;;;;;;;;;;
1319 ;
1320 ; scan matrix p1 row
1321 ; INPUT: F1=1, r1=15h, r2=3fh, r3=01h, r7=r4&c0h
1322 ;       (r1): last state
1323 ;
1324 ; r0:col, r7:bus-current, r3:row(drive H), r4=bus-default
1325 ;
1326 ; $15: bit7
1327 ;
1328 ; bus:  xxxS Gccc
1329 ;
1330 X0263:  mov     a,#008h         ; 0263 - a=8 LOOP>>>
1331         mov     r0,a            ; 0265 - r0=08h =column
1332         orl     a,r7            ; 0266 - a=08h|r7
1333         mov     r7,a            ; 0267 - r7=a     =xxxx  1ccc(G:1 column:ccc) r7=P1 value
1334 X0268:  dec     r7              ; 0268 - LOOP>> r7--
1335         mov     a,r7            ; 0269 - a=r7
1336         outl    bus,a           ; 026a -                        [select column]
1337         orl     bus,#010h       ; 026b - sensor out=H           [sensor clamp=H]???
1338         mov     a,r3            ; 026d - a=r3                   current row
1339         outl    p1,a            ; 026e - drive line with H      [select row]
1340         mov     a,r4            ; 026f - a=r4                   bus default value
1341         outl    bus,a           ; 0270 -                        [revert bus default]
1342         orl     bus,#008h       ; 0271 - D3:H sensor-G          [strobe]??? hold? clean Sensor?
1343         anl     p1,#000h        ; 0273 -                        [unselect row]
1344
1345         jnt0    X02ab           ; 0275 - sensor out==0
1346 ; Sensor==1[key is on]
1347         mov     a,@r1           ; 0277 - a=$(r1); r1=15...  last key state
1348         jb7     X02e5           ; 0278 - jump if a:bit7==1(off) press
1349 ; a:bit7==0(last key state is on)  same as last
1350 ;On->On
1351
1352
1353 ; Go to next column
1354 X027a:  rl      a               ; 027a - a=a<<1
1355         mov     @r1,a           ; 027b - (r1)=a; (r1)=(r1)<<1   next col of last key state
1356 X027c:  dec     r2              ; 027c - r2--                   [key index of scan code table]
1357         djnz    r0,X0268        ; 027d - <<LOOP(8)              [next col]
1358
1359         dec     r1              ; 027f - r1--   15,14,13,12,11,10,0F,0E? [last key state]
1360         mov     a,r3            ; 0280 -
1361         rl      a               ; 0281 -
1362         mov     r3,a            ; 0282 - r3=r3<<1 next row
1363         jb0     X0230           ; 0283 - jump if a:bit0==1  scan end(goto Main loop)
1364         jmp     X0263           ; 0285 - <<<LOOP                [next row]
1365
1366
1367 ;;;;;;;;;;;;;;;;;;;;;;;;;;;
1368 ;
1369 ; Scan matrix p2 row(F1==1)
1370 ; INPUT: F0=0, F1=0, r1=1ch, r2=77h, r3=02h, r7=bus-current, r4=bus-default
1371 ;
1372 ; r0:col, r7:bus-current, r3:row(drive H), r4=bus-default
1373 ;   key index: 77h-
1374 X0287:  mov     a,#008h         ; 0287 - a=8    LOOP>>
1375         mov     r0,a            ; 0289 - r0=8
1376         orl     a,r7            ; 028a - a=a|r7
1377         mov     r7,a            ; 028b - r7=a
1378 X028c:  dec     r7              ; 028c - r7-- LOOP>>
1379         mov     a,r7            ; 028d - a=r7
1380         outl    bus,a           ; 028e -                        [select column]
1381         mov     a,r4            ; 0293 -                        bus default value
1382         outl    bus,a           ; 0294 -                        [revert bus default]
1383         orl     bus,#008h       ; 0295 -                        [strobe]
1384         anl     p2,#000h        ; 0297 - p2=00h                 [unselect row]
1385         jnt0    X02ab           ; 0299 - jump if sensor out==0(key is on)
1386 ; sensor==1(key is off)
1387         mov     a,@r1           ; 029b - a=(r1)                 [last key state]
1388         jb7     X02e5           ; 029c - jump if a:bit7==1(off)  press
1389
1390 ; a:bit7==0(last key state is on)
1391 X029e:  rl      a               ; 029e - a=a<<1
1392         mov     @r1,a           ; 029f - (r1)=a                 [next last key bit]
1393 X02a0:  dec     r2              ; 02a0 - r2--(77h)
1394         djnz    r0,X028c        ; 02a1 - jump if r0--!=0 <<LOOP(8)
1395         dec     r1              ; 02a3 - r1--                   [next last key byte]
1396         mov     a,r3            ; 02a4 -
1397         rl      a               ; 02a5 -
1398         mov     r3,a            ; 02a6 - r3=r3<<1   [next row]??
1399         jb0     X025d           ; 02a7 -
1400         jmp     X0287           ; 02a9 - <<LOOP
1401
1402 ;
1403 ; debouncing and change last key state
1404 ;
1405 ; sensor out==0(press; key is on)
1406 ;
1407 ; debouncing
1408 X02ab:  call    X030d           ; 02ab - a=0(sensor out=1), ffh(sensor out=0)   [Sense key]
1409         jz      X02f8           ; 02ad - if a==0(key is off)
1410         call    X030d           ; 02af -                                        [Sense key]
1411         jz      X02f8           ; 02b1 - if a==0(key is off)
1412
1413 ; Sensor==0(a=ffh; press)
1414         mov     a,@r1           ; 02b3 - a=(r1) last key state????
1415         jb7     X02ca           ; 02b4 -
1416
1417 ;
1418 ; [release](off->on)
1419 ;
1420 ; last:bit7==0(off) && sensor=0(on)
1421         orl     a,#080h         ; 02b6 - 0:on   1:off
1422         rl      a               ; 02b8 -
1423         mov     @r1,a           ; 02b9 - (r1)=(r1)<<1   next column
1424         call    X0325           ; 02ba - key configure flag
1425                                 ;        (a:bit1=repeat enable, a:bit0=break enable)
1426 ; if keyconf:bit0==1 then set release flag
1427         jb0     X02fd           ; 02bc - r2=r2|80h          [press flag]
1428 ; if keyconf:bit1==1 then set repeat
1429         jb1     X02e1           ; 02be - r5=repeat delay    [repeat]
1430
1431 ; get scan code and queue it into buffer
1432 X02c0:  call    translate034E   ; 02c0 - a=scancode
1433         call    X0339           ; 02c2 - queue data to buffer
1434         call    X0303           ; 02c4 -                    [r1=a=address of last key state]
1435 X02c6:  jf1     X027c           ; 02c6 - next col(F1==1)
1436         jmp     X02a0           ; 02c8 - next col(F1==0)
1437
1438 ;
1439 ; [hold key]
1440 ;
1441 ; last key is on and sensor==0(on)     (on->on)
1442 X02ca:  rl      a               ; 02ca -
1443         mov     @r1,a           ; 02cb - (r1)=(r1)<<1
1444         call    X0325           ; 02cc - key configure flag
1445                                 ;        (a:bit1=repeat enable, a:bit0=break enable)
1446 ; repeat:flag
1447         jb1     X02d4           ; 02ce -                    [repeat]
1448
1449 ; if repeat:flag(bit1)==0  (no repeat)
1450 X02d0:  call    X0303           ; 02d0 - r1=r2&0fh+0eh      address of last key state
1451         jmp     X02c6           ; 02d2 - goto next col
1452
1453 ; if flag:bit1==1  (repeat)
1454 X02d4:  jf0     X02dd           ; 02d4 -
1455
1456 ; F0==0
1457         cpl     f0              ; 02d6 - F0=~F0=1
1458         djnz    r5,X02d0        ; 02d7 -
1459         mov     r5,#007h        ; 02d9 - r5=07h             repeat interval
1460         jmp     X02c0           ; 02db - send scan code
1461
1462 ; F0==1
1463 X02dd:  mov     r5,#028h        ; 02dd - r5=28h             repeat delay(for first repeat)
1464         jmp     X02d0           ; 02df -
1465 ;
1466 X02e1:  mov     r5,#028h        ; 02e1 - r5=28h             repeat delay(for first repeat)
1467         jmp     X02c0           ; 02e3 - send scan code
1468
1469
1470 ;
1471 ; debouncing and change last key state: press
1472 ;
1473 ;   INPUT: (r1): last key status
1474 ;
1475 ; (r1):bit7==1(last key is on) &&  Sensor==1(key is off)  [release]
1476 X02e5:  call    X030d           ; 02e5 - a=0(sensor out=1), ffh(sensor out=0)   [Sense key]
1477         jnz     X02f8           ; 02e7 -
1478         call    X030d           ; 02e9 -                                        [Sense key]
1479         jnz     X02f8           ; 02eb - \_debouncing
1480 ; Sensor==1(a=0)                                                                [Debounced]
1481
1482 ;
1483 ; on->off [release]
1484 ;
1485         mov     a,@r1           ; 02ed - a=(r1) RAM
1486         anl     a,#07fh         ; 02ee - a=a&7fh        last state=0(0:on 1:off)
1487         rl      a               ; 02f0 - a=a<<1
1488         mov     @r1,a           ; 02f1 - (r1)=a
1489 ;
1490         call    X0325           ; 02f2 - key configure flag
1491                                 ;        (a:bit1=repeat enable, a:bit0=break enable)
1492         jb0     X02c0           ; 02f4 - goto translate if a:bit0==1
1493         jmp     X02d0           ; 02f6 -
1494
1495 ; go to next col scan   Sensor==1
1496 X02f8:  mov     a,@r1           ; 02f8 -
1497         jf1     X027a           ; 02f9 - goto next col scan(p1) if F1==1        [Next column]
1498         jmp     X029e           ; 02fb - goto next col scan(p2) else            [Next column]
1499
1500 ;
1501 ; add press flag(bit8)
1502 ; r2=key index
1503 X02fd:  mov     a,r2            ; 02fd -                                        [key index]
1504         orl     a,#080h         ; 02fe -
1505         mov     r2,a            ; 0300 - r2=r2|80h  **press flag**
1506         jmp     X02c0           ; 0301 -
1507
1508 ; Address of last key state
1509 ; INPUT: r2=key index
1510 ; OUTPUT: r1=(r2>>3)&0fh+0eh    = address of last key state
1511 X0303:  mov     a,r2            ; 0303 - a=r2   key index
1512         rr      a               ; 0304 -
1513         rr      a               ; 0305 -
1514         rr      a               ; 0306 - a= a>>3
1515         anl     a,#00fh         ; 0307 - a= a & 0fh
1516         add     a,#00eh         ; 0309 - a= a + 0eh
1517         mov     r1,a            ; 030b - r1=a
1518         ret                     ; 030c -
1519
1520 ;;;;;;;;;;;;;;;;;;;;;;;
1521 ; Sense key
1522 ;   INPUT: r7: bus-current, F1:0(p2),1(p1) r4=bus-default, r3=row
1523 ;   RETURN: a=0xff(sensor out=0, press), 0(sensor out=1, release)
1524 ;
1525 X030d:  mov     a,r7            ; 030d - r7: bus-current
1526         outl    bus,a           ; 030e -                            [Select column]
1527         orl     bus,#010h       ; 030f -                            [Charge: D4]
1528         mov     a,r3            ; 0311 - r3: row(drive) select      p1(F1=1)/p2(F1=0) setting
1529         jf1     X0317           ; 0312 -
1530 ; F1==0
1531         outl    p2,a            ; 0314 - set p2                     [Select row]
1532         jmp     X0318           ; 0315 -
1533 ; F1==1
1534 X0317:  outl    p1,a            ; 0317 - set p1                     [Select row]
1535
1536 X0318:  mov     a,r4            ; 0318 - r4: bus-default
1537         outl    bus,a           ; 0319 - set bus
1538         clr     a               ; 031a - a=0
1539         orl     bus,#008h       ; 031b -                            [Strobe: D3]
1540         anl     p1,#000h        ; 031d - clear p1                   [Unselect row]
1541         anl     p2,#000h        ; 031f - clear p2                   [Unselect row]
1542
1543         jt0     X0324           ; 0321 - sensor out==1
1544 sensor out==0
1545         cpl     a               ; 0323 -  a=0xff                    [press(on)]
1546 sensor out==1
1547 X0324:  ret                     ; 0324 -  a=0                       [release(off)]
1548 ;
1549 ; End of Main
1550 ;
1551 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1552
1553
1554
1555 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1556 ;
1557 ; key configure flags
1558 ;
1559 ; INPUT: r2=key index(p1:-3fh, p2:-77h)    (aaaaaaii)
1560 : OUTPUT: a=Key configure 2-bit flags;  bit0 and 1 are only valid. (------rb)
1561 ;
1562 :   Key configure flags are retained in RAM($22-3F) and
1563 ;   Key configure flags use 2bit per key so that a byte can has flags of four key like:
1564 ;       bit 7   6   5   4   3   2   1   0
1565 ;           3r  3b  2r  2b  1r  1b  0r  0b
1566 ;   where r=repeat enable, b=break code(release) eanble
1567 ;
1568 X0325:  mov     a,r2            ; 0325 - a=r2           index
1569         rr      a               ; 0326 -
1570         rr      a               ; 0327 - a=a>>2         bit7-2 of index(aaaaaa)
1571         add     a,#022h         ; 0328 - a=a+22h        $22+aaaaaa
1572         mov     r1,a            ; 032a - r1=a
1573         mov     a,@r1           ; 032b - a=(r1)         $22-3F(ignored bit7,bit6)
1574         mov     r1,a            ; 032c - r1=a           r1=($22-3F) ????
1575         mov     a,r2            ; 032d - a=r2           index
1576         anl     a,#003h         ; 032e - a=a&03h        a=bit0,bit1 of index
1577         xch     a,r1            ; 0330 - a<->r1         r1=bit0,bit1 of index, a=($22-3F)
1578         inc     r1              ; 0331 - r1++           =1-4
1579 X0332:  djnz    r1,X0335        ; 0332 - while --r1>0
1580         ret                     ; 0334 -
1581
1582 ; place flags of the key on bit0 and 1
1583 X0335:  rr      a               ; 0335 -
1584         rr      a               ; 0336 - a=a>>2; a=$22-3F
1585         jmp     X0332           ; 0337 -
1586
1587 ;
1588 ; Queue data to bottom of outgoing buffer(bank1:r5,r6,r7)
1589 ; INPUT: a=data, r2=???
1590 ; OUTPUT: r2=r2&07h
1591 ; a->r5->r6->r7
1592 X0339:  sel     rb1             ; 0339 -   switch to bank1
1593         inc     a               ; 033a -   a++
1594         xch     a,r5            ; 033b -   a<->r5
1595         jz      X0348           ; 033c -
1596         xch     a,r5            ; 033e -
1597         xch     a,r6            ; 033f -
1598         jz      X0348           ; 0340 -
1599         xch     a,r6            ; 0342 -
1600         xch     a,r7            ; 0343 -
1601         jz      X0348           ; 0344 -
1602         mov     r7,#0ffh        ; 0346 -   buffer overflow
1603 X0348:  sel     rb0             ; 0348 -   switch to bank0
1604         mov     a,r2            ; 0349 -   a=r2
1605         anl     a,#07fh         ; 034a -   a=a&7fh
1606         mov     r2,a            ; 034c -   r2=a
1607         ret                     ; 034d -
1608 ;
1609 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1610
1611
1612
1613 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1614 ;
1615 ; Translate key index into scancode
1616 ;
1617 ; INPUT: r2=keyindex [bit7:release flag(1:release/0:press), bit6-0:index]
1618 ; OUTPUT: a=scancode
1619 translate034E:
1620         mov     r1,#021h        ; 034e -
1621         mov     a,@r1           ; 0350 - a=$21  $21:bit6,5,4 = traslate table
1622         anl     a,#0f0h         ; 0351 - a=a & f0h
1623         xrl     a,#020h         ; 0353 - a=a ^ 20h      $21:bit5(0010 0000) 0010 xxxx => table1
1624         jz      X0361           ; 0355 - if a==0        read table1     (6019273 50-key)
1625         xrl     a,#010h         ; 0357 - a=a ^ 10h      $21:bit4(0001 0000) 0011 xxxx => table2
1626         jz      X0370           ; 0359 -                read table2     (6019284 62-key)
1627         xrl     a,#070h         ; 035b - a=a & 70h      $21:bit6(0111 0000) 0100 xxxx => table2
1628         jz      X0370           ; 035d -                read table2     (6019303 77-key)
1629         mov     a,r2            ; 035f -                else use r2(keyindex) instead of scancode
1630         ret                     ; 0360 -
1631 ; table1(8x7=56)
1632 X0361:  mov     a,r2            ; 0361 - keyindex
1633         anl     a,#07fh         ; 0362 -
1634         add     a,#078h         ; 0364 - table1
1635 ; read table
1636 X0366:  movp3   a,@a            ; 0366 - read scancode from table a=scan code
1637         xch     a,r2            ; 0367 - a=keyindex, r2=scancode
1638         jb7     X036c           ; 0368 - if keyindex:bit7==1 [relase event]
1639         xch     a,r2            ; 036a - a=scancode, r2=keyindex
1640         ret                     ; 036b -
1641 ; release flag
1642 X036c:  xch     a,r2            ; 036c -
1643         orl     a,#080h         ; 036d - [[[[[release flag(bit7)]]]]]
1644         ret                     ; 036f - a: scan code
1645 ; table2(8X10=80)
1646 X0370:  mov     a,r2            ; 0370 -
1647         anl     a,#07fh         ; 0371 -
1648         add     a,#0b0h         ; 0373 - table2
1649         jmp     X0366           ; 0375 - read table
1650
1651
1652 ; maybe 'salt' to make sum of program memory 'zero'(at 0222h)
1653         db      0b6h                                    ; 0377 6
1654
1655
1656 ;;;;;;;;;;;;;;;;;;
1657 ;
1658 ; Scancode table
1659 ;
1660
1661 ;;;;;;;;;;;;;;;;;;
1662 ; Used for 6019273                                        Add  Key              Parameter RAM
1663 table1: db      03fh,037h,03ah,036h,02ah,035h,022h,023h ; 0378
1664         db      03bh,02bh,039h,031h,032h,029h,021h,0ffh ; 0380
1665         db      033h,038h,0ffh,030h,028h,0ffh,020h,0ffh ; 0388
1666         db      017h,01dh,01ch,015h,00ch,00dh,004h,005h ; 0390
1667         db      00fh,01fh,01bh,013h,014h,00bh,003h,0ffh ; 0398
1668         db      00eh,01ah,019h,012h,009h,00ah,001h,002h ; 03a0
1669         db      016h,01eh,018h,010h,011h,008h,000h,0ffh ; 03a8
1670
1671 ;;;;;;;;;;;;;;;;;;
1672 ; Used for 6019284 and 6019303                            Add  Key              Parameter RAM
1673 table2: db      02fh,03dh,03ch,02dh,01dh,01ch,00ch,00eh ; 03b0 Enter ... BS     $22, $23
1674         db      03fh,042h,03bh,02bh,02ch,01bh,01fh,00dh ; 03b8 RAlt ...         $24, $25
1675         db      039h,03ah,029h,02ah,002h,003h,00ah,00fh ; 03c0 ...              $26, $27
1676         db      038h,037h,028h,027h,017h,001h,008h,009h ; 03c8 ...              $28, $29
1677         db      040h,036h,025h,026h,015h,016h,011h,012h ; 03d0 ...              $2a, $2b
1678         db      035h,034h,023h,024h,013h,014h,01ah,010h ; 03d8 ...              $2c, $2d
1679         db      03fh,032h,033h,022h,021h,006h,005h,019h ; 03e0 LAlt ...         $2e, $2f
1680         db      031h,041h,03eh,030h,020h,004h,000h,018h ; 03e8 Reset ... 1      $30, $31
1681         db      071h,076h,075h,066h,055h,056h,045h,046h ; 03f0 Used for 77-key  $32, $33
1682         db      077h,067h,074h,064h,065h,054h,0ffh,044h ; 03f8 Used for 77-key  $34, $35
1683 ;
1684 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1685
1686
1687
1688 ;
1689 ;       symbol equates
1690 ;
1691 ;  these are symbols from the control
1692 ;  file that are referenced in the code
1693 ;
1694 jump_table      equ     0fah
1695 ;
1696         end