Space-cadet keyboard

User avatar
webwit
Wild Duck

25 Oct 2011, 14:59


User avatar
Half-Saint

25 Oct 2011, 15:11

The keycaps are massive!

User avatar
HoboBob

25 Oct 2011, 15:13

Really nice! I like the blue.

And at first I read 'Geek' and not 'Greek' in the 5th picture.

'TOP GEEK' heck yeah! wait... bawwww

User avatar
7bit

25 Oct 2011, 15:15

webwit wrote:The legendary Space Cadet keyboard. No case, guts only, but new and unused.
Congratulations!

This is the top of your collection.

You will never ever find something more valuable!

Ever!

User avatar
webwit
Wild Duck

25 Oct 2011, 15:17

New with case. Or maybe the Knight Keyboard.

User avatar
7bit

25 Oct 2011, 15:23

webwit wrote:New with case. Or maybe the Knight Keyboard.
OK, yes.

I did not think of that.

So, carry on!
:ugeek: ^ :ugeek:

User avatar
Ascaii
The Beard

25 Oct 2011, 15:28

hmm it looks like a cherry stem would fit inside the space cadet stem. Make the caps mx compatible and post pics^^

User avatar
webwit
Wild Duck

25 Oct 2011, 15:36

I only got it to harvest the keycaps for my POKER!

User avatar
Ascaii
The Beard

25 Oct 2011, 15:53

webwit wrote:I only got it to harvest the keycaps for my POKER!
exactly!

User avatar
7bit

25 Oct 2011, 15:56

webwit wrote:I only got it to harvest the keycaps for my POKER!
:o I should get some people together to rescue the Holy Grail!

User avatar
webwit
Wild Duck

25 Oct 2011, 15:59

What can possibly stop me?

Image

Image

User avatar
7bit

25 Oct 2011, 16:07

webwit wrote:What can possibly stop me?

[...]
I've sent out these to come to the rescue:
Image

to be serious:
Is there any sign of when it had been produced?

User avatar
webwit
Wild Duck

25 Oct 2011, 16:21

No dates anywhere on the keyboard, I think.

User avatar
lal

25 Oct 2011, 18:32

How do the switches feel??? And why does the top left naked switch seem to have brunette hair?

User avatar
webwit
Wild Duck

25 Oct 2011, 18:37

All the stabilizers have a fuzzy little bit.
The switches are linear, they are rather uneventful and feel similar to these Micro Switch switches:

Image

Image

xbb

25 Oct 2011, 19:20

wow :shock:

User avatar
sixty
Gasbag Guru

26 Oct 2011, 15:35

Congrats. About time you managed to get one of these. Knight next!

PS: You should totally find a cable that fits the plug on the back and safely convert this with an Aikon. The matrix looks easy enough to follow on the PCB pics!

User avatar
webwit
Wild Duck

27 Oct 2011, 01:15

I wonder how many layers/characters the Aikon supports. From the Jargon File:
Space-cadet keyboard

