User avatar
olaf
Posts: 11
Joined: Sat Nov 03, 2012 3:01 pm
Location: Germany, Friesland
Contact: Website

Re: Raspberry 500 / Amiga Pi ?

Tue Nov 20, 2012 3:55 pm

Great work, thank you Thomas!
in case you also want to connect some oldshool digital joysticks like the competition pro to your retro Amiga here's a simple solution.
This code transforms the arduino leonardo board into a HID joystick converter for two digital joysticks.

put this into your HID.cpp to create 2 HID Gamepads:

Code: Select all

//   Commodore / Atari Joystick 1

	0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
	0x09, 0x05,                    // USAGE (Game Pad)
	0xa1, 0x01,                    // COLLECTION (Application)
	0x85, 0x03,                    //   REPORT_ID (3)
	0x09, 0x01,                    //   USAGE (Pointer)
	0xa1, 0x00,                    //   COLLECTION (Physical)
	0x09, 0x30,                    //     USAGE (X)
	0x09, 0x31,                    //     USAGE (Y)
	0x15, 0xff,                    //     LOGICAL_MINIMUM (-1)
	0x25, 0x01,                    //     LOGICAL_MAXIMUM (1)
	0x95, 0x02,                    //     REPORT_COUNT (2)
	0x75, 0x02,                    //     REPORT_SIZE (2) ; two bits to represent each axis
	0x81, 0x02,                    //     INPUT (Data,Var,Abs)
	0xc0,                          //   END_COLLECTION
	0x05, 0x09,                    //   USAGE_PAGE (Button)
	0x19, 0x01,                    //   USAGE_MINIMUM (Button 1)
	0x29, 0x01,                    //   USAGE_MAXIMUM (Button 1)
	0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
	0x25, 0x01,                    //   LOGICAL_MAXIMUM (1)
	0x95, 0x01,                    //   REPORT_COUNT (1) ; 1 button
	0x75, 0x01,                    //   REPORT_SIZE (1)
	0x81, 0x02,                    //   INPUT (Data,Var,Abs)
	0x95, 0x03,                    //	REPORT_COUNT (3) ; to pad out the bits into a number divisible by 8
	0x81, 0x03,                    //   INPUT (Const,Var,Abs)
	0xc0,                          // END_COLLECTION
 
//   Commodore / Atari Joystick 2

	0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
	0x09, 0x05,                    // USAGE (Game Pad)
	0xa1, 0x01,                    // COLLECTION (Application)
	0x85, 0x04,                    //   REPORT_ID (4)
 	0xa1, 0x00,                    //   COLLECTION (Physical)	
	0x95, 0x01,                    //	REPORT_COUNT (1) ; to pad out the bits into a number divisible by 8
	0x81, 0x03,                    //   INPUT (Const,Var,Abs)	
	0x05, 0x09,                    //   USAGE_PAGE (Button)
	0x19, 0x01,                    //   USAGE_MINIMUM (Button 1)
	0x29, 0x01,                    //   USAGE_MAXIMUM (Button 3)
	0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
	0x25, 0x01,                    //   LOGICAL_MAXIMUM (1)
	0x95, 0x01,                    //   REPORT_COUNT (1) ; 1 button
	0x75, 0x01,                    //   REPORT_SIZE (1)
	0x81, 0x02,                    //   INPUT (Data,Var,Abs)
 	0x95, 0x02,                    //	REPORT_COUNT (2) ; to pad out the bits into a number divisible by 8
	0x81, 0x03,                    //   INPUT (Const,Var,Abs)
    0x05, 0x01,                    //     USAGE_PAGE (Generic Desktop)
	0x09, 0x30,                    //     USAGE (X)
	0x09, 0x31,                    //     USAGE (Y)
	0x15, 0xff,                    //     LOGICAL_MINIMUM (-1)
	0x25, 0x01,                    //     LOGICAL_MAXIMUM (1)
	0x95, 0x02,                    //     REPORT_COUNT (2)
	0x75, 0x02,                    //     REPORT_SIZE (2) ; two bits to represent each axis
	0x81, 0x02,                    //     INPUT (Data,Var,Abs)
	0xc0,                          //   END_COLLECTION
	0xc0                           // END_COLLECTION	 
merge this into your existing sketch or use it as a standalone solution:

