From 1a93253a0723e1453c498f7b526e355b721899f6 Mon Sep 17 00:00:00 2001 From: Lars Brinkhoff Date: Fri, 5 Oct 2018 20:25:53 +0200 Subject: [PATCH] Use 8748 assembler to assemble Lispm keyboard PROM. --- build/lisp.tcl | 8 + src/lmio1/ukbd.24 | 671 ++++++++++++++++++++++++++++++++ src/lmio1/ukbd.prom | 917 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 1596 insertions(+) create mode 100644 src/lmio1/ukbd.24 create mode 100644 src/lmio1/ukbd.prom diff --git a/build/lisp.tcl b/build/lisp.tcl index bd6f955c..c9db14ec 100644 --- a/build/lisp.tcl +++ b/build/lisp.tcl @@ -1130,3 +1130,11 @@ respond "*" ":complr\r" respond "_" "lmio1;as8748\r" respond "_" "\032" type ":kill\r" + +respond "*" ":lisp\r" +respond "Alloc?" "n" +respond "*" "(load '((lmio1) as8748))" +respond_load "(load '((lmio1) ukbd))" +respond "T" "(as 'ukbd)" +respond "UKBD" "(quit)" +expect ":KILL" diff --git a/src/lmio1/ukbd.24 b/src/lmio1/ukbd.24 new file mode 100644 index 00000000..62a75621 --- /dev/null +++ b/src/lmio1/ukbd.24 @@ -0,0 +1,671 @@ +;;; -*- Mode: Lisp; Base: 8; Package: User; Lowercase:t -*- + +;Assemble this with HIC;AS8748 and stuff it into a keyboard with LMIO1;PROMP + +;This is the new (11/18/80) version for use with the new keyboard PC, +;which contains a 24-bit shift register for faster transmission to the +;host and provides for running the mouse through the keyboard ("remote mouse" +;in the IOB). + +;9/18/81 modified as follows: +; Check the mouse more often in the keyboard-scanning loop +; [Hmm, it's already checking the mouse more often, but +; I don't think that change was ever installed.] +; Feep with a low pitch on powering up, and a higher pitch +; after successfully sending a character to the Lisp machine. +; Time out waiting for the DONE flag. It can get turned off by +; random noise on the clock line if the Lisp machine is powered +; off or disconnected; we don't want that to break the keyboard. + +(defun complement (x) + (logxor 377 x)) + +;;; Hardware documentation + +;To read from keyboard, P1<4:1> gets column number, then P1<0> gets 0, +;then read back keys from P2, then P1<1> gets 1 again. + +;P1<7> = beeper (pin 5 on the connector) +;P1<6> = write register select bit 0 (pin 3 on the connector) +;P1<5> = write register select bit 1 (pin 1 on the connector) +;T1 = pin 2 on the connector (not used any more) +; +;Reading the data bus returns +;DONE in bit 0 and the mouse in bits 1-7. DONE is 1 if the shift +;register has been sent off to the host computer. +; +;Writing the data bus writes into +;one of the three bytes of the shift register; write the first byte +;last with a start bit in its low-order bits. P1<6:5> selects which byte. + +;The following are the bit numbers of the keys which are specially +;known about for shifting purposes: +; mode lock 3 +; caps lock 125 +; alt lock 15 +; repeat 115 +; top 104 / 155 +; greek 44 / 35 +; shift 24 / 25 +; hyper 145 / 175 +; super 5 / 65 +; meta 45 / 165 +; control 20 / 26 + +; For booting, we know that rubout is 23 and return is 136 + +;Protocol documentation is at the end of this file + +;;; Locations in data memory +(setq bitmap 60) ;60-77 Bit map. 0 if key up, 1 if key down. +(setq bootflag 57) ;Normally 0, non-zero to suppress key-up codes + ; and mouse codes while in boot sequence +(setq mouse 56) ;Last known state of the mouse input lines +(setq init 55) ;Non-zero if have sent a character + +;;; Note that we always return the beeper output to 0 when not using it. +;;; This is for convenience in the keyboard-scanning loop, since it's +;;; on the same port. + +;;; Program +(putprop 'ukbd '( + (= 0) + (jmp beg) + (= 1) ;Table of magic constants for keyboard scanner + 001 003 005 007 011 013 015 017 + 021 023 025 027 031 033 035 037 + + (= 100) ;Why location 100? +beg (mov a (/# 377)) + (outl p1 a) ;Mainly turn off data out + (outl p2 a) ;Enable input + (mov r0 (/# 40)) ;Clear all memory above location 40, + (mov r1 (/# 40)) ; especially the bitmap + (clr a) +clear-bitmap-loop + (mov @r0 a) + (inc r0) + (djnz r1 clear-bitmap-loop) + (mov r0 (/# 8)) ;Wait 3 seconds after powering up +power-up-delay-1 + (mov r1 (/# 0)) ;Delay 400 ms +power-up-delay-2 + (mov r2 (/# 0)) ;Delay 1.5 ms +power-up-delay-3 + (djnz r2 power-up-delay-3) + (djnz r1 power-up-delay-2) + (djnz r0 power-up-delay-1) + (mov r0 (/# 24.)) ;Give medium pitched feep + (mov r1 (/# 100.)) ;for 1/3 second + (call feep) +its-all-up ;Send all-up code to initialize the + (call send-all-up-code) ; shift register in the Lisp machine + (mov r0 (/# init)) ;Initialized yet? + (mov a @r0) + (jnz scan-keyboard) ;Yes + (call await-done) ;Wait for response from Lisp machine + (ins a bus) ;A<0>=DONE + (rrc a) ;C=DONE + (jnc scan-keyboard) ;await-done timed out + (mov r0 (/# init)) ;Success, set initialized flag + (mov @r0 (/# 1)) + (mov r0 (/# 8)) ;Then give high-pitched feep + (mov r1 (/# 250.)) ;For 1/4 second + (call feep) ;and drop into scan-keyboard + +;Scanning Loop. +;R2 is bitmap index in bytes, plus 1 +;R1 points to previous mouse status +;R0 is address of bitmap byte that goes with R2 + +scan-keyboard + (mov r2 (/# 20)) ;Loop counter and index + (mov r1 (/# mouse)) ;Addressibility + (mov r0 (/# (+ bitmap 17))) ;Address of bitmap byte +scan-loop + (ins a bus) ;Get mouse status + (anl a (/# (complement 1))) ;Clear done bit + (xrl a @r1) ;Has mouse status changed? + (jnz scan-mouse) ;Yes, punt keyboard and go send mouse char + (mov a r2) + (movp a @a) ;A<4:1>  R2-1, A<0>  1 + (outl p1 a) ;Select row and disable decoder + (anl p1 (/# (complement 1))) ;Strobe the decoder (why?) + (in a p2) ;Get row of keys + (xrl a @r0) ;A  changed bits + (jnz scan-found) ;Jump if key state changed + (dec r0) + (djnz r2 scan-loop) + (jmp scan-keyboard) ;Nothing happening, idle. + +scan-mouse + (xrl a @r1) ;Restore from xor above + (mov @r1 a) ;Update previous-mouse-state + (xrl a (/# 340)) ;Compensate for hardware bug--buttons complemented + (mov r2 a) ;Arg for send + (mov r3 (/# 0)) + (mov r4 (/# 176_1)) ;Source ID 6 (mouse) + (mov r0 (/# bootflag)) ;Don't send if in boot sequence + (mov a @r0) + (jnz scan-keyboard) + (call send) + (jmp scan-keyboard) + +;R0 address of bit map entry +;R2 bit number +;R3 changed bits +;R4 bit mask +scan-found + (mov r3 a) + (mov r4 (/# 1)) + (mov a r2) ;Bit number is byte number times 8 + (dec a) + (rl a) + (rl a) + (rl a) + (mov r2 a) +scan-bits-loop + (mov a r4) + (anl a r3) + (jnz scan-found-key) + (inc r2) + (mov a r4) ;Shift left one bit, A  0 when done + (add a r4) + (mov r4 a) + (jnz scan-bits-loop) + (jmp scan-keyboard) ;wtf? should have found something + +scan-found-key + (mov a r2) ;Shift r2 left 1 + (add a r2) + (mov r2 a) + (mov a r4) ;Bit mask + (xrl a @r0) ;Change bitmap bit + (mov @r0 a) ;Put back in bitmap + (anl a r4) ;0 if key now up, non-0 if key now down + (mov r3 (/# 0)) ;Assume key down + (jnz scan-found-key-down) + (mov r3 (/# 2)) ;Key up, middle byte is 1 + ;; If booting, don't send key-up codes + (mov r1 (/# bootflag)) + (mov a @r1) + (jnz scan-keyboard) + ;; If this is a shifting key, don't send all-keys-up, send this-key-up. + ;; This is so that with paired shifting keys we know which it is. + (mov a r0) + (add a (/# (- 200 bitmap))) ;Point to mask of non-shifting keys + (movp3 a @a) + (anl a r4) ;A gets bit from table (0 => shifting) + (jz scan-found-key-down) ;Shifting => don't send all-keys-up + ;; Look through the bit map and see if all non-shifting keys are now + ;; up. If so, send an all-keys-up instead. + (mov r0 (/# bitmap)) + (mov r1 (/# 200)) ;P3 table at 1600 + (mov r4 (/# 20)) +check-for-all-up + (mov a r1) + (movp3 a @a) + (anl a @r0) + (jnz scan-found-key-down) + (inc r0) + (inc r1) + (djnz r4 check-for-all-up) + (call await-done) + (jmp its-all-up) + +scan-found-key-down + (mov r4 (/# 171_1)) ;Source ID 1 (new keyboard) + (call send) ;Transmit character + (call check-boot) ;See if request to boot machine + (jmp scan-keyboard) + +;Subroutine to transmit like old-type Knight keyboard (using new shift reg hardware) +;Send a 24-bit character from R2, R3, R4 +;But note that it's all shifted left 1 bit. R2<0> must be zero, +;it's the start-bit. +send (call await-done) +send1 (orl p1 (/# 140)) ;P1<5:6>=3 + (mov a r4) + (outl bus a) + (anl p1 (/# 277)) ;P1<5:6>=2 + (mov a r3) + (outl bus a) + (anl p1 (/# 337)) ;P1<5:6>=1 + (orl p1 (/# 100)) + (mov a r2) + (outl bus a) + (ret) + + + (= 400) +;Send all-up key-code. NOTE that this does not wait for DONE. +;This works by checking through the bitmap looking for shift keys +;that are down, and OR'ing in the bits. +send-all-up-code + (clr a) ;Cannot clear registers directly + (mov r2 a) ;Start with no bits set + (mov r3 a) + (mov r5 a) ;R5 address in P3 + (mov r0 (/# bitmap)) ;R0 address in bitmap +cauc-0 (mov r4 (/# 1)) ;R4 bit mask +cauc-1 (mov a r5) + (movp3 a @a) ;Get table entry + (jb7 cauc-9) ;Jump if this key not a shifter + (mov r6 a) ;Save bit number + (mov a r4) ;Check bit in bit map + (anl a @r0) + (jz cauc-9) ;Key not pressed + (mov a r6) ;See if bit number 7 or more + (add a (/# -7)) + (jb7 cauc-4) ;Jump if less than 7 + (mov r6 a) ;Save bitnumber within middle byte + (call cauc-sh) + (orl a r3) + (mov r3 a) + (jmp cauc-9) + +cauc-4 (inc r6) + (call cauc-sh) + (orl a r2) + (mov r2 a) +;Done with this key, step to next +cauc-9 (inc r5) ;Advance P3 address + (mov a r4) ;Shift bit mask left 1 + (add a r4) + (mov r4 a) + (jnz cauc-1) ;Jump if more bits this word + (inc r0) ;Advance bitmap address + (mov a r0) ;See if done + (add a (/# (- (+ bitmap 20)))) + (jnz cauc-0) ;Jump if more words in bitmap + (mov r4 (/# 363)) ;Source ID 1, bit 15 on + (jmp send1) ;Send it and return + +;Produce in A a bit shifted left by amount in R6 +cauc-sh (inc r6) ;Compensate for DJNZ + (mov a (/# 200)) +cauc-sh-1 + (rl a) + (djnz r6 cauc-sh-1) + (ret) + +;Is request to boot machine if both controls and both metas are held +;down, along with rubout or return. We have just sent the key-down codes +;for all of those keys. We now send a boot character, then set a flag preventing +;sending of up-codes until the next down-code. This gives the machine time +;to load microcode and read the character to see whether +;it is a warm or cold boot, before sending any other characters, such as up-codes. +; meta 45 / 165 +; control 20 / 26 +; rubout 23 +; return 136 +; The locking keys are in bytes 1, 3, and 12, conveniently out of the way +;A boot code: +; 15-10 1 +; 9-6 0 +; 5-0 46 (octal) if cold, 62 (octal) if warm. + +check-boot + (mov r1 (/# bootflag)) ;Establish addressibility for later + (mov r0 (/# 64)) ;Check one meta key + (mov a @r0) + (xrl a (/# 1_5)) + (jnz not-boot) + (mov r0 (/# 76)) ;Check other meta key + (mov a @r0) + (xrl a (/# 1_5)) + (jnz not-boot) + (mov r0 (/# 62)) ;Check byte containing controls and rubout + (mov a @r0) + (xrl a (/# (+ 1_0 1_6 1_3))) + (jz cold-boot) ;Both controls and rubout => cold-boot + (xrl a (/# 1_3)) + (jnz not-boot) + (mov r0 (/# 73)) ;Check for return + (mov a @r0) + (xrl a (/# 1_6)) + (jnz not-boot) +warm-boot + (mov r2 (/# 62_1)) + (jmp send-boot) + +cold-boot + (mov r2 (/# 46_1)) +send-boot + (mov r3 (/# 174_1)) ;1's in bits 14-10 + (mov r4 (/# 363)) ;Source ID 1 (new keyboard), 1 in bit 15 + (mov @r1 (/# 377)) ;Set bootflag + (jmp send) ;Transmit character and return + +not-boot + (mov @r1 (/# 0)) ;Clear bootflag + (ret) + +;Wait for PC board to say that it is done shifting out previous character +;This will time out after 1 second +;Bashes R0, R1, A +await-done + (mov r0 (/# 0)) +await-done-1 + (mov r1 (/# 0)) +await-done-2 + (ins a bus) ;A<0>=DONE + (rrc a) ;C=DONE + (jnc await-done-3) ;Not DONE yet + (ret) + +await-done-3 + (djnz r1 await-done-2) + (djnz r0 await-done-1) + (ret) ;timeout + +;Feep routine. R0 is the half-period in units of 100 microseconds. +;R1 is the number of cycles to do. +feep (orl p1 (/# 200)) ;Cycle feeper + (call feep-delay) + (anl p1 (/# (complement 200))) + (call feep-delay) + (djnz r1 feep) + (ret) + +feep-delay + (mov a r0) + (mov r2 a) +feep-1 (mov r3 (/# 15.)) ;djnz takes 6+ microseconds +feep-2 (djnz r3 feep-2) + (djnz r2 feep-1) + (ret) + +;In P3 (1400-1577) we have a table, indexed by key number, of shifting +;keys. The byte is 200 for ordinary keys, or the bit number in the +;all-keys-up message for locking and shifting keys. + (= 1400) + 200 ;0 + 200 + 200 + 9. ;3 mode lock + 200 + 6. ;5 super + 200 + 200 + + 200 ;10 + 200 + 200 + 200 + 200 + 8. ;15 alt lock + 200 + 200 + + 4. ;20 control + 200 + 200 + 200 + 0. ;24 shift + 0. ;25 shift + 4. ;26 control + 200 + + 200 ;30 + 200 + 200 + 200 + 200 + 1. ;35 greek + 200 + 200 + + 200 ;40 + 200 + 200 + 200 + 1. ;44 greek + 5. ;45 meta + 200 + 200 + + 200 ;50 + 200 + 200 + 200 + 200 + 200 + 200 + 200 + + 200 ;60 + 200 + 200 + 200 + 200 + 6. ;65 super + 200 + 200 + + 200 ;70 + 200 + 200 + 200 + 200 + 200 + 200 + 200 + + 200 ;100 + 200 + 200 + 200 + 2. ;104 top + 200 + 200 + 200 + + 200 ;110 + 200 + 200 + 200 + 200 + 10. ;115 repeat + 200 + 200 + + 200 ;120 + 200 + 200 + 200 + 200 + 3. ;125 caps lock + 200 + 200 + + 200 ;130 + 200 + 200 + 200 + 200 + 200 + 200 + 200 + + 200 ;140 + 200 + 200 + 200 + 200 + 7. ;145 hyper + 200 + 200 + + 200 ;150 + 200 + 200 + 200 + 200 + 2. ;155 top + 200 + 200 + + 200 ;160 + 200 + 200 + 200 + 200 + 5. ;165 meta + 200 + 200 + + 200 ;170 + 200 + 200 + 200 + 200 + 7. ;175 hyper + 200 + 200 + + (= 1600) +;Locations 1600-1617 contain a mask which has 1's for bit-map positions +;which contain non-shifting keys. + 327 ;3 and 5 + 337 ;15 + 216 ;20, 24, 25, 26 + 337 ;35 + 317 ;44, 45 + 377 + 337 ;65 + 377 ;70 + 357 ;104 + 337 ;115 + 337 ;125 + 377 + 337 ;145 + 337 ;155 + 337 ;165 + 337 ;175 + + ) +'code) + +;These don't work any more: +;;Look at kbd and print out any characters that come in +;(defun test () +; (let ((tv-more-processing-global-enable nil)) +; (do ((ch)) (nil) +; (process-allow-schedule) +; (and (setq ch (si:kbd-tyi-raw-no-hang)) +; (print (ldb 0027 ch)))))) +; +;;This version isn't stoppable, because it just gets it right out of the hardware +;;Prevents you from getting screwed by call-processing and the like. +;(defun supertest () +; (let ((tv-more-processing-global-enable nil)) +; (do ((ch)) (nil) +; (or si:kbd-buffer (si:kbd-get-hardware-char-if-any)) +; (and si:kbd-buffer +; (progn (setq ch si:kbd-buffer si:kbd-buffer nil) +; (print (ldb 0027 ch))))))) + +;;; Protocol documentation + +; Protocol for new keyboards -- 9/27/79 +; +; Present hardware character format conventions: +; +; A character is 24 bits, sent low-order bit first. There is also +; a "start bit" or "request signal", which is low. Bits appear +; on the cable in true-high form. The cable is high when idle. +; The clock is high when idle, and the falling edge is the clock +; in the central machine. The leading edge (check this) is the +; clock in the keyboard. +; +; The old (Knight) keyboards send 1's for the high 9 bits. +; +; Bit 16 is normally 1, 0 for the "remote mouse" which the IOB +; claims to support. Whether the IOB +; hardware actually looks at this bit is under program control. +; +; The IOB boots the lisp machine if a character is received with +; bits 10-13 = 1, bits 6-9 = 0, and bit 16 = 1 (bit 16 may or may +; not be looked at depending on remote mouse enable.) The low 6 +; bits control whether it is a warm or cold boot. +; +; Here is the new standard character format: +; 15-0 Information +; 18-16 Source ID +; 23-19 Reserved, must be 1's. +; +; The following source ID's are defined: +; 111 Old keyboard, information is as follows: +; 5-0 keycode +; 7-6 shift +; 9-8 top +; 11-10 control +; 13-12 meta +; 14 shift-lock +; 15 unused +; 110 IOB's "remote mouse", this also uses up codes 000, 010, 100 +; Low bits are the input lines from the mouse +; 101 Reserved. +; 001 New keyboard, information as follows: +; An up-down code: +; 15 0 (indicates up-down code) +; 14 0 (reserved for expansion of codes) +; 13 0 (so it doesn't look like a boot) +; 12-9 0 (reserved for expansion) +; 8 1=key up, 0=key down +; 7 0 (reserved for expansion of keys) +; 6-0 keycode (not same codes as old keyboards) +; +; An all-keys-up: (This is sent when a key-up code would be sent but +; now no keys other than shifting and/or locking keys are +; down. This ensures that the status of the shifting keys, +; especially the locking ones, does not get out of phase. +; A 1 is sent for each special key that is currently down.) +; 15 1 (indicates not an up-down code) +; 14 0 (reserved for expansion of codes) +; 13 0 (so it doesn't look like a boot) +; 12 0 (reserved for expansion of keys) +; 11 0 (reserved for expansion of keys) +; 10 Repeat +; 9 Mode lock +; 8 Alt lock +; 7 Hyper (either one) +; 6 Super (either one) +; 5 Meta (either one) +; 4 Control (either one) +; 3 Caps lock +; 2 Top (either one) +; 1 Greek (either one) +; 0 Shift (either one) +; +; A boot code: +; 15-10 1 +; 9-6 0 +; 5-0 46 (octal) if cold, 62 (octal) if warm. +; +; All key-encoding, including hacking of shifts, will be done +; in software in the central machine, not in the keyboard. Note +; that both pressing and releasing a key send a code, therefore +; the central machine knows the status of all keys. If the machine +; somehow gets out of phase, the next time the user presses and releases +; a key an all-keys-up message will be sent, getting it back into phase. +; +; Note that after sending a boot the keyboard must not +; send any more characters (such as up-codes) until +; another key is depressed, or the keyboard buffer +; in the IOB would forget the type of boot. +; +; 011 Mouse attached via new keyboard. Information as follows: +; [This won't be implemented soon; it's not what this program does.] +; 5-0 Delta-X, 2's complement +; 11-6 Delta-Y, 2's complement +; 12 0. Prevents accidental booting. +; 15-13 Current status of buttons. +; Every time the mouse moves or the button status changes, +; a mouse character is sent, except that there is a minimum +; delay between mouse characters of probably 1/30th or 1/40th +; second. Between characters the keyboard tracks motion of +; the mouse. These mouse characters will not be processed +; by hardware in the IOB. They will probably be processed +; by the CADR microcode interrupt handler. diff --git a/src/lmio1/ukbd.prom b/src/lmio1/ukbd.prom new file mode 100644 index 00000000..97802d7d --- /dev/null +++ b/src/lmio1/ukbd.prom @@ -0,0 +1,917 @@ +PROM LOCATION UKBD SUM-CHECK NIL + +0 4 +1 100 +2 0 +3 0 +4 0 +5 0 +6 0 +7 0 +10 0 +11 0 +12 0 +13 0 +14 0 +15 0 +16 0 +17 0 +20 0 +21 0 +22 0 +23 0 +24 0 +25 0 +26 0 +27 0 +30 0 +31 0 +32 0 +33 0 +34 0 +35 0 +36 0 +37 0 +40 0 +41 0 +42 0 +43 0 +44 0 +45 0 +46 0 +47 0 +50 0 +51 0 +52 0 +53 0 +54 0 +55 0 +56 0 +57 0 +60 0 +61 0 +62 0 +63 0 +64 0 +65 0 +66 0 +67 0 +70 0 +71 0 +72 0 +73 0 +74 0 +75 0 +76 0 +77 0 +100 43 +101 377 +102 71 +103 72 +104 270 +105 60 +106 271 +107 20 +110 47 +111 240 +112 30 +113 351 +114 111 +115 272 +116 20 +117 43 +120 57 +121 152 +122 250 +123 372 +124 7 +125 211 +126 37 +127 22 +130 133 +131 231 +132 375 +133 62 +134 137 +135 231 +136 373 +137 122 +140 143 +141 231 +142 367 +143 162 +144 147 +145 231 +146 357 +147 231 +150 376 +151 12 +152 320 +153 226 +154 161 +155 352 +156 117 +157 4 +160 115 +161 253 +162 274 +163 1 +164 372 +165 7 +166 347 +167 347 +170 347 +171 252 +172 374 +173 133 +174 226 +175 206 +176 32 +177 374 +200 154 +201 254 +202 226 +203 172 +204 4 +205 115 +206 374 +207 320 +210 240 +211 134 +212 273 +213 0 +214 226 +215 240 +216 33 +217 270 +220 60 +221 271 +222 200 +223 274 +224 20 +225 371 +226 343 +227 120 +230 226 +231 240 +232 30 +233 31 +234 354 +235 225 +236 64 +237 0 +240 274 +241 371 +242 24 +243 250 +244 64 +245 67 +246 4 +247 115 +250 231 +251 277 +252 372 +253 24 +254 270 +255 373 +256 24 +257 270 +260 374 +261 24 +262 270 +263 106 +264 263 +265 211 +266 100 +267 203 +270 270 +271 10 +272 22 +273 306 +274 126 +275 274 +276 231 +277 277 +300 147 +301 106 +302 301 +303 350 +304 272 +305 203 +306 126 +307 306 +310 211 +311 100 +312 147 +313 106 +314 313 +315 350 +316 272 +317 203 +320 0 +321 0 +322 0 +323 0 +324 0 +325 0 +326 0 +327 0 +330 0 +331 0 +332 0 +333 0 +334 0 +335 0 +336 0 +337 0 +340 0 +341 0 +342 0 +343 0 +344 0 +345 0 +346 0 +347 0 +350 0 +351 0 +352 0 +353 0 +354 0 +355 0 +356 0 +357 0 +360 0 +361 0 +362 0 +363 0 +364 0 +365 0 +366 0 +367 0 +370 0 +371 0 +372 0 +373 0 +374 0 +375 0 +376 0 +377 0 +400 272 +401 0 +402 273 +403 200 +404 275 +405 0 +406 270 +407 60 +410 274 +411 1 +412 375 +413 343 +414 362 +415 43 +416 256 +417 374 +420 120 +421 306 +422 43 +423 376 +424 3 +425 370 +426 362 +427 37 +430 256 +431 64 +432 60 +433 113 +434 253 +435 44 +436 43 +437 64 +440 60 +441 112 +442 252 +443 35 +444 374 +445 154 +446 254 +447 226 +450 12 +451 30 +452 370 +453 3 +454 300 +455 226 +456 10 +457 203 +460 36 +461 43 +462 200 +463 347 +464 356 +465 63 +466 203 +467 270 +470 64 +471 360 +472 323 +473 40 +474 226 +475 157 +476 270 +477 76 +500 360 +501 323 +502 40 +503 226 +504 157 +505 270 +506 62 +507 360 +510 323 +511 111 +512 306 +513 133 +514 323 +515 10 +516 226 +517 157 +520 270 +521 73 +522 360 +523 323 +524 100 +525 226 +526 157 +527 272 +530 62 +531 44 +532 135 +533 272 +534 46 +535 273 +536 374 +537 274 +540 371 +541 24 +542 250 +543 274 +544 6 +545 273 +546 0 +547 272 +550 0 +551 352 +552 151 +553 353 +554 147 +555 354 +556 145 +557 203 +560 0 +561 0 +562 0 +563 0 +564 0 +565 0 +566 0 +567 0 +570 0 +571 0 +572 0 +573 0 +574 0 +575 0 +576 0 +577 0 +600 0 +601 0 +602 0 +603 0 +604 0 +605 0 +606 0 +607 0 +610 0 +611 0 +612 0 +613 0 +614 0 +615 0 +616 0 +617 0 +620 0 +621 0 +622 0 +623 0 +624 0 +625 0 +626 0 +627 0 +630 0 +631 0 +632 0 +633 0 +634 0 +635 0 +636 0 +637 0 +640 0 +641 0 +642 0 +643 0 +644 0 +645 0 +646 0 +647 0 +650 0 +651 0 +652 0 +653 0 +654 0 +655 0 +656 0 +657 0 +660 0 +661 0 +662 0 +663 0 +664 0 +665 0 +666 0 +667 0 +670 0 +671 0 +672 0 +673 0 +674 0 +675 0 +676 0 +677 0 +700 0 +701 0 +702 0 +703 0 +704 0 +705 0 +706 0 +707 0 +710 0 +711 0 +712 0 +713 0 +714 0 +715 0 +716 0 +717 0 +720 0 +721 0 +722 0 +723 0 +724 0 +725 0 +726 0 +727 0 +730 0 +731 0 +732 0 +733 0 +734 0 +735 0 +736 0 +737 0 +740 0 +741 0 +742 0 +743 0 +744 0 +745 0 +746 0 +747 0 +750 0 +751 0 +752 0 +753 0 +754 0 +755 0 +756 0 +757 0 +760 0 +761 0 +762 0 +763 0 +764 0 +765 0 +766 0 +767 0 +770 0 +771 0 +772 0 +773 0 +774 0 +775 0 +776 0 +777 0 +1000 0 +1001 0 +1002 0 +1003 0 +1004 0 +1005 0 +1006 0 +1007 0 +1010 0 +1011 0 +1012 0 +1013 0 +1014 0 +1015 0 +1016 0 +1017 0 +1020 0 +1021 0 +1022 0 +1023 0 +1024 0 +1025 0 +1026 0 +1027 0 +1030 0 +1031 0 +1032 0 +1033 0 +1034 0 +1035 0 +1036 0 +1037 0 +1040 0 +1041 0 +1042 0 +1043 0 +1044 0 +1045 0 +1046 0 +1047 0 +1050 0 +1051 0 +1052 0 +1053 0 +1054 0 +1055 0 +1056 0 +1057 0 +1060 0 +1061 0 +1062 0 +1063 0 +1064 0 +1065 0 +1066 0 +1067 0 +1070 0 +1071 0 +1072 0 +1073 0 +1074 0 +1075 0 +1076 0 +1077 0 +1100 0 +1101 0 +1102 0 +1103 0 +1104 0 +1105 0 +1106 0 +1107 0 +1110 0 +1111 0 +1112 0 +1113 0 +1114 0 +1115 0 +1116 0 +1117 0 +1120 0 +1121 0 +1122 0 +1123 0 +1124 0 +1125 0 +1126 0 +1127 0 +1130 0 +1131 0 +1132 0 +1133 0 +1134 0 +1135 0 +1136 0 +1137 0 +1140 0 +1141 0 +1142 0 +1143 0 +1144 0 +1145 0 +1146 0 +1147 0 +1150 0 +1151 0 +1152 0 +1153 0 +1154 0 +1155 0 +1156 0 +1157 0 +1160 0 +1161 0 +1162 0 +1163 0 +1164 0 +1165 0 +1166 0 +1167 0 +1170 0 +1171 0 +1172 0 +1173 0 +1174 0 +1175 0 +1176 0 +1177 0 +1200 0 +1201 0 +1202 0 +1203 0 +1204 0 +1205 0 +1206 0 +1207 0 +1210 0 +1211 0 +1212 0 +1213 0 +1214 0 +1215 0 +1216 0 +1217 0 +1220 0 +1221 0 +1222 0 +1223 0 +1224 0 +1225 0 +1226 0 +1227 0 +1230 0 +1231 0 +1232 0 +1233 0 +1234 0 +1235 0 +1236 0 +1237 0 +1240 0 +1241 0 +1242 0 +1243 0 +1244 0 +1245 0 +1246 0 +1247 0 +1250 0 +1251 0 +1252 0 +1253 0 +1254 0 +1255 0 +1256 0 +1257 0 +1260 0 +1261 0 +1262 0 +1263 0 +1264 0 +1265 0 +1266 0 +1267 0 +1270 0 +1271 0 +1272 0 +1273 0 +1274 0 +1275 0 +1276 0 +1277 0 +1300 0 +1301 0 +1302 0 +1303 0 +1304 0 +1305 0 +1306 0 +1307 0 +1310 0 +1311 0 +1312 0 +1313 0 +1314 0 +1315 0 +1316 0 +1317 0 +1320 0 +1321 0 +1322 0 +1323 0 +1324 0 +1325 0 +1326 0 +1327 0 +1330 0 +1331 0 +1332 0 +1333 0 +1334 0 +1335 0 +1336 0 +1337 0 +1340 0 +1341 0 +1342 0 +1343 0 +1344 0 +1345 0 +1346 0 +1347 0 +1350 0 +1351 0 +1352 0 +1353 0 +1354 0 +1355 0 +1356 0 +1357 0 +1360 0 +1361 0 +1362 0 +1363 0 +1364 0 +1365 0 +1366 0 +1367 0 +1370 0 +1371 0 +1372 0 +1373 0 +1374 0 +1375 0 +1376 0 +1377 0 +1400 200 +1401 200 +1402 200 +1403 11 +1404 200 +1405 200 +1406 200 +1407 200 +1410 200 +1411 200 +1412 200 +1413 200 +1414 200 +1415 10 +1416 200 +1417 200 +1420 4 +1421 200 +1422 200 +1423 200 +1424 0 +1425 0 +1426 4 +1427 200 +1430 200 +1431 200 +1432 200 +1433 200 +1434 200 +1435 1 +1436 200 +1437 200 +1440 200 +1441 200 +1442 200 +1443 200 +1444 1 +1445 5 +1446 200 +1447 200 +1450 200 +1451 200 +1452 200 +1453 200 +1454 200 +1455 200 +1456 200 +1457 200 +1460 200 +1461 200 +1462 200 +1463 200 +1464 200 +1465 6 +1466 200 +1467 200 +1470 200 +1471 200 +1472 200 +1473 200 +1474 200 +1475 200 +1476 200 +1477 200 +1500 200 +1501 200 +1502 200 +1503 200 +1504 2 +1505 200 +1506 200 +1507 200 +1510 200 +1511 200 +1512 200 +1513 200 +1514 200 +1515 12 +1516 200 +1517 200 +1520 200 +1521 200 +1522 200 +1523 200 +1524 200 +1525 3 +1526 200 +1527 200 +1530 200 +1531 200 +1532 200 +1533 200 +1534 200 +1535 200 +1536 200 +1537 200 +1540 200 +1541 200 +1542 200 +1543 200 +1544 200 +1545 7 +1546 200 +1547 200 +1550 200 +1551 200 +1552 200 +1553 200 +1554 200 +1555 2 +1556 200 +1557 200 +1560 200 +1561 200 +1562 200 +1563 200 +1564 200 +1565 5 +1566 200 +1567 200 +1570 200 +1571 200 +1572 200 +1573 200 +1574 200 +1575 7 +1576 200 +1577 200 +1600 327 +1601 337 +1602 216 +1603 337 +1604 317 +1605 377 +1606 337 +1607 377 +1610 357 +1611 337 +1612 337 +1613 377 +1614 337 +1615 337 +1616 337 +1617 337 +1620 0 + +END