A now-legendary device used on MIT LISP machines, which inspired several still-current jargon terms and influenced the design of EMACS. It was equipped with no fewer than seven shift keys: four keys for bucky bits (`control', `meta', `hyper', and `super') and three like regular shift keys, called `shift', `top', and `front'. Many keys had three symbols on them: a letter and a symbol on the top, and a Greek letter on the front. For example, the `L' key had an `L' and a two-way arrow on the top, and the Greek letter lambda on the front. By pressing this key with the right hand while playing an appropriate `chord' with the left hand on the shift keys, you could get the following results:

L: lowercase l
shift-L: uppercase L
front-L: lowercase lambda
front-shift-L: uppercase lambda
top-L: two-way arrow (front and shift are ignored)

And of course each of these might also be typed with any combination of the control, meta, hyper, and super keys. On this keyboard, you could type over 8000 different characters! This allowed the user to type very complicated mathematical text, and also to have thousands of single-character commands at his disposal. Many hackers were actually willing to memorize the command meanings of that many characters if it reduced typing time (this attitude obviously shaped the interface of EMACS). Other hackers, however, thought having that many bucky bits was overkill, and objected that such a keyboard can require three or four hands to operate.

xahlee

27 Oct 2011, 23:05

webwit, may i have permission to use your photos on my website? I write about keyboards, in particular related to emacs.

credit will be given of course, with links to here or your website. Thanks.

Xah

User avatar
webwit
Wild Duck

27 Oct 2011, 23:19

xahlee wrote:webwit, may i have permission to use your photos on my website? I write about keyboards, in particular related to emacs.
No problem, all my keyboard photos are in the public domain.
sixty wrote:PS: You should totally find a cable that fits the plug on the back and safely convert this with an Aikon. The matrix looks easy enough to follow on the PCB pics!
I might be getting the source code for the Intel 8748 controller (which is actually missing, but I don't need it) from the previous owner, depending on the readability this could reveal the matrix as well.

User avatar
webwit
Wild Duck

28 Oct 2011, 02:31

The assembler for the 8748 was written in Lisp, of course. Seems well documented.
Spoiler:

Code: Select all

;;; -*- Mode: Lisp; Base: 8; Package: User -*-

(defun complement (x)
  (logxor 377 x))

(setq bitmap 60)	;60-77 Bit map.  0 if key up, 1 if key down.
;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> = pin 5 on the connector
;P1<6> = pin 3 on the connector	(used for data)
;P1<5> = pin 1 on the connector
;T1    = pin 2 on the connector (used for clock)

;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

(putprop 'ukbd '(
	(= 0)
	(jmp beg)

	(= 100)
beg	(mov a (/# 377))
	(outl p1 a)			;Mainly turn off data out
	(outl p2 a)			;Enable input
	(mov r0 (/# bitmap))		;Clear the bitmap
	(mov r1 (/# 20))
	(clr a)
clear-bitmap-loop
	(mov @r0 a)
	(inc r0)
	(djnz r1 clear-bitmap-loop)
;Scanning Loop.
;R2 is bitmap index in bytes, plus 1
;R0,R1 temporary as usual

scan-keyboard
	(mov r2 (/# 20))
scan-loop
	(mov a (/# (1- bitmap)))
	(add a r2)			;Address of bitmap byte
	(mov r0 a)
	(mov a r2)
	(dec a)
	(orl p1 (/# 37))		;P1<4:1>  R2-1, and disable decoder
	(jb0 scan-loop-p1out-0)
	(anl p1 (/# (complement 2_0)))
scan-loop-p1out-0
	(jb1 scan-loop-p1out-1)
	(anl p1 (/# (complement 2_1)))
scan-loop-p1out-1
	(jb2 scan-loop-p1out-2)
	(anl p1 (/# (complement 2_2)))
scan-loop-p1out-2
	(jb3 scan-loop-p1out-3)
	(anl p1 (/# (complement 2_3)))
scan-loop-p1out-3
	(anl p1 (/# (complement 1)))	;Strobe the decoder
	(in a p2)			;Get row of keys
	(xrl a @r0)			;A  changed bits
	(jnz scan-found)		;Jump if key state changed
	(djnz r2 scan-loop)
	;
	(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 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)
	(inc r3)			;Key up, middle byte is 1
	;; 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 compute-all-up-code)
scan-found-key-down
	(mov r4 (/# 371))		;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
;Send a 24-bit character from R2, R3, R4
;T1    = pin 2 on the connector	(used for clock)
;P1<6> = pin 3 on the connector	(used for data)
;Data output is normally high, we make it low to get the attention of the keyboard
; multiplexor.
;Clock input is normally high, its low-going transition is when we send the next bit.
;A 1 bit is a high.
;R0 has a count

;Timing:	(1 cycle = about 4 microseconds)
;Clock-low to data-change: 4 to 6 cycles
;Data-change to await-clock-high: 1 cycle
;Clock-high to await-clock-low: 6 cycles best case, 15 cycles worst case
;Start-bit to await-clock-low: 7 cycles
;If clock is symmetric, minimum period is 22 cycles (88 microseconds).

send	(anl p1 (/# (complement 1_6)))	;Send a 0 to start
	(mov a r2)
	(call send-byte)
	(mov a r3)
	(call send-byte)
	(mov a r4)
	(call send-byte)
send-1	(jnt1 send-1)			;Await clock high (idle)
	(orl p1 (/# 1_6))		;Restore line to high
	(ret)

send-byte
	(mov r0 (/# 10))
send-byte-1
	(jb0 send-a-1)
send-a-0
	(jt1 send-a-0)			;Await clock low
	(anl p1 (/# (complement 1_6)))	;Send a 0
send-next-bit-0
	(rrc a)
send-await-clock-high-0
	(jnt1 send-await-clock-high-0)
	(djnz r0 send-byte-1)
	(ret)

send-a-1
	(jt1 send-a-1)			;Await clock low
	(orl p1 (/# 1_6))		;Send a 1
send-next-bit-1
	(rrc a)
send-await-clock-high-1
	(jnt1 send-await-clock-high-1)
	(djnz r0 send-byte-1)
	(ret)

	(= 400)
;Return in R2 and R3 the low 16 bits of an all-up key-code.
;This works by checking through the bitmap looking for shift keys
;that are down, and OR'ing in the bits.
compute-all-up-code
	(mov r2 (/# 0))
	(mov r3 (/# 200))		;Start with only bit 15 set
	(mov r5 (/# 0))			;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 8 or more
	(add a (/# -8))
	(jb7 cauc-4)			;Jump if less than 8
	(mov r6 a)			;Save bitnumber within middle byte
	(call cauc-sh)
	(orl a r3)
	(mov r3 a)
	(jmp cauc-9)

cauc-4	(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
	(ret)				;Result is in R2,R3

;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 delay for 3 seconds
;to give 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 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))
	(jmp send-boot)

cold-boot
	(mov r2 (/# 46))
send-boot
	(mov r3 (/# 374))		;1's in bits 15-10
	(mov r4 (/# 371))		;Source ID 1 (new keyboard)
	(call send)			;Transmit character
	(mov r4 (/# 6))			;Delay 3 seconds
boot-delay-1
	(mov r3 (/# 0))			;Delay 1/2 second
boot-delay-2
	(mov r2 (/# 0))			;Delay 2 milliseconds
boot-delay-3
	(djnz r2 boot-delay-3)
	(djnz r3 boot-delay-2)
	(djnz r4 boot-delay-1)
not-boot
	(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)

;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)))))))
     
Space-cadet controller source code

User avatar
Soarer

28 Oct 2011, 02:56

webwit wrote:I wonder how many layers/characters the Aikon supports.
Plus a custom HID driver for your OS? I'm sure it's do-able...

woody
Count Troller

28 Oct 2011, 12:37

webwit wrote:;;; -*- Mode: Lisp; Base: 8; Package: User -*-

(defun complement (x)
(logxor 377 x))
Good grief, octal as default radix.

User avatar
Ascaii
The Beard

28 Oct 2011, 12:45

too lazy to compare...but is this related? http://jrm-code-project.googlecode.com/ ... /ukbd.lisp

User avatar
7bit

28 Oct 2011, 12:52

woody wrote:
webwit wrote:;;; -*- Mode: Lisp; Base: 8; Package: User -*-

(defun complement (x)
(logxor 377 x))
Good grief, octal as default radix.
This I like most:

Code: Select all

;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 delay for 3 seconds
;to give 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_L-Control_L-Control_R-Meta-Return (or Rubout for cold-boot)

xahlee

29 Oct 2011, 02:47

@webwit i used your photos at http://xahlee.org/kbd/lisp_keyboards.html Thanks for the perm.

What's the one in front for the key “:”?
it looks like section sign “§” but doesn't seem to be.

btw, where do you get a new one like that? It's quite amazing.

were you using lisp machines in the 1980s?

User avatar
webwit
Wild Duck

29 Oct 2011, 03:57

cadetcap.jpg
cadetcap.jpg (34.47 KiB) Viewed 27796 times
Got it from someone who was working at MIT's AI lab when these were being built. He had this one in storage ever since.
I wasn't using Lisp machines in the 80ties, a was just a small innocent little duck back then.

xahlee

29 Oct 2011, 06:45

webwit wrote:
cadetcap.jpg
Got it from someone who was working at MIT's AI lab when these were being built. He had this one in storage ever since.
I wasn't using Lisp machines in the 80ties, a was just a small innocent little duck back then.
Cool, and thanks for the new photo.

what the heck is that symbol... i couldn't find the symbol in unicode, nor APL keyboard... tried to find it in lisp machine manual but no luck. Thought it's some currency symbol but doesn't seem so after checking wikipedia.
Last edited by xahlee on 29 Oct 2011, 20:52, edited 1 time in total.

User avatar
webwit
Wild Duck

29 Oct 2011, 11:51

Maybe it's just a styled section sign.

xahlee

29 Oct 2011, 20:48

webwit wrote:Maybe it's just a styled section sign.
you are probably right. Will go with that. Am trying to create a diagram of its layout.

do you plan to get this keyboard to work?

a lisp machine Rainer Joswig got a later model of the lisp machine keyboard on his mac. But his website seems down. Another lisper i recall has also got it to work... i think they home made some converter dongle to usb and documented some of it... i don't know nothing about hardware...

Post Reply

Return to “Gallery”