Code: Select all

    uint8_t Joy;
    uint8_t MemoJoy1 ;
    uint8_t MemoJoy2 ;

    void setup() { 

      // Joystick 1
      pinMode(0, INPUT_PULLUP);						// configure as DigIn  with pull up
      pinMode(1, INPUT_PULLUP);
      pinMode(2, INPUT_PULLUP);
      pinMode(3, INPUT_PULLUP);
      pinMode(4, INPUT_PULLUP);
      
      // Joystick 2
      pinMode(A0, INPUT_PULLUP);
      pinMode(A1, INPUT_PULLUP);
      pinMode(A2, INPUT_PULLUP);
      pinMode(A3, INPUT_PULLUP);
      pinMode(A4, INPUT_PULLUP);
    }

    void loop() 
    {
            // Joystick 1
            Joy = ~PIND;   									// read Port D , invert bit logic
            if (Joy != MemoJoy1) {  				// state changed?
              HID_SendReport(3, &Joy, 1);   // send HID report
              MemoJoy1 = Joy;								// save last state
            }  
           // Joystick 2
            Joy = ~PINF;
            if (Joy != MemoJoy2) {
              HID_SendReport(4, &Joy, 1);
              MemoJoy2 = Joy;
            }  
    }
    
Joystick 1 must be hooked up to digital inputs 0...4, joystck 2 to analog inputs A0...A4.

together with the keyboard interface you now have the complete keyrah functionality, but faster and cheaper!

Olaf
Dipl. Ing. (FH) Olaf Berthold Hardware- und Softwareentwicklung
www.olafberthold.de . . . . www.canhack.de . . . . www.cpos-online.de

thradtke
Posts: 492
Joined: Wed May 16, 2012 5:16 am
Location: Germany / EL

Re: Raspberry 500 / Amiga Pi ?

Tue Nov 20, 2012 7:18 pm

Excellent, Olaf! :-)
Rocket Scientist.

mikerr
Posts: 2814
Joined: Thu Jan 12, 2012 12:46 pm
Location: UK
Contact: Website

Re: Raspberry 500 / Amiga Pi ?

Tue Nov 20, 2012 8:26 pm

Now put UAE amiga emulator on the Pi (precompiled here http://www.raspberrypi.org/phpBB3/viewt ... 41#p178187), and you have come full circle ;)
Android app - Raspi Card Imager - download and image SD cards - No PC required !

Altairst8te74
Posts: 23
Joined: Mon Nov 19, 2012 10:08 pm

Re: Raspberry 500 / Amiga Pi ?

Tue Nov 20, 2012 9:02 pm

Amazing. All I need to get now is some Pi lol.
I missed one the other day, seller had bought it for a project that fell through.

How well does amiga emulation run on these things?

User avatar
Wizard
Posts: 120
Joined: Sun Aug 19, 2012 4:52 am
Location: Sweden

Re: Raspberry 500 / Amiga Pi ?

Wed Nov 21, 2012 12:16 am

Am I the only one using bog-standard UAE?

e-uae doesnt work properly IMHO and uae4all throws up various issues every time I decide to have a go at it...

I tried do rewrite uae to use directfb but I've so far been unsuccessful in my attempts...

My goal is to boot into uae in fullscreen without X.

Project two is to wire in one internal Amiga 500 floppy drive and that's going to be an exciting exercise with regards to timings and interrupts!
I know you can buy a board that does this but what's the fun with that ;)

p.s Nice work on the joystick parts!!!
Raspberry Pi - finally a worthy replacement for A500!!!

User avatar
olaf
Posts: 11
Joined: Sat Nov 03, 2012 3:01 pm
Location: Germany, Friesland
Contact: Website

Re: Raspberry 500 / Amiga Pi ?

Thu Nov 22, 2012 10:55 pm

here's a little improvement:
to avoid sending HID reports caused by random changes of unused inputs you should add a bit mask in the code:

Code: Select all

      // Joystick 1
      Joy = ~PIND & 0b00011111;     // read Port D, invert logic, mask relevant bits
      if (Joy != MemoJoy1) {        // state changed?
        HID_SendReport(3, &Joy, 1); // send HID report
        MemoJoy1 = Joy;             // save last state
      } 
     // Joystick 2
      Joy = ~PINF & 0b11110010;
      if (Joy != MemoJoy2) {
        HID_SendReport(4, &Joy, 1);
        MemoJoy2 = Joy;
      }  
Dipl. Ing. (FH) Olaf Berthold Hardware- und Softwareentwicklung
www.olafberthold.de . . . . www.canhack.de . . . . www.cpos-online.de

User avatar
olaf
Posts: 11
Joined: Sat Nov 03, 2012 3:01 pm
Location: Germany, Friesland
Contact: Website

Re: Raspberry 500 / Amiga Pi ?

Thu Nov 22, 2012 11:13 pm

this is the pin assignment:

Code: Select all

Joystick 1

IO DB9  Function

1   1   Forward 
0   2   Back 
2   3   Left 
3   4   Right 
    5   not connected 
4   6   Button1 
5V  7   +5V 
GND 8   Ground 
    9   Button2 (optional)

Joystick 2

IO DB9  Function

A0  1   Forward 
A1  2   Back 
A2  3   Left 
A3  4   Right 
    5   not connected 
A4  6   Button1 
5V  7   +5V 
GND 8   Ground 
    9   Button2 (optional)
I wonder if it would be useful to add a second button?
Dipl. Ing. (FH) Olaf Berthold Hardware- und Softwareentwicklung
www.olafberthold.de . . . . www.canhack.de . . . . www.cpos-online.de

Altairst8te74
Posts: 23
Joined: Mon Nov 19, 2012 10:08 pm

Re: Raspberry 500 / Amiga Pi ?

Fri Nov 23, 2012 2:31 pm

Am I right in assuming I will need another Leonardo board to have the amiga keyboard and joystick ports or can I just wire everything up on one board?

I am practically ready to start putting this all together now but if I need another Arduino I need to order it asap!

User avatar
olaf
Posts: 11
Joined: Sat Nov 03, 2012 3:01 pm
Location: Germany, Friesland
Contact: Website

Re: Raspberry 500 / Amiga Pi ?

Fri Nov 23, 2012 2:38 pm

You can use both on the same Arduino Leonardo.
Dipl. Ing. (FH) Olaf Berthold Hardware- und Softwareentwicklung
www.olafberthold.de . . . . www.canhack.de . . . . www.cpos-online.de

Altairst8te74
Posts: 23
Joined: Mon Nov 19, 2012 10:08 pm

Re: Raspberry 500 / Amiga Pi ?

Fri Nov 23, 2012 3:18 pm

Excellent news! :)

