Post by Mairtrus on Mar 4, 2011 16:57:02 GMT -5
Like one month ago, I was bored of test small useless code in my Genny with the LAKABAJO, so I remembered when some guy in the forums (like 1-2 years ago) asked if is possible to use a PS/2 keyboard in the real hardware... In the SpritesMind forums, some guys did it like 3-4 years ago, but no code was ever released, so I put my hands on it... and I got it!!
First, you will need a PS/2->DB-9 cable, which isn't too hard to make (if I could, anyone can) where the pins asignement is the next:
Data->Pin 1
Clock->Pin 2
Vcc->Pin 5
Gnd->Pin 8
This is the code for getting a message (scancode of pressed/unpressed keys, errors, etc):
I made it in asm only because the BEX code has no enough speed to get data when the clock reachs the falling edge. Also, I used the first joypad port only because I have the LAKABAJO cable plugged on the second joypad port, but if you want to use another port, change A10003(first joypad port) for A10005(second joypad port) or A10007 (exp port)
However, that code doesn't gives you the ASCII code of the current pressed key, just it's scancode. Next, there is a complete BEX template which shows how to create a writing routine:
As you can see, those scancode are for a Spanish Keyboard (the ones who have the Ñ and Ç letters), so for whatever other keyboard configuration, you will need to complete it whit your own configuration (mostly simbols and shit like that, since the uppercase and lowercase letters seems to have always the scancodes in all the keyboards)...
I added the extra functionality to the F1...4 functions to change the color of the text (command INK), and the arrows can be used for move around the text, but works weird for some reasons...
If you follow the code, you will see that there is a function to send commands to keyboard, however it doesn't work correctly for some reason (keyboard always responds whit "RESEND"). I hope somebody can be able to fix it.
Well, I think that's all, enjoy...
First, you will need a PS/2->DB-9 cable, which isn't too hard to make (if I could, anyone can) where the pins asignement is the next:
Data->Pin 1
Clock->Pin 2
Vcc->Pin 5
Gnd->Pin 8
This is the code for getting a message (scancode of pressed/unpressed keys, errors, etc):
GetPS2Msg:
move.l #$A10003,a0
move.b #0,6(a0)
bsr.w HighLow ; Wait for bit 0
moveq #7,d7
moveq #0,d1
moveq #0,d2
@1: bsr.w HighLow
move.b (a0),d0
andi.b #1,d0
or.b d0,d1
ror.b #1,d1
add.b d0,d2
dbra d7,@1
bsr.w HighLow ; Wait for parity
move.b (a0),d3
andi.w #1,d3
bsr.w HighLow ; Wait for bit 1
not.b d2
andi.b #1,d2
move.b #2,6(a0)
rts
HighLow:
move.w #800,d4
@1: move.b (a0),d0
andi.b #2,d0
beq.s @2
subq.w #1,d4
beq.s @3
bra.s @1
@2: move.b (a0),d0
andi.b #2,d0
beq.s @2
rts
@3: addq.l #4,a7
move.b #2,6(a0)
rts
I made it in asm only because the BEX code has no enough speed to get data when the clock reachs the falling edge. Also, I used the first joypad port only because I have the LAKABAJO cable plugged on the second joypad port, but if you want to use another port, change A10003(first joypad port) for A10005(second joypad port) or A10007 (exp port)
However, that code doesn't gives you the ASCII code of the current pressed key, just it's scancode. Next, there is a complete BEX template which shows how to create a writing routine:
option TEXTSTART,1,2
Dim Key as Integer, Parity as Integer, KbParity as Integer, KbMsg as Integer
Init:
' KbMsg=&hEE
' gosub SendPS2Msg
' gosub GetPS2Msg
' print right$(hex$(Key),2)
' asm
' jsr joypad_checkreset
' end asm
' goto Init
locate 0,0
Cursor=addsprite(1,1)
propsprite Cursor,&hDB,0
MainLoop:
Key=0
gosub GetPS2Msg
if Key<&hF0 then
if Key<&hE0 then
if Key=&h5A then
print ""
elseif Key=&h12 then
ShiftMode=1
elseif Key=&h14 then
CtrlMode=1
elseif Key=&h11 then
AltMode=1
elseif Key=&h76 then
cls
locate 0,0
elseif Key=&h66 then
if PosX()>0 then
Locate ,PosX()-1
else
if PosY()>0 then
Locate PosY()-1,37
end if
end if
Cx=PosX()
Cy=PosY()
print " ";
Locate Cy,Cx
elseif Key=&h05 then
ink 0
elseif Key=&h06 then
ink 1
elseif Key=&h04 then
ink 2
elseif Key=&h0C then
ink 3
else
asm
move.l #ScanCodes1,a0
tst.w (__INTEGER_ShiftMode)
bne.s @1
move.l #ScanCodes2,a0
@1:
move.w (__INTEGER_CtrlMode),d0
and.w (__INTEGER_AltMode),d0
beq.s @2
move.l #ScanCodes3,a0
@2:
moveq #0,d0
move.w (__INTEGER_Key),d0
lsl.w #1,d0
move.w (a0,d0.w),d1
move.w d1,(__INTEGER_Key)
end asm
print chr$(Key);
end if
else
gosub GetPS2Msg
if Key>=&h6B then
Select Case Key-&h6B
Case 0:
if PosX()>0 then
Locate ,PosX()-1
else
if PosY()>0 then
Locate PosY()-1,37
end if
end if
Exit Select
Case 7:
if PosY()<25 then
Locate PosY()+1,
end if
Exit Select
Case 9:
if PosX()<37 then
Locate ,PosX()+1
else
if PosY()<25 then
Locate PosY()+1,0
end if
end if
Exit Select
Case 10:
if PosY()>0 then
Locate PosY()-1,
end if
Case Else:
Exit Select
End Select
else
if Key=&h4A then
print "/";
end if
end if
end if
else
gosub GetPS2Msg
if Key>=&hE0 then
gosub GetPS2Msg
else
if Key=&h12 then
ShiftMode=0
elseif Key=&h14 then
CtrlMode=0
elseif Key=&h11 then
AltMode=0
end if
end if
end if
movesprite Cursor,144+(PosX()<<3),136+(PosY()<<3)
asm
jsr joypad_checkreset
end asm
goto MainLoop
GetPS2Msg:
asm
move.l #$A10003,a0
move.b #0,6(a0)
bsr.w HighLow ; Wait for bit 0
moveq #7,d7
moveq #0,d1
moveq #0,d2
@1: bsr.w HighLow
move.b (a0),d0
andi.b #1,d0
or.b d0,d1
ror.b #1,d1
add.b d0,d2
dbra d7,@1
bsr.w HighLow ; Wait for parity
move.b (a0),d3
andi.w #1,d3
bsr.w HighLow ; Wait for bit 1
move.w d1,(__INTEGER_Key)
not.b d2
andi.b #1,d2
move.w d2,(__INTEGER_Parity)
move.w d3,(__INTEGER_KBParity)
move.b #2,6(a0)
rts
HighLow:
move.w #800,d4
@1: move.b (a0),d0
andi.b #2,d0
beq.s @2
subq.w #1,d4
beq.s @3
bra.s @1
@2: move.b (a0),d0
andi.b #2,d0
beq.s @2
rts
@3: addq.l #4,a7
move.b #2,6(a0)
rts
end asm
SendPS2Msg:
asm
move.l #$A10003,a0
move.b #2,6(a0)
move.l #20,d0
dbra d0,*
move.w (__INTEGER_KbMsg),d1
moveq #7,d7
moveq #0,d1
moveq #0,d2
moveq #0,d3
move.b #1,6(a0)
move.b #0,(a0)
bsr.w HighLow
@1: move.b d1,d2
andi.b #1,d2
bsr.w HighLow
move.b d2,(a0)
ror.b #1,d1
add.b d2,d3
dbra d7,@1
not.b d3
andi.b #1,d3
move.b d3,(a0)
bsr.w HighLow
move.b #0,6(a0)
bsr.w HighLow
move.b (a0),d0
andi.b #2,d0
move.b #2,6(a0)
rts
end asm
asm
ScanCodes1:
dc.w 0 ; 00
dc.w 0 ; +1
dc.w 0 ; +2
dc.w 0 ; +3
dc.w 0 ; +4
dc.w 0 ; +5
dc.w 0 ; +6
dc.w 0 ; +7
dc.w 0 ; +8
dc.w 0 ; +9
dc.w 0 ; +A
dc.w 0 ; +B
dc.w 0 ; +C
dc.w 0 ; +D
dc.w $A6 ; +E
dc.w 0 ; +F
dc.w 0 ; 10
dc.w 0 ; +1
dc.w 0 ; +2
dc.w 0 ; +3
dc.w 0 ; +4
dc.w 'Q' ; +5
dc.w '!' ; +6
dc.w 0 ; +7
dc.w 0 ; +8
dc.w 0 ; +9
dc.w 'Z' ; +A
dc.w 'S' ; +B
dc.w 'A' ; +C
dc.w 'W' ; +D
dc.w '"' ; +E
dc.w 0 ; +F
dc.w 0 ; 20
dc.w 'C' ; +1
dc.w 'X' ; +2
dc.w 'D' ; +3
dc.w 'E' ; +4
dc.w '$' ; +5
dc.w '#' ; +6
dc.w 0 ; +7
dc.w 0 ; +8
dc.w ' ' ; +9
dc.w 'V' ; +A
dc.w 'F' ; +B
dc.w 'T' ; +C
dc.w 'R' ; +D
dc.w '%' ; +E
dc.w 0 ; +F
dc.w 0 ; 30
dc.w 'N' ; +1
dc.w 'B' ; +2
dc.w 'H' ; +3
dc.w 'G' ; +4
dc.w 'Y' ; +5
dc.w '&' ; +6
dc.w 0 ; +7
dc.w 0 ; +8
dc.w 0 ; +9
dc.w 'M' ; +A
dc.w 'J' ; +B
dc.w 'U' ; +C
dc.w '/' ; +D
dc.w '(' ; +E
dc.w 0 ; +F
dc.w 0 ; 40
dc.w ';' ; +1
dc.w 'K' ; +2
dc.w 'I' ; +3
dc.w 'O' ; +4
dc.w '=' ; +5
dc.w ')' ; +6
dc.w 0 ; +7
dc.w 0 ; +8
dc.w ':' ; +9
dc.w '_' ; +A
dc.w 'L' ; +B
dc.w $A5 ; +C
dc.w 'P' ; +D
dc.w '?' ; +E
dc.w 0 ; +F
dc.w 0 ; 50
dc.w 0 ; +1
dc.w 0 ; +2
dc.w 0 ; +3
dc.w 0 ; +4
dc.w $A8 ; +5
dc.w 0 ; +6
dc.w 0 ; +7
dc.w 0 ; +8
dc.w 0 ; +9
dc.w 0 ; +A
dc.w 0 ; +B
dc.w 0 ; +C
dc.w $80 ; +D
dc.w 0 ; +E
dc.w 0 ; +F
dc.w 0 ; 60
dc.w '>' ; +1
dc.w 0 ; +2
dc.w 0 ; +3
dc.w 0 ; +4
dc.w 0 ; +5
dc.w 0 ; +6
dc.w 0 ; +7
dc.w 0 ; +8
dc.w '1' ; +9
dc.w 0 ; +A
dc.w '4' ; +B
dc.w '7' ; +C
dc.w 0 ; +D
dc.w 0 ; +E
dc.w 0 ; +F
dc.w '0' ; 70
dc.w '.' ; +1
dc.w '2' ; +2
dc.w '5' ; +3
dc.w '6' ; +4
dc.w '8' ; +5
dc.w 0 ; +6
dc.w 0 ; +7
dc.w 0 ; +8
dc.w '+' ; +9
dc.w '3' ; +A
dc.w '-' ; +B
dc.w '*' ; +C
dc.w '9' ; +D
dc.w 0 ; +E
dc.w 0 ; +F
ScanCodes2:
dc.w 0 ; 00
dc.w 0 ; +1
dc.w 0 ; +2
dc.w 0 ; +3
dc.w 0 ; +4
dc.w 0 ; +5
dc.w 0 ; +6
dc.w 0 ; +7
dc.w 0 ; +8
dc.w 0 ; +9
dc.w 0 ; +A
dc.w 0 ; +B
dc.w 0 ; +C
dc.w 0 ; +D
dc.w $A7 ; +E
dc.w 0 ; +F
dc.w 0 ; 10
dc.w 0 ; +1
dc.w 0 ; +2
dc.w 0 ; +3
dc.w 0 ; +4
dc.w 'q' ; +5
dc.w '1' ; +6
dc.w 0 ; +7
dc.w 0 ; +8
dc.w 0 ; +9
dc.w 'z' ; +A
dc.w 's' ; +B
dc.w 'a' ; +C
dc.w 'w' ; +D
dc.w '2' ; +E
dc.w 0 ; +F
dc.w 0 ; 20
dc.w 'c' ; +1
dc.w 'x' ; +2
dc.w 'd' ; +3
dc.w 'e' ; +4
dc.w '4' ; +5
dc.w '3' ; +6
dc.w 0 ; +7
dc.w 0 ; +8
dc.w ' ' ; +9
dc.w 'v' ; +A
dc.w 'f' ; +B
dc.w 't' ; +C
dc.w 'r' ; +D
dc.w '5' ; +E
dc.w 0 ; +F
dc.w 0 ; 30
dc.w 'n' ; +1
dc.w 'b' ; +2
dc.w 'h' ; +3
dc.w 'g' ; +4
dc.w 'y' ; +5
dc.w '6' ; +6
dc.w 0 ; +7
dc.w 0 ; +8
dc.w 0 ; +9
dc.w 'm' ; +A
dc.w 'j' ; +B
dc.w 'u' ; +C
dc.w '7' ; +D
dc.w '8' ; +E
dc.w 0 ; +F
dc.w 0 ; 40
dc.w ',' ; +1
dc.w 'k' ; +2
dc.w 'i' ; +3
dc.w 'o' ; +4
dc.w '0' ; +5
dc.w '9' ; +6
dc.w 0 ; +7
dc.w 0 ; +8
dc.w '.' ; +9
dc.w '-' ; +A
dc.w 'l' ; +B
dc.w $A4 ; +C
dc.w 'p' ; +D
dc.w $27 ; +E
dc.w 0 ; +F
dc.w 0 ; 50
dc.w 0 ; +1
dc.w 0 ; +2
dc.w 0 ; +3
dc.w 0 ; +4
dc.w $AD ; +5
dc.w 0 ; +6
dc.w 0 ; +7
dc.w 0 ; +8
dc.w 0 ; +9
dc.w 0 ; +A
dc.w 0 ; +B
dc.w 0 ; +C
dc.w $87 ; +D
dc.w 0 ; +E
dc.w 0 ; +F
dc.w 0 ; 60
dc.w '<' ; +1
dc.w 0 ; +2
dc.w 0 ; +3
dc.w 0 ; +4
dc.w 0 ; +5
dc.w 0 ; +6
dc.w 0 ; +7
dc.w 0 ; +8
dc.w '1' ; +9
dc.w 0 ; +A
dc.w '4' ; +B
dc.w '7' ; +C
dc.w 0 ; +D
dc.w 0 ; +E
dc.w 0 ; +F
dc.w '0' ; 70
dc.w '.' ; +1
dc.w '2' ; +2
dc.w '5' ; +3
dc.w '6' ; +4
dc.w '8' ; +5
dc.w 0 ; +6
dc.w 0 ; +7
dc.w 0 ; +8
dc.w '+' ; +9
dc.w '3' ; +A
dc.w '-' ; +B
dc.w '*' ; +C
dc.w '9' ; +D
dc.w 0 ; +E
dc.w 0 ; +F
ScanCodes3:
dc.w 0 ; 00
dc.w 0 ; +1
dc.w 0 ; +2
dc.w 0 ; +3
dc.w 0 ; +4
dc.w 0 ; +5
dc.w 0 ; +6
dc.w 0 ; +7
dc.w 0 ; +8
dc.w 0 ; +9
dc.w 0 ; +A
dc.w 0 ; +B
dc.w 0 ; +C
dc.w 0 ; +D
dc.w $5C ; +E
dc.w 0 ; +F
dc.w 0 ; 10
dc.w 0 ; +1
dc.w 0 ; +2
dc.w 0 ; +3
dc.w 0 ; +4
dc.w 'q' ; +5
dc.w '1' ; +6
dc.w 0 ; +7
dc.w 0 ; +8
dc.w 0 ; +9
dc.w 'z' ; +A
dc.w 's' ; +B
dc.w 'a' ; +C
dc.w 'w' ; +D
dc.w '2' ; +E
dc.w 0 ; +F
dc.w 0 ; 20
dc.w 'c' ; +1
dc.w 'x' ; +2
dc.w 'd' ; +3
dc.w 'e' ; +4
dc.w '4' ; +5
dc.w '3' ; +6
dc.w 0 ; +7
dc.w 0 ; +8
dc.w ' ' ; +9
dc.w 'v' ; +A
dc.w 'f' ; +B
dc.w 't' ; +C
dc.w 'r' ; +D
dc.w '5' ; +E
dc.w 0 ; +F
dc.w 0 ; 30
dc.w 'n' ; +1
dc.w 'b' ; +2
dc.w 'h' ; +3
dc.w 'g' ; +4
dc.w 'y' ; +5
dc.w '6' ; +6
dc.w 0 ; +7
dc.w 0 ; +8
dc.w 0 ; +9
dc.w 'm' ; +A
dc.w 'j' ; +B
dc.w 'u' ; +C
dc.w '7' ; +D
dc.w '8' ; +E
dc.w 0 ; +F
dc.w 0 ; 40
dc.w ',' ; +1
dc.w 'k' ; +2
dc.w 'i' ; +3
dc.w 'o' ; +4
dc.w '0' ; +5
dc.w '9' ; +6
dc.w 0 ; +7
dc.w 0 ; +8
dc.w '.' ; +9
dc.w '-' ; +A
dc.w 'l' ; +B
dc.w 'ñ' ; +C
dc.w 'p' ; +D
dc.w $27 ; +E
dc.w 0 ; +F
dc.w 0 ; 50
dc.w 0 ; +1
dc.w 0 ; +2
dc.w 0 ; +3
dc.w 0 ; +4
dc.w '¡' ; +5
dc.w 0 ; +6
dc.w 0 ; +7
dc.w 0 ; +8
dc.w 0 ; +9
dc.w 0 ; +A
dc.w 0 ; +B
dc.w 0 ; +C
dc.w 'ç' ; +D
dc.w 0 ; +E
dc.w 0 ; +F
dc.w 0 ; 60
dc.w '<' ; +1
dc.w 0 ; +2
dc.w 0 ; +3
dc.w 0 ; +4
dc.w 0 ; +5
dc.w 0 ; +6
dc.w 0 ; +7
dc.w 0 ; +8
dc.w '1' ; +9
dc.w 0 ; +A
dc.w '4' ; +B
dc.w '7' ; +C
dc.w 0 ; +D
dc.w 0 ; +E
dc.w 0 ; +F
dc.w '0' ; 70
dc.w '.' ; +1
dc.w '2' ; +2
dc.w '5' ; +3
dc.w '6' ; +4
dc.w '8' ; +5
dc.w 0 ; +6
dc.w 0 ; +7
dc.w 0 ; +8
dc.w '+' ; +9
dc.w '3' ; +A
dc.w '-' ; +B
dc.w '*' ; +C
dc.w '9' ; +D
dc.w 0 ; +E
dc.w 0 ; +F
end asm
As you can see, those scancode are for a Spanish Keyboard (the ones who have the Ñ and Ç letters), so for whatever other keyboard configuration, you will need to complete it whit your own configuration (mostly simbols and shit like that, since the uppercase and lowercase letters seems to have always the scancodes in all the keyboards)...
I added the extra functionality to the F1...4 functions to change the color of the text (command INK), and the arrows can be used for move around the text, but works weird for some reasons...
If you follow the code, you will see that there is a function to send commands to keyboard, however it doesn't work correctly for some reason (keyboard always responds whit "RESEND"). I hope somebody can be able to fix it.
Well, I think that's all, enjoy...