PS/2 keyboard to Amiga 1200 mainboard adapter

pvdven777

New Member
Allright, so here's a little background first.
My warehouse colleague came to me with a big metal box one day asking me if it is safe to scrap.
Judging by the layer of dust on it I predicted that wouldn't be a problem and said I'd take it off his hand for the time. However being the nostalgic tinkerer that I am I just had to open up this vague box to see what's inside.
Turns out there's some golden oldie in there. It was some sort of headless computer based on an Amiga 1200 mainboard. So all I had was pretty much a bare mainboard and a hacked together power supply that was put in by whatever company that built this headless hack-computer. I hacked together a mouse by using an old PS/2 mouse. Made an adapter to connect to SCART as with compsite it was nearly impossbile to see anything on screen. Using an emulator I prepped a bootable harddisk. But then there was the challenge. I didnt have a keyboard.

Picaxe - Retro - Challenge :
Now here is my first genuine great excuse to start trying out my recently acquired Picaxe (020 starter) set.
Now there are some PIC based solutions out there already. However the documentation is not all that understandable to me. On top of that I wanted something easily and quickly customisable. Most certainly I didn't want to learn another assembly language or buy/built a PIC programmer.
Because Picaxe already has PS/2 input support I thought that would do half the job already.
Turns out however that some of the limitations of the kbin command nearly made my idea impossible but I managed to work around most of that. Now these kind of projects I guess are never finished but the first and most important step has now been completed. Time to sare has come.
I've got the hardware linked and the software programming set up such that I can type text on a PS/2 keyboard and have it sent to/ register on the Amiga.

Won't go into all of the detail unless someone likes to know specifics. In short what I've done is attached a PS/2 connector to the picaxe to hook up a keyboard. Then on the other end I've managed to tap into the Amiga 1200 chipset such that I can bypass the orginal ribbon internal keyboard connector and also get power to my project board.

Here's the cleaned up and commented code I built to get things working :

Code:
' ********************************************************************
' ********************************************************************
' PS/2 to Amiga 1200 keyboard protocol conversion
' 
' Code version:	V1.0 
'
' Written for:	PICAXE 20M2
'
' Notes :
' Leg 15 of chip as Amiga Keyboard data line
' Leg 16 of chip as Amiga Keyboard clock line
' Leg 9 of chip as PS/2 Keyboard data line (as per datasheet)
' Leg 8 of chip as PS/2 Keyboard clock line (as per datasheet)
' Any M2 Picaxe could be used here except 08M2 which has no PS/2 input
'
' ********************************************************************
' ********************************************************************

Symbol AmiKDAT = b.2					' Preset Picaxe Amiga Keyboard data line
Symbol AmiKCLK = b.3					' Preset Picaxe Amiga Keyboard clock line
symbol PS2ReadKey = b10 				' What's read from PS/2 keyboard
symbol Amikeycode = b2 					' The Amiga equivalent of the PS/2 keyboard code
symbol Sendcode = b1					' Preprocessed ready to send to Amiga code
Symbol Var_Out = b12					' Temporary storage for output
Symbol mask = b13						' Mask to assist in isolating each bit for bitbang output
Symbol Counter = b11					' Loop counter
Symbol bits = 8						' Number of bits to send (loop counter target)

MAIN:
' **********************
' *** Initialization ***
' **********************

		'setfreq m4					' Force Picaxe to operate at 4 Mhz to ensure correct timings
		'input AmiKDAT				' Set pin to input "High-Z"
		'input AmiKCLK				' Set pin to input "High-Z"
		'...						' init keyboard communication
		'input AmiKDAT				' Set pin to input "High-Z"
		'input AmiKCLK				' Set pin to input "High-Z"
				
' ********************		
' *** Main program ***
' ********************

Readkeyloop:
						
		kbin PS2ReadKey				' Get the PS/2 keypress
		readtable PS2ReadKey,Amikeycode	' Convert PS/2 keycode to Amiga code by lookup table

		gosub Keypress				' Handle keypress
		'PAUSEUS 500				' Extra pause in between press and release action
		gosub Keyrelease				' Handle (simulate) key release
goto Readkeyloop						' Continuous loop

' *******************
' *** Subroutines ***
' *******************