Altairst8te74
Posts: 23
Joined: Mon Nov 19, 2012 10:08 pm

Re: Raspberry 500 / Amiga Pi ?

Tue Nov 27, 2012 10:32 pm

Guys, im reading about something to do with adding a jumper from pin2 to ground on the leonardo, this is supposed to stop the board getting stuck in keyboard mode.

Will this need to be done for the a500 keyboard stuff? are the commands in the a500 keyboard sketch as im not sure.

Also I have been picking away at this when I have spare time so have not done as much as I would like to. I think the wiring has been sussed out and im reading up about what the commands do. Hopefully I will end up with what im planning :lol:

thradtke
Posts: 492
Joined: Wed May 16, 2012 5:16 am
Location: Germany / EL

Re: Raspberry 500 / Amiga Pi ?

Wed Nov 28, 2012 6:08 am

Altairst8te74 wrote:Guys, im reading about something to do with adding a jumper from pin2 to ground on the leonardo, this is supposed to stop the board getting stuck in keyboard mode.
Nope. Reflashing the AVR is possible by simply resetting the board.
Rocket Scientist.

Altairst8te74
Posts: 23
Joined: Mon Nov 19, 2012 10:08 pm

Re: Raspberry 500 / Amiga Pi ?

Wed Nov 28, 2012 1:15 pm

Thanx, that is great to know! :)

Can somebody please confirm my wiring is correct:

Amiga <---------------------> Leonardo
1 KBCLK 9
2 KBDATA 8
3 KBRST 10
4 5v 5v
5 NC
6 GND GND
7 STATUS 11
8 IN USE 12

Just waiting for the decent a500 keyboard to turn up in the post and I can finish up.

:)

thradtke
Posts: 492
Joined: Wed May 16, 2012 5:16 am
Location: Germany / EL

Re: Raspberry 500 / Amiga Pi ?

Wed Nov 28, 2012 1:27 pm

Altairst8te74 wrote: 7 STATUS 11
8 IN USE 12
No! Never directly connect the LEDs to the Arduino pins. As I said earlier, you absolutely need a constant current source (wiring is contained somewhere in this thread) to drive the LEDs.
Rocket Scientist.

Altairst8te74
Posts: 23
Joined: Mon Nov 19, 2012 10:08 pm

Re: Raspberry 500 / Amiga Pi ?

Wed Nov 28, 2012 1:54 pm

No worries on the leds, I will be hooking them direct to the mini-itx board to get power and hard drive activity.

Altairst8te74
Posts: 23
Joined: Mon Nov 19, 2012 10:08 pm

Re: Raspberry 500 / Amiga Pi ?

Thu Nov 29, 2012 1:23 pm

I have some spare time today so my leonardo and a500 keyboard are hooked up. I ran into problems with the usb lead that was supplied, I so much as breathe on it things go awol. So I fished out a decent one from my lg phone.

I have confirmed the leonardo seems to be working with the Blink test sketch.

So I hooked up the keyboard and then went to upload the a500 sketch. The uploader program flags this:

'class keyboard_'has no member named 'press 2'

then highlights this:

void loop() {
// Reset
if (digitalRead(A500RES)==LOW && state!=WAIT_RES) {
digitalWrite(LED_B,LOW);
interrupts();
Keyboard.press2(0x4C,0x05);
delay(20);
Keyboard.release2(0x4C,0x05);
delay(20);
fn=false;
lkey=1000;
state=WAIT_RES;

I feel like im missing something obvious...

thradtke
Posts: 492
Joined: Wed May 16, 2012 5:16 am
Location: Germany / EL

Re: Raspberry 500 / Amiga Pi ?

Thu Nov 29, 2012 1:49 pm

Yes, those methods/members are to be defined in HID.cpp (you probably already did this) and declared in USBAPI.h. Please read especially Wizards posts in this thread about this.
Rocket Scientist.

Altairst8te74
Posts: 23
Joined: Mon Nov 19, 2012 10:08 pm

Re: Raspberry 500 / Amiga Pi ?

Sat Dec 01, 2012 4:05 am

Finally I have a working a500 keyboard thanks to you guys :)

Silly little things like me not putting files in the correct places led to me tearing my hair out trying to verify and compile stuff.

Then I traced my wiring and found the data and clock were reversed lol, kept getting errors with usb device not recognised, at least I did not fry the leonardo.

So it now works thanks to thradtke and wizard! but I want a bit more speed, I am probably asking for too much seeing how things have to be collected and read but I seem to bog things down when typing? I type a line of text and it will catch up seconds later. But all in all the fact that it works is just great.

I can start moving along with the a500 build im doing.
I have a dead c64 sitting in the corner aswell... very tempted to put a pi board in that!
:)

thradtke
Posts: 492
Joined: Wed May 16, 2012 5:16 am
Location: Germany / EL

Re: Raspberry 500 / Amiga Pi ?

Sat Dec 01, 2012 9:21 am

Glad you made it :-)

The protocol requires a handshake of 85ms, that's where the delay comes from. Dunno how it was on the A500, never owned a working one and hardly remember my A1000 times. You can probably lower the handshake time - try it and report back!

Unfortunately, the reference manuals aren't consistent in CLK and Signal, I think it was the wiring scheme where the bug is. I know from my own experience that mixing that up doesn't fry the Arduino.

Have lots of fun with it!
Rocket Scientist.

User avatar
Wizard
Posts: 120
Joined: Sun Aug 19, 2012 4:52 am
Location: Sweden

Re: Raspberry 500 / Amiga Pi ?

Sat Dec 01, 2012 11:38 am

A few ms can probably be shaved off but I'll consult my Amiga Hardware Reference Manual later tonight. (The blue Amiga bible!!!)

Here you'll find the files for Arduino 1.5
Make sure you put the correct files where they should be.

sam files:
http://arrendegarden.se/raspi/USBAPI.h
http://arrendegarden.se/raspi/HID.cpp

avr files:
http://arrendegarden.se/raspi/avr/USBAPI.h
http://arrendegarden.se/raspi/avr/HID.cpp

This'll enable thradtkes new methods for both Leonardo etc and the new DUE.

These files will not work with Arduino 1.0.1

As already stated by thradtke, do NOT connect the two diodes on the keybord to your Arduino. There is separate info how to wire those up.

The original A500 keyboard also had a lag whilst typing. In fact most computers had it back then.
Remember, the original PAL version of Amiga ran something like 7.14 MHz which is a lot less than an Arduino ;)

Happy tinkering!
Raspberry Pi - finally a worthy replacement for A500!!!

Altairst8te74
Posts: 23
Joined: Mon Nov 19, 2012 10:08 pm

Re: Raspberry 500 / Amiga Pi ?

Sat Dec 01, 2012 7:38 pm

:)

I picked up a working a500 in need of some love. I did start cleaning it all up back in march, the disk drive was in a real grotty mess. Anyway I will crack on and finish that one and try out the keyboard. It has been along time since I had a working a500, my first amiga was an a500 1.3 with the ecs chipset back in the early 1990's. Sort of a cut down a500plus and I did the 1meg chip ram hack. Should never have sold that one :(

Then after that it has been the amiga 1200 ever since and I guess the keyboard side of that works better.

Next up its joystick time and a few tweaks on the speed so yes I will be having fun :D

User avatar
olaf
Posts: 11
Joined: Sat Nov 03, 2012 3:01 pm
Location: Germany, Friesland
Contact: Website

Re: Raspberry 500 / Amiga Pi ?

Wed Dec 05, 2012 10:16 pm