' *** Keypress handler routine ***
Keypress:
		Sendcode = Amikeycode * 2		' Shift left by 1 position
		'...						' Set key pressed bit (not needed because its already 0 after shift)
		'...			 			' Save key code to "release action" queue (for future code version)
		gosub Amikeysend	 			' Go to send subroutine
Return

' *** Key release handler routine ***
Keyrelease:	
		'................... 			' Get key code from release action queue in future revision code
		Sendcode = Amikeycode * 2		' Shift left by 1 position
		Sendcode = Sendcode + 1			' Set key release bit
		gosub Amikeysend	 			' Go to send subroutine
		'...						' Clear keycode from "release action" queue (for future code version)
Return

' *** Keycode send to Amiga handler routine ***
AmiKeysend:

		high AmiKCLK				' Initialize Amiga keyboard Clock line
		high AmiKDAT				' Initialize Amiga keyboard Data line
		'PAUSEUS 20					' Wait for line stabilization

		'...						' Keyboard supposedly pulses KDAT low once for min. 1usec.as handshake.
		'...						' Doesn't appear to be required to make things work. (possibly for future code version) 	
						
var_out = not sendcode					' Load code to be sent and invert it (Amiga expects active low signals)							

for counter = 1 to bits 				' Count up to number of bits to send
	mask = var_out & 128 				' Mask MSB
	if mask = 0 then low AmiKDAT else		' Set dataline low or high
	high AmiKDAT					
	endif 
	PAUSEUS 20						' Wait 20 usec. for dataline to stabilize
	pulsout AmiKCLK,2 				' Pulse clock for 20us
	var_out = var_out * 2 				' Shift variable left to get next bit positioned under the mask correctly
next counter						' Loop to send out next bit
high AmiKDAT
								' Computer now pulses Kdat low for 1~85usec. as handshake/Ack
								' Doesn't appear to be required to make things work. (possibly for future code version)
return

' ****************************************
' *** Preload lookup table into memory ***
' ****************************************
	
TABLE $00,($20,$58,$20,$54,$52,$50,$51,$20,$20,$59,$57,$55,$53,$42,$20,$20)	'$0x
TABLE $10,($20,$64,$60,$20,$63,$10,$01,$20,$20,$20,$31,$21,$20,$11,$02,$66)	'$1x (Main keyboard keys)
TABLE $20,($20,$33,$32,$22,$12,$04,$03,$67,$20,$40,$34,$23,$14,$13,$05,$65)	'$2x (Main keyboard keys)
TABLE $30,($20,$36,$35,$25,$24,$15,$06,$20,$20,$20,$37,$26,$16,$07,$08,$20)	'$3x (Main keyboard keys)
TABLE $40,($20,$38,$27,$17,$18,$0A,$09,$20,$20,$39,$3A,$28,$29,$19,$0B,$20)	'$4x (Main keyboard keys)
TABLE $50,($20,$20,$2A,$20,$1A,$0C,$20,$20,$62,$61,$44,$1B,$20,$20,$20,$20)	'$5x (Main keyboard keys)
TABLE $60,($20,$20,$20,$20,$20,$20,$41,$20,$20,$1D,$20,$4F,$3D,$20,$20,$20)	'$6x
TABLE $70,($5F,$46,$4D,$2E,$4E,$4C,$45,$20,$20,$5E,$1F,$4A,$5D,$3F,$20,$20)	'$7x
TABLE $80,($20,$20,$20,$56,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20)
Since kbin doesn't give me key release info I had to fake it.
In this version I send a key press and immediately after I generate my own key release.
I'm hoping to build a solution into the next revision that will allow me to send a key release with a delay so that overlapping key presses become an option.
Right now I'm stuck with all lowercase letters and no special key combo's because of this.

My idea was to send each key to a buffer. Then I could send the key release with a certain delay big enough to allow one or maybe two other keys to be pressed on between.
I thought I could do this with a second program thread. However I've now understood that this may not work because the picaxe switches from one thread to another executing one line of code at a time.
Imagine what would happen whilst sending bits to the keyboard controller one by one..... another command may disturb timing or pass the wrong bit on.
Suggestions are very welcome !!

I've added an 'action shot' for the fun of it.
 

Attachments

Top