Hi,
I replaced the "digitalRead" calls with "PINB" and lowered the handshake time to 10ms.
It still runs fine with no problems and it's incredible fast! (1ms also works).

I also added a second joystick button:

Code: Select all

//   Commodore /  Atari Joystick 1

	0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
	0x09, 0x05,                    // USAGE (Game Pad)
	0xa1, 0x01,                    // COLLECTION (Application)
	0x85, 0x03,                    //   REPORT_ID (3)
	0x09, 0x01,                    //   USAGE (Pointer)
	0xa1, 0x00,                    //   COLLECTION (Physical)
	0x09, 0x30,                    //     USAGE (X)
	0x09, 0x31,                    //     USAGE (Y)
	0x15, 0xff,                    //     LOGICAL_MINIMUM (-1)
	0x25, 0x01,                    //     LOGICAL_MAXIMUM (1)
	0x95, 0x02,                    //     REPORT_COUNT (2)
	0x75, 0x02,                    //     REPORT_SIZE (2) ; two bits to represent each axis
	0x81, 0x02,                    //     INPUT (Data,Var,Abs)
	0xc0,                          //   END_COLLECTION
	0x05, 0x09,                    //   USAGE_PAGE (Button)
	0x19, 0x01,                    //   USAGE_MINIMUM (Button 1)
	0x29, 0x01,                    //   USAGE_MAXIMUM (Button 1)
	0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
	0x25, 0x01,                    //   LOGICAL_MAXIMUM (1)
	0x95, 0x01,                    //   REPORT_COUNT (1) ; 1 button
	0x75, 0x01,                    //   REPORT_SIZE (1)
	0x81, 0x02,                    //   INPUT (Data,Var,Abs)
	0x95, 0x02,                    //	REPORT_COUNT (2) ; to pad out the bits into a number divisible by 8
	0x81, 0x03,                    //   INPUT (Const,Var,Abs)
    0x05, 0x09,                    //   USAGE_PAGE (Button)
	0x19, 0x02,                    //   USAGE_MINIMUM (Button 2)
	0x29, 0x02,                    //   USAGE_MAXIMUM (Button 2)
	0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
	0x25, 0x01,                    //   LOGICAL_MAXIMUM (1)
	0x95, 0x01,                    //   REPORT_COUNT (1) ; 1 button
	0x75, 0x01,                    //   REPORT_SIZE (1)
	0x81, 0x02,                    //   INPUT (Data,Var,Abs)
	0xc0,                          // END_COLLECTION
 
//   Commodore /  Atari Joystick 2

	0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
	0x09, 0x05,                    // USAGE (Game Pad)
	0xa1, 0x01,                    // COLLECTION (Application)
	0x85, 0x04,                    //   REPORT_ID (4)
 	0xa1, 0x00,                    //   COLLECTION (Physical)	
	0x05, 0x09,                    //   USAGE_PAGE (Button)
	0x19, 0x01,                    //   USAGE_MINIMUM (Button 1)
	0x29, 0x02,                    //   USAGE_MAXIMUM (Button 2)
	0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
	0x25, 0x01,                    //   LOGICAL_MAXIMUM (1)
	0x95, 0x02,                    //   REPORT_COUNT (2) ; 2 buttons
	0x75, 0x01,                    //   REPORT_SIZE (1)
	0x81, 0x02,                    //   INPUT (Data,Var,Abs)
 	0x95, 0x02,                    //	REPORT_COUNT (2) ; to pad out the bits into a number divisible by 8
	0x81, 0x03,                    //   INPUT (Const,Var,Abs)
    0x05, 0x01,                    //     USAGE_PAGE (Generic Desktop)
	0x09, 0x30,                    //     USAGE (X)
	0x09, 0x31,                    //     USAGE (Y)
	0x15, 0xff,                    //     LOGICAL_MINIMUM (-1)
	0x25, 0x01,                    //     LOGICAL_MAXIMUM (1)
	0x95, 0x02,                    //     REPORT_COUNT (2)
	0x75, 0x02,                    //     REPORT_SIZE (2) ; two bits to represent each axis
	0x81, 0x02,                    //     INPUT (Data,Var,Abs)
	0xc0,                          //   END_COLLECTION
	0xc0                           // END_COLLECTION	 

};
here's my complete sketch (notice that I disabled the LEDs and changed ALT,CTRL and AMIGA keys to have the usual pc keyboard layout) :

Code: Select all

    #define A500CLK 8
    #define A500SP 9
    #define A500RES 10
    
    #define BITMASK_A500CLK 0b00010000
    #define BITMASK_A500SP 0b00100000
    #define BITMASK_A500RES 0b01000000
    
    //#define LED_A 11
    //#define LED_B 12

    #define SYNCH_HI 1
    #define SYNCH_LO 2
    #define HANDSHAKE 4
    #define READ 16
    #define WAIT_LO 8
    #define WAIT_RES 64

    unsigned char state;
    signed char bitn=-1;
    long counter;
    unsigned short key,lkey=1000;
    byte mode, fn, caps=0, num=0, scroll=0;

    // normal layout
    unsigned char ktab1[]={
      // Tilde, 1-9, 0, sz, Accent, backslash, Num 0 (00 - 0F)
      0x35, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x2D, 0x2E, 0x31, 0, 0x62,
      // Q bis +, -, Num 1, Num 2, Num3 (10 - 1F)
      0x14, 0x1A, 0x08, 0x15, 0x17, 0x1C, 0x18, 0x0C, 0x12, 0x13, 0x2F, 0x30, 0, 0x59, 0x5A, 0x5B,
      // A-#, -, Num 4, Num 5, Num 6 (20 - 2F)
      0x04, 0x16, 0x07, 0x09, 0x0A, 0x0B, 0x0D, 0x0E, 0x0F, 0x33, 0x34, 0x32, 0, 0x5C, 0x5D, 0x5E,
      // <>,Y- -, -, Num . , Num 7, Num 8, Num 9 (30 - 3F)
      0x64 , 0x1D, 0x1B, 0x06, 0x19, 0x05, 0x11, 0x10, 0x36, 0x37, 0x38, 0, 0x63, 0x5F, 0x60, 0x61,
      // Space, BS, Tab, Enter, Return, ESC, Del, -, -, -, Num -, -, up, down, right, left (40 - 4F)
      0x2C, 0x2A, 0x2B, 0x58, 0x28, 0x29, 0x4C, 0, 0, 0, 0x56, 0, 0x52, 0x51, 0x4F, 0x50,
      // F1-F10, -, -, Num /, Num *, Num +, - (50 - 5F)
      0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0, 0, 0x54, 0x55, 0x57, 0x3A
    };

    // num-lock layout
    unsigned char ktab2[]={
      // Tilde, 1-9, 0, sz, Accent, backslash, Num 0 (00 - 0F)
      0x35, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x2D, 0x2E, 0x31, 0, 0x27,
      // Q bis +, -, Num 1, Num 2, Num3 (10 - 1F)
      0x14, 0x1A, 0x08, 0x15, 0x17, 0x1C, 0x18, 0x0C, 0x12, 0x13, 0x2F, 0x30, 0, 0x1E, 0x1F, 0x20,
      // A-#, -, Num 4, Num 5, Num 6 (20 - 2F)
      0x04, 0x16, 0x07, 0x09, 0x0A, 0x0B, 0x0D, 0x0E, 0x0F, 0x33, 0x34, 0x32, 0, 0x21, 0x22, 0x23,
      // <>,Y- -, -, Num . , Num 7, Num 8, Num 9 (30 - 3F)
      0x64 , 0x1D, 0x1B, 0x06, 0x19, 0x05, 0x11, 0x10, 0x36, 0x37, 0x38, 0, 0x37, 0x24, 0x25, 0x26,
      // Space, BS, Tab, Enter, Return, ESC, Del, -, -, -, Num -, -, up, down, right, left (40 - 4F)
      0x2C, 0x2A, 0x2B, 0x58, 0x28, 0x29, 0x4C, 0, 0, 0, 0x56, 0, 0x52, 0x51, 0x4F, 0x50,
      // F1-F10, -, -, Num /, Num *, Num +, - (50 - 5F)
      0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0, 0, 0x54, 0x55, 0x57, 0x3A
    };
    unsigned char *ktab;
    
    uint8_t Joy;
    uint8_t MemoJoy1 ;
    uint8_t MemoJoy2 ;

    void setup() { 

      // Joystick 1
      pinMode(0, INPUT_PULLUP);
      pinMode(1, INPUT_PULLUP);
      pinMode(2, INPUT_PULLUP);
      pinMode(3, INPUT_PULLUP);
      pinMode(4, INPUT_PULLUP);
      pinMode(6, INPUT_PULLUP);
      
      // Joystick 2
      pinMode(A0, INPUT_PULLUP);
      pinMode(A1, INPUT_PULLUP);
      pinMode(A2, INPUT_PULLUP);
      pinMode(A3, INPUT_PULLUP);
      pinMode(A4, INPUT_PULLUP);
      pinMode(A5, INPUT_PULLUP);      

      // Keyboard
      pinMode(A500CLK, INPUT);
      pinMode(A500SP, INPUT);
      pinMode(A500RES, INPUT);
      //pinMode(LED_A, OUTPUT);
      //pinMode(LED_B, OUTPUT);
      digitalWrite(A500SP, LOW);
      state=SYNCH_HI;
      counter=0;
      ktab=ktab1;
      Keyboard.begin();
    }

    void loop() {

            // Joystick 1
            Joy = ~PIND & 0b10011111;
            if (Joy != MemoJoy1) {
              HID_SendReport(3, &Joy, 1);
              MemoJoy1 = Joy;
            }  

           // Joystick 2
            Joy = ~PINF & 0b11110011;
            if (Joy != MemoJoy2) {
              HID_SendReport(4, &Joy, 1);
              MemoJoy2 = Joy;
            }  
      
      // Reset
//      if (digitalRead(A500RES)==LOW && state!=WAIT_RES) {
        if (((PINB & BITMASK_A500RES)==0) && state!=WAIT_RES) {
        //digitalWrite(LED_B,LOW);
        interrupts();
        Keyboard.press2(0x4C,0x05);
        delay(20);
        Keyboard.release2(0x4C,0x05);
        delay(20);
        fn=false;
        lkey=1000;
        state=WAIT_RES;
      }
      // Warten Reset Ende
      else if (state==WAIT_RES) {
//      if (digitalRead(A500RES)==HIGH) state=SYNCH_HI;
        if ((PINB & BITMASK_A500RES)!=0) state=SYNCH_HI;
      }
      // Synch-Puls
      else if (state==SYNCH_HI) {
//      if (digitalRead(A500CLK)==LOW) {
        if ((PINB & BITMASK_A500CLK)==0) {
          state=SYNCH_LO;
        }
      }
      else if (state==SYNCH_LO) {
//      if (digitalRead(A500CLK)==HIGH) {
        if ((PINB & BITMASK_A500CLK)!=0) {
          //digitalWrite(LED_B,HIGH);
          state=HANDSHAKE;
        }
      }
      else if (state==HANDSHAKE) {
        if (counter==0) {
          pinMode(A500SP, OUTPUT);
          digitalWrite(A500SP,LOW);
          counter=millis();
        }
        else if (millis()-counter>10) {
          counter=0;
          pinMode(A500SP, INPUT);
          digitalWrite(A500SP, HIGH);
          state=WAIT_LO;
          key=0;
          bitn=7;
        }
      }
      else if (state==READ) {
//        if (digitalRead(A500CLK)==HIGH) {
        if ((PINB & BITMASK_A500CLK)!=0) {  

          // add bit
//          key+=(!digitalRead(A500SP))<<(bitn?bitn-1:7);
          key+=((PINB & BITMASK_A500SP)==0)<<(bitn?bitn-1:7);

          // all bits read
          if (--bitn<0) {
            interrupts();
            state=HANDSHAKE;
           
            if (key==lkey) {
            }
            else {
              lkey=key;

              switch (key) {
              //case 0x63:  // Control left
                case 0x64:  // Alt left
                mode|=0x01;
                break;
              //case 0xE3:
                case 0xE4:
                mode&=0xFE;
                break;
              //case 0x67:  // Control right (Amiga right)
              case 0x65:  // Alt right
                mode|=0x10;
                break;
              //case 0xE7:
                case 0xE5:
                mode&=0xEF;
                break;
              //case 0x64:  // Alt left
                case 0x66:  // left amiga
                mode|=0x04;
                break;
              //case 0xE4:
                case 0xE6:
                mode&=0xFB;
                break;
              //case 0x65:  // Alt right
              case 0x67:  // Control right (Amiga right)
                mode|=0x40;
                break;
              //case 0xE5:
              case 0xE7:
                mode&=0xBF;
                break;
              case 0x60:  // Shift left
                mode|=0x02;
                break;
              case 0xE0:
                mode&=0xFD;
                break;
              case 0x61:  // Shift right
                mode|=0x20;
                break;
              case 0xE1:
                mode&=0xDF;
                break;
            //  case 0x66:  // left amiga / FN
              case 0x63:  // Control left
                fn=true;
                break;
              //case 0xE6:
                case 0xE3:
                fn=false;
                break;
              default:
                // left Amiga
                if (fn) {
                  // F11-F12
                  if (key==0x50) {
                    Keyboard.press2(0x44,0);
                    Keyboard.release2(0x44,0);
                  }
                  else if (key==0x51) {
                    Keyboard.press2(0x45,0);
                    Keyboard.release2(0x45,0);
                  }
                  // NumLock
                  else if (key==0x5A) {
                    num^=1;
                    if (num) {
                      //digitalWrite(LED_A, HIGH);
                      ktab=ktab2;
                    }
                    else {
                      ktab=ktab1;
                      //digitalWrite(LED_A, LOW);
                    }
                  }
                  // At
                  else if (key==0x02) {
                    Keyboard.press2(0x14,0x40);
                    Keyboard.release2(0x14,0x40);
                  }
                  // Grad
                  else if (key==0x04) {
                    Keyboard.press2(0x35,0x40);
                    Keyboard.release2(0x35,0x40);
                  }
                }
                // CapsLock
                else if (key==0x62) {
                  caps=0x02;
                }
                else if (key==0xE2) {
                  caps=0;
                }
               
                else if (key==0x00) {
                  if (mode&0x02 || mode&0x20) {
                    // Tilde
                    Keyboard.press2(0x30,0x40);
                    Keyboard.release2(0x30,0x40);
                  }
                  else {
                    // Apostroph
                    Keyboard.press2(0x32,0x20);
                    Keyboard.release2(0x32,0x20);
                  }
                }
               
                // Backslash and Seperator
                else if (key==0x0D) {
                  if (mode&0x02 || mode&0x20) {
                    Keyboard.press2(0x64,0x40);
                    Keyboard.release2(0x64,0x40);
                  }
                  else {
                    Keyboard.press2(0x2D,0x40);
                    Keyboard.release2(0x2D,0x40);
                  }
                }
                // Dach
                else if (key==0x2B && (mode&0x02 || mode&0x20)) {
                  Keyboard.press2(0x35,0);
                  Keyboard.release2(0x35,0);
                }
                // [ {
                else if (key==0x5A) {
                  if (mode&0x02 || mode&0x20) {
                    Keyboard.press2(0x24,0x40);
                    Keyboard.release2(0x24,0x40);
                  }
                  else {
                    Keyboard.press2(0x25,0x40);
                    Keyboard.release2(0x25,0x40);
                  }
                }
                // ] }
                else if (key==0x5B) {
                  if (mode&0x02 || mode&0x20) {
                    Keyboard.press2(0x27,0x40);
                    Keyboard.release2(0x27,0x40);
                  }
                  else {
                    Keyboard.press2(0x26,0x40);
                    Keyboard.release2(0x26,0x40);
                  }
                }
     
                // Tabelle
                else if (((byte)key&0x7F)<0x60) {
                 
                  if (((byte)key&0x80)==0x80) Keyboard.release2(ktab[(byte)key&0x7F],mode|caps);
                  else Keyboard.press2(ktab[key],mode|caps);
                }
               
                // Fehler (keyboard)
                else if (key==0xF9) {
                  mode=0;
                  Keyboard.releaseAll();
                }
                else if (key==0xFD) {
                  mode=0;
                  Keyboard.releaseAll();
                }
                break;
              }
            }
            key=0;
          }
          else state=WAIT_LO;
          
        }
      }
      else if (state==WAIT_LO) {
//      if (digitalRead(A500CLK)==LOW) {
        if ((PINB & BITMASK_A500CLK)==0) {
          noInterrupts();
          state=READ;
        }
      }
    }
    
cheers
Olaf
Dipl. Ing. (FH) Olaf Berthold Hardware- und Softwareentwicklung
www.olafberthold.de . . . . www.canhack.de . . . . www.cpos-online.de

User avatar
Wizard
Posts: 120
Joined: Sun Aug 19, 2012 4:52 am
Location: Sweden

Re: Raspberry 500 / Amiga Pi ?

Wed Dec 05, 2012 11:09 pm

olaf wrote:Hi,
I replaced the "digitalRead" calls with "PINB" and lowered the handshake time to 10ms.
It still runs fine with no problems and it's incredible fast! (1ms also works).

snip

cheers
Olaf
Nicely done there Olaf! :)
Raspberry Pi - finally a worthy replacement for A500!!!

Altairst8te74
Posts: 23
Joined: Mon Nov 19, 2012 10:08 pm

Re: Raspberry 500 / Amiga Pi ?

Thu Dec 06, 2012 6:36 pm

Wow Olaf, thank you very much :D

I shall be testing it out asap! I need to get the joystick ports mounted into the back somehow... I have my hot glue gun at the ready lol.

Altairst8te74
Posts: 23
Joined: Mon Nov 19, 2012 10:08 pm

Re: Raspberry 500 / Amiga Pi ?

Thu Dec 13, 2012 2:00 pm

Can somebody please confirm if this will work at the bios level on a pc? I have been putting this together on a netbook and I could not get into the bios using the amiga keyboard.

I have yet to test it on a proper motherboard.

Thanks :)

Return to “Other projects”