Revision 275
Added by markw almost 11 years ago
| firmware/usb/usb.h | ||
|---|---|---|
| 
     //#include <stdbool.h>
 
   | 
||
| 
     | 
||
| 
     #include "common/integer.h"
 
   | 
||
| 
     #include "timer.h"
 
   | 
||
| 
     | 
||
| 
     /* NAK powers. To save space in endpoint data structure, amount of retries */
 
   | 
||
| 
     /* before giving up and returning 0x4 is stored in bmNakPower as a power of 2.*/
 
   | 
||
| ... | ... | |
| 
         } __attribute__((packed));
 
   | 
||
| 
       } __attribute__((packed)) ReqType_u;
 
   | 
||
| 
       uint8_t    bRequest;		   //   1      Request
 
   | 
||
| 
       union {
 
   | 
||
| 
         uint16_t    wValue;            //   2/3    Depends on bRequest
 
   | 
||
| 
         struct {
 
   | 
||
| 
           uint8_t    wValueLo;
 
   | 
||
| 
           uint8_t    wValueHi;
 
   | 
||
| 
         } __attribute__((packed));
 
   | 
||
| 
       }  __attribute__((packed)) wVal_u;
 
   | 
||
| 
       uint16_t    wIndex;              //   4      Depends on bRequest
 
   | 
||
| 
       uint16_t    wLength;             //   6      Depends on bRequest
 
   | 
||
| 
       uint8_t    wValueL;
 
   | 
||
| 
       uint8_t    wValueH;
 
   | 
||
| 
       uint8_t    wIndexL;              //   4      Depends on bRequest
 
   | 
||
| 
       uint8_t    wIndexH;              //   5      Depends on bRequest
 
   | 
||
| 
       uint8_t    wLengthL;             //   6      Depends on bRequest
 
   | 
||
| 
       uint8_t    wLengthH;             //   7      Depends on bRequest
 
   | 
||
| 
     } __attribute__((packed)) setup_pkt_t;
 
   | 
||
| 
     | 
||
| 
     // Additional Error Codes
 
   | 
||
| ... | ... | |
| 
       uint8_t parent;                          // parent device address
 
   | 
||
| 
       uint8_t port;
 
   | 
||
| 
       bool lowspeed;
 
   | 
||
| 
       char volatile * host_addr;
 
   | 
||
| 
     | 
||
| 
       union {
 
   | 
||
| 
         usb_hub_info_t hub_info;
 
   | 
||
| ... | ... | |
| 
       };
 
   | 
||
| 
     } usb_device_t;
 
   | 
||
| 
     | 
||
| 
     struct usb_host
 
   | 
||
| 
     {
 
   | 
||
| 
     	uint8_t usb_task_state;
 
   | 
||
| 
             unsigned char * addr;
 
   | 
||
| 
             msec_t poll;
 
   | 
||
| 
             msec_t delay;
 
   | 
||
| 
     };
 
   | 
||
| 
     | 
||
| 
     #define USB_CLASS_USE_CLASS_INFO          0x00    // Use Class Info in the Interface Descriptors
 
   | 
||
| 
     #define USB_CLASS_AUDIO                   0x01    // Audio
 
   | 
||
| 
     #define USB_CLASS_COM_AND_CDC_CTRL        0x02    // Communications and CDC Control
 
   | 
||
| ... | ... | |
| 
     typedef struct {
 
   | 
||
| 
       uint8_t  bLength;            // Length of this descriptor.
 
   | 
||
| 
       uint8_t  bDescriptorType;    // DEVICE descriptor type (USB_DESCRIPTOR_DEVICE).
 
   | 
||
| 
       uint16_t bcdUSB;	       // USB Spec Release Number (BCD).
 
   | 
||
| 
       uint8_t bcdUSBL;	       // USB Spec Release Number (BCD).
 
   | 
||
| 
       uint8_t bcdUSBH;	       // USB Spec Release Number (BCD).
 
   | 
||
| 
       uint8_t  bDeviceClass;       // Class code (assigned by the USB-IF). 0xFF-Vendor specific.
 
   | 
||
| 
       uint8_t  bDeviceSubClass;    // Subclass code (assigned by the USB-IF).
 
   | 
||
| 
       uint8_t  bDeviceProtocol;    // Protocol code (assigned by the USB-IF). 0xFF-Vendor specific.
 
   | 
||
| 
       uint8_t  bMaxPacketSize0;    // Maximum packet size for endpoint 0.
 
   | 
||
| 
       uint16_t idVendor;	       // Vendor ID (assigned by the USB-IF).
 
   | 
||
| 
       uint16_t idProduct;	       // Product ID (assigned by the manufacturer).
 
   | 
||
| 
       uint16_t bcdDevice;	       // Device release number (BCD).
 
   | 
||
| 
       uint8_t idVendorL;	       // Vendor ID (assigned by the USB-IF).
 
   | 
||
| 
       uint8_t idVendorH;	       // Vendor ID (assigned by the USB-IF).
 
   | 
||
| 
       uint8_t idProductL;	       // Product ID (assigned by the manufacturer).
 
   | 
||
| 
       uint8_t idProductH;	       // Product ID (assigned by the manufacturer).
 
   | 
||
| 
       uint8_t bcdDeviceL;	       // Device release number (BCD).
 
   | 
||
| 
       uint8_t bcdDeviceH;	       // Device release number (BCD).
 
   | 
||
| 
       uint8_t  iManufacturer;      // Index of String Descriptor describing the manufacturer.
 
   | 
||
| 
       uint8_t  iProduct;           // Index of String Descriptor describing the product.
 
   | 
||
| 
       uint8_t  iSerialNumber;      // Index of String Descriptor with the device's serial number.
 
   | 
||
| ... | ... | |
| 
     typedef struct {
 
   | 
||
| 
       uint8_t bLength;             // Length of this descriptor.
 
   | 
||
| 
       uint8_t bDescriptorType;     // CONFIGURATION descriptor type (USB_DESCRIPTOR_CONFIGURATION).
 
   | 
||
| 
       uint16_t wTotalLength;       // Total length of all descriptors for this configuration.
 
   | 
||
| 
       uint8_t wTotalLengthL;       // Total length of all descriptors for this configuration.
 
   | 
||
| 
       uint8_t wTotalLengthH;       // Total length of all descriptors for this configuration.
 
   | 
||
| 
       uint8_t bNumInterfaces;      // Number of interfaces in this configuration.
 
   | 
||
| 
       uint8_t bConfigurationValue; // Value of this configuration (1 based).
 
   | 
||
| 
       uint8_t iConfiguration;      // Index of String Descriptor describing the configuration.
 
   | 
||
| ... | ... | |
| 
     #define USB_DESCRIPTOR_OTHER_SPEED      0x07    // bDescriptorType for a Other Speed Configuration.
 
   | 
||
| 
     #define USB_DESCRIPTOR_INTERFACE_POWER  0x08    // bDescriptorType for Interface Power.
 
   | 
||
| 
     | 
||
| 
     void usb_init();
 
   | 
||
| 
     void usb_poll();
 
   | 
||
| 
     void usb_SetHubPreMask(void);
 
   | 
||
| 
     void usb_ResetHubPreMask(void);
 
   | 
||
| 
     void usb_init(struct usb_host * host, int portnumber);
 
   | 
||
| 
     void usb_poll(struct usb_host * host);
 
   | 
||
| 
     | 
||
| 
     uint8_t usb_set_addr( usb_device_t *, uint8_t );
 
   | 
||
| 
     uint8_t usb_ctrl_req( usb_device_t *, uint8_t bmReqType, 
 
   | 
||
| firmware/Makefile | ||
|---|---|---|
| 
     DE1_5200_DIR = de1_5200
 
   | 
||
| 
     CHAMELEON_DIR = chameleon
 
   | 
||
| 
     MCC_DIR = mcc
 
   | 
||
| 
     MCCTV_DIR = mcctv
 
   | 
||
| 
     MIST_DIR = mist
 
   | 
||
| 
     MIST_5200_DIR = mist_5200
 
   | 
||
| 
     LINUXSIM_DIR = linux
 
   | 
||
| ... | ... | |
| 
     DE1_5200_BUILD_DIR = $(BUILD_DIR)/$(DE1_5200_DIR)
 
   | 
||
| 
     CHAMELEON_BUILD_DIR = $(BUILD_DIR)/$(CHAMELEON_DIR)
 
   | 
||
| 
     MCC_BUILD_DIR = $(BUILD_DIR)/$(MCC_DIR)
 
   | 
||
| 
     MCCTV_BUILD_DIR = $(BUILD_DIR)/$(MCCTV_DIR)
 
   | 
||
| 
     MIST_BUILD_DIR = $(BUILD_DIR)/$(MIST_DIR)
 
   | 
||
| 
     MIST_5200_BUILD_DIR = $(BUILD_DIR)/$(MIST_5200_DIR)
 
   | 
||
| 
     LINUXSIM_BUILD_DIR = $(BUILD_DIR)/$(LINUXSIM_DIR)
 
   | 
||
| ... | ... | |
| 
     A800_SRC = ${A800_SRC_LIGHT} a800/joystick.c libgcc_divmod.c
 
   | 
||
| 
     5200_SRC_LIGHT = 5200/freeze.c  5200/mainmenu.c
 
   | 
||
| 
     5200_SRC = ${5200_SRC_LIGHT} 5200/joystick.c
 
   | 
||
| 
     USB_SRC = usb/hid.c  usb/hidparser.c  usb/hub.c usb/timer.c  usb/usb.c
 
   | 
||
| 
     | 
||
| 
     AEON_LITE_PRJ = AEON_LITE
 
   | 
||
| 
     AEON_LITE_SRC = $(COMMON_SRC) $(SDCARD_SRC) $(A800_SRC) de1/dirs.c
 
   | 
||
| ... | ... | |
| 
     CHAMELEON_OBJ = $(patsubst %.c,$(CHAMELEON_BUILD_DIR)/%.o,$(CHAMELEON_SRC))
 
   | 
||
| 
     | 
||
| 
     MCC_PRJ = MCC216
 
   | 
||
| 
     MCC_SRC = $(COMMON_SRC) $(SDCARD_SRC) $(A800_SRC) mcc/dirs.c
 
   | 
||
| 
     MCC_SRC = $(COMMON_SRC) $(SDCARD_SRC) $(A800_SRC) $(USB_SRC) mcc/dirs.c
 
   | 
||
| 
     #MCC_SRC = $(COMMON_SRC) $(SDCARD_SRC) $(A800_SRC) mcc/dirs.c
 
   | 
||
| 
     MCC_OBJ = $(patsubst %.c,$(MCC_BUILD_DIR)/%.o,$(MCC_SRC))
 
   | 
||
| 
     | 
||
| 
     MCCTV_PRJ = MCCTV
 
   | 
||
| 
     MCCTV_SRC = $(COMMON_SRC) $(SDCARD_SRC) $(A800_SRC) $(USB_SRC) mcc/dirs.c
 
   | 
||
| 
     #MCCTV_SRC = $(COMMON_SRC) $(SDCARD_SRC) $(A800_SRC) mcc/dirs.c
 
   | 
||
| 
     MCCTV_OBJ = $(patsubst %.c,$(MCCTV_BUILD_DIR)/%.o,$(MCCTV_SRC))
 
   | 
||
| 
     | 
||
| 
     MIST_PRJ = MIST
 
   | 
||
| 
     MIST_SRC = $(COMMON_SRC) $(SDCARD_SRC) $(A800_SRC) mist/dirs.c
 
   | 
||
| 
     MIST_OBJ = $(patsubst %.c,$(MIST_BUILD_DIR)/%.o,$(MIST_SRC))
 
   | 
||
| ... | ... | |
| 
     MIST_5200_OBJ = $(patsubst %.c,$(MIST_5200_BUILD_DIR)/%.o,$(MIST_5200_SRC))
 
   | 
||
| 
     | 
||
| 
     LINKMAP  = ./standalone_simple.ld
 
   | 
||
| 
     LINKMAP_LARGE  = ./standalone_simple_large.ld
 
   | 
||
| 
     | 
||
| 
     LINUXSIM_EXE	= linuxsim
 
   | 
||
| 
     LINUXSIM_SRC	= $(COMMON_SRC) $(A800_SRC_LIGHT) linux/main.c linux/mmc.c \
 
   | 
||
| 
     LINUXSIM_SRC	= $(COMMON_SRC) $(A800_SRC_LIGHT) $(USB_SRC) linux/main.c linux/mmc.c \
 
   | 
||
| 
     	sd_direct/diskio_mmc.c linux/dirs.c linux/linux_memory.c linux/curses_screen.c \
 
   | 
||
| 
     	linux/linux_helper.c
 
   | 
||
| 
     	linux/linux_helper.c linux/emulate_usb.c
 
   | 
||
| 
     | 
||
| 
     LINUXSIM_5200_EXE	= linuxsim_5200
 
   | 
||
| 
     LINUXSIM_5200_SRC	= $(COMMON_SRC) $(5200_SRC_LIGHT) linux/main.c linux/mmc.c \
 
   | 
||
| ... | ... | |
| 
     ZPUOPTS =
 
   | 
||
| 
     CFLAGS  = -I. -Isd_direct -Iprintf -Ifat -Icommon -Isdram_common -c -g -Os $(ZPUOPTS) -DDISABLE_UART_RX
 
   | 
||
| 
     | 
||
| 
     HOST_CFLAGS += -I. -Isd_direct -Iprintf -Ifat -Icommon -Isdram_common -DDISABLE_UART_RX
 
   | 
||
| 
     HOST_CFLAGS += -I. -Isd_direct -Iprintf -Ifat -Icommon -Isdram_common -DDISABLE_UART_RX -DUSB -Iusb
 
   | 
||
| 
     | 
||
| 
     LFLAGS  = -nostartfiles -nostdlib -Wl,--relax -g -Os -Wl,-Map=out.map
 
   | 
||
| 
     LFLAGS_5200  = -nostartfiles -Wl,--relax -g -Os -Wl,-Map=out.map
 
   | 
||
| 
     #LFLAGS  = -nostartfiles -Os
 
   | 
||
| 
     | 
||
| 
     CFLAGS_USB = $(CFLAGS) -DUSB -Iusb
 
   | 
||
| 
     CFLAGS_USB2 = $(CFLAGS) -DUSB -DUSB2 -Iusb
 
   | 
||
| 
     CFLAGS_5200 = $(CFLAGS) -DFIRMWARE_5200
 
   | 
||
| 
     HOST_CFLAGS_5200 = $(HOST_CFLAGS) -DFIRMWARE_5200
 
   | 
||
| 
     | 
||
| 
     # Our target.
 
   | 
||
| 
     all: mcc mist de1 aeon_lite chameleon  de1_5200 mist_5200
 
   | 
||
| 
     all: mcc mcctv mist de1 aeon_lite chameleon  de1_5200 mist_5200
 
   | 
||
| 
     | 
||
| 
     install:
 
   | 
||
| 
     	cd ../common/romgen && ./createall && cd ../../firmware
 
   | 
||
| ... | ... | |
| 
     | 
||
| 
     mcc: $(BUILD_DIR) $(MCC_PRJ).bin $(MCC_PRJ).rpt
 
   | 
||
| 
     | 
||
| 
     mcctv: $(BUILD_DIR) $(MCCTV_PRJ).bin $(MCCTV_PRJ).rpt
 
   | 
||
| 
     | 
||
| 
     mist: $(BUILD_DIR) $(MIST_PRJ).bin $(MIST_PRJ).rpt
 
   | 
||
| 
     | 
||
| 
     mist_5200: $(BUILD_DIR) $(MIST_5200_PRJ).bin $(MIST_5200_PRJ).rpt
 
   | 
||
| ... | ... | |
| 
     	$(LD) $(LFLAGS) -T $(LINKMAP) -o $@ $+ $(LIBS)
 
   | 
||
| 
     | 
||
| 
     $(MCC_PRJ).elf: $(MINSTARTUP_OBJ) $(MCC_OBJ)
 
   | 
||
| 
     	$(LD) $(LFLAGS) -T $(LINKMAP) -o $@ $+ $(LIBS)
 
   | 
||
| 
     	$(LD) $(LFLAGS) -T $(LINKMAP_LARGE) -o $@ $+ $(LIBS)
 
   | 
||
| 
     #	$(LD) $(LFLAGS) -T $(LINKMAP) -o $@ $+ $(LIBS)
 
   | 
||
| 
     | 
||
| 
     $(MCCTV_PRJ).elf: $(MINSTARTUP_OBJ) $(MCCTV_OBJ)
 
   | 
||
| 
     	$(LD) $(LFLAGS) -T $(LINKMAP_LARGE) -o $@ $+ $(LIBS)
 
   | 
||
| 
     | 
||
| 
     $(MIST_PRJ).elf: $(MINSTARTUP_OBJ) $(MIST_OBJ)
 
   | 
||
| 
     	$(LD) $(LFLAGS) -T $(LINKMAP) -o $@ $+ $(LIBS)
 
   | 
||
| 
     | 
||
| ... | ... | |
| 
     | 
||
| 
     $(MCC_BUILD_DIR)/%.o: %.c Makefile
 
   | 
||
| 
     	mkdir -p `dirname $@`
 
   | 
||
| 
     	$(CC) -I$(MCC_DIR) $(CFLAGS)  -o $@ -c $<
 
   | 
||
| 
     	$(CC) -I$(MCC_DIR) $(CFLAGS_USB)  -o $@ -c $<
 
   | 
||
| 
     | 
||
| 
     $(MCCTV_BUILD_DIR)/%.o: %.c Makefile
 
   | 
||
| 
     	mkdir -p `dirname $@`
 
   | 
||
| 
     	$(CC) -I$(MCCTV_DIR) $(CFLAGS_USB2)  -o $@ -c $<
 
   | 
||
| 
     | 
||
| 
     $(MIST_BUILD_DIR)/%.o: %.c Makefile
 
   | 
||
| 
     	mkdir -p `dirname $@`
 
   | 
||
| 
     	$(CC) -I$(MIST_DIR) $(CFLAGS)  -o $@ -c $<
 
   | 
||
| firmware/a800/joystick.c | ||
|---|---|---|
| 
     | 
||
| 
     //#include <stdio.h>
 
   | 
||
| 
     | 
||
| 
     #ifdef USB
 
   | 
||
| 
     #include "usb.h"
 
   | 
||
| 
     #endif
 
   | 
||
| 
     | 
||
| 
     #ifdef USB
 
   | 
||
| 
     extern struct usb_host usb_porta;
 
   | 
||
| 
     #endif
 
   | 
||
| 
     #ifdef USB2
 
   | 
||
| 
     extern struct usb_host usb_portb;
 
   | 
||
| 
     #endif
 
   | 
||
| 
     | 
||
| 
     void joystick_poll(struct joystick_status * status)
 
   | 
||
| 
     {
 
   | 
||
| 
     	status->x_ = 0;
 
   | 
||
| ... | ... | |
| 
     	status->fire_ = 0;
 
   | 
||
| 
     	status->escape_ = 0;
 
   | 
||
| 
     | 
||
| 
     #ifdef USB
 
   | 
||
| 
     	usb_poll(&usb_porta);
 
   | 
||
| 
     #endif
 
   | 
||
| 
     #ifdef USB2
 
   | 
||
| 
     	usb_poll(&usb_portb);
 
   | 
||
| 
     #endif
 
   | 
||
| 
     | 
||
| 
     	unsigned char porta = *atari_porta;
 
   | 
||
| 
     | 
||
| 
     	int controls = get_controls();
 
   | 
||
| firmware/a800/mainmenu.c | ||
|---|---|---|
| 
     | 
||
| 
     unsigned char freezer_rom_present;
 
   | 
||
| 
     | 
||
| 
     #ifdef USB
 
   | 
||
| 
     #include "usb.h"
 
   | 
||
| 
     #endif
 
   | 
||
| 
     | 
||
| 
     void loadosrom()
 
   | 
||
| 
     {
 
   | 
||
| 
     	if (file_size(files[5]) == 0x4000)
 
   | 
||
| ... | ... | |
| 
     	}
 
   | 
||
| 
     }
 
   | 
||
| 
     | 
||
| 
     #ifdef USB
 
   | 
||
| 
     struct usb_host usb_porta;
 
   | 
||
| 
     #endif
 
   | 
||
| 
     #ifdef USB2
 
   | 
||
| 
     struct usb_host usb_portb;
 
   | 
||
| 
     #endif
 
   | 
||
| 
     | 
||
| 
     void mainmenu()
 
   | 
||
| 
     {
 
   | 
||
| 
     #ifdef USB
 
   | 
||
| 
     	usb_init(&usb_porta,0);
 
   | 
||
| 
     #endif
 
   | 
||
| 
     #ifdef USB2
 
   | 
||
| 
     	usb_init(&usb_portb,1);
 
   | 
||
| 
     #endif
 
   | 
||
| 
     	freezer_rom_present = 0;
 
   | 
||
| 
     	if (SimpleFile_OK == dir_init((void *)DIR_INIT_MEM, DIR_INIT_MEMSIZE))
 
   | 
||
| 
     	{
 
   | 
||
| ... | ... | |
| 
     		//printf("DIR init failed\n");
 
   | 
||
| 
     	}
 
   | 
||
| 
     	reboot(1);
 
   | 
||
| 
     	for (;;) actions();
 
   | 
||
| 
     	for (;;) actions(1);
 
   | 
||
| 
     }
 
   | 
||
| 
     | 
||
| 
     char const * get_ram()
 
   | 
||
| ... | ... | |
| 
     int settings()
 
   | 
||
| 
     {
 
   | 
||
| 
     	struct joystick_status joy;
 
   | 
||
| 
     	joy.x_ = joy.y_ = joy.fire_ = 0;
 
   | 
||
| 
     	joy.x_ = joy.y_ = joy.fire_ = joy.escape_ = 0;
 
   | 
||
| 
     | 
||
| 
     	int row = 0;
 
   | 
||
| 
     | 
||
| ... | ... | |
| 
     	return 0;
 
   | 
||
| 
     }
 
   | 
||
| 
     | 
||
| 
     | 
||
| 
     | 
||
| 
     void actions()
 
   | 
||
| 
     {
 
   | 
||
| 
     #ifdef LINUX_BUILD
 
   | 
||
| 
     	check_keys();
 
   | 
||
| 
     #endif
 
   | 
||
| 
     #ifdef USB
 
   | 
||
| 
     	usb_poll(&usb_porta);
 
   | 
||
| 
     #endif
 
   | 
||
| 
     #ifdef USB2
 
   | 
||
| 
     	usb_poll(&usb_portb);
 
   | 
||
| 
     #endif
 
   | 
||
| 
     | 
||
| 
     	// Show some activity!
 
   | 
||
| 
     	//*atari_colbk = *atari_random;
 
   | 
||
| 
     | 
||
| ... | ... | |
| 
     	}
 
   | 
||
| 
     	else if (get_hotkey_fileselect())
 
   | 
||
| 
     	{
 
   | 
||
| 
     /*#ifdef USB
 
   | 
||
| 
     		set_pause_6502(1);
 
   | 
||
| 
     		set_freezer_enable(0);
 
   | 
||
| 
     		freeze();
 
   | 
||
| 
     | 
||
| 
     		debug_pos = 0;	
 
   | 
||
| 
     		printf("Hello USB");
 
   | 
||
| 
     		debug_pos = 80;
 
   | 
||
| 
     		usb_init();
 
   | 
||
| 
     		while (1)
 
   | 
||
| 
     		{
 
   | 
||
| 
     			usb_poll();
 
   | 
||
| 
     			if (debug_pos>1000)
 
   | 
||
| 
     			{
 
   | 
||
| 
     				debug_pos = 80;
 
   | 
||
| 
     			}
 
   | 
||
| 
     		}
 
   | 
||
| 
     | 
||
| 
     		debug_pos = -1;
 
   | 
||
| 
     		restore();
 
   | 
||
| 
     		set_freezer_enable(freezer_rom_present);
 
   | 
||
| 
     		set_pause_6502(0);
 
   | 
||
| 
     #else*/
 
   | 
||
| 
     		set_pause_6502(1);
 
   | 
||
| 
     		set_freezer_enable(0);
 
   | 
||
| 
     		freeze();
 
   | 
||
| 
     		filter = filter_disks;
 
   | 
||
| 
     		file_selector(files[0]);
 
   | 
||
| 
     		debug_pos = -1;
 
   | 
||
| firmware/aeon_lite/memory.h | ||
|---|---|---|
| 
     | 
||
| 
     #define atari_regbase  ((void*) 0x10000)
 
   | 
||
| 
     #define atari_regmirror  ((void*) 0x20000)
 
   | 
||
| 
     #define config_regbase ((void*) 0x40000)
 
   | 
||
| 
     #define zpu_regbase ((void*) 0x40000)
 
   | 
||
| 
     #define pokey_regbase ((void*) 0x40400)
 
   | 
||
| 
     | 
||
| 
     #endif
 
   | 
||
| firmware/atari_drive_emulator.c | ||
|---|---|---|
| 
     | 
||
| 
     	//printf("Waiting for command\n");
 
   | 
||
| 
     	//USART_Data_Ready();
 
   | 
||
| 
     	while (0 == USART_Command_Line());
 
   | 
||
| 
     	while (0 == USART_Command_Line()) actions();
 
   | 
||
| 
     	//printf("Init:");
 
   | 
||
| 
     	//printf("%d",*zpu_sio);
 
   | 
||
| 
     	USART_Init(speed+6);
 
   | 
||
| 
     	//printf("%d",speed);
 
   | 
||
| 
     	//printf("\n");
 
   | 
||
| 
     	while (1 == USART_Command_Line())
 
   | 
||
| 
     	{
 
   | 
||
| 
     		actions();
 
   | 
||
| 
     	}
 
   | 
||
| 
     	while (1 == USART_Command_Line()) actions();
 
   | 
||
| 
     	for (i=0;i!=5;++i)
 
   | 
||
| 
     		((char *)cmd)[i] = USART_Receive_Byte();
 
   | 
||
| 
     	/*cmd->deviceId = USART_Receive_Byte();
 
   | 
||
| ... | ... | |
| 
     	cmd->aux1 = USART_Receive_Byte();
 
   | 
||
| 
     	cmd->aux2 = USART_Receive_Byte();
 
   | 
||
| 
     	cmd->chksum = USART_Receive_Byte();*/
 
   | 
||
| 
     	while (0 == USART_Command_Line())
 
   | 
||
| 
     	{
 
   | 
||
| 
     		actions();
 
   | 
||
| 
     	}
 
   | 
||
| 
     	while (0 == USART_Command_Line());
 
   | 
||
| 
     	//printf("cmd:");
 
   | 
||
| 
     	//printf("Gone high\n");
 
   | 
||
| 
     	atari_sector_buffer[0] = cmd->deviceId;
 
   | 
||
| firmware/linux/curses_screen.c | ||
|---|---|---|
| 
     		switch (ch) {
 
   | 
||
| 
     		case KEY_F(12):
 
   | 
||
| 
     			*zpu_in1 = 1<<11; return;
 
   | 
||
| 
     		case 27: // ESCAPE:
 
   | 
||
| 
     			longjmp(exit_jmp_buf, 1);
 
   | 
||
| 
     		case KEY_F(11):
 
   | 
||
| 
     			*zpu_in1 = 1<<10; return;
 
   | 
||
| 
     		}
 
   | 
||
| 
     	}
 
   | 
||
| 
     }
 
   | 
||
| ... | ... | |
| 
     	status->x_ = 0;
 
   | 
||
| 
     	status->y_ = 0;
 
   | 
||
| 
     	status->fire_ = 0;
 
   | 
||
| 
     	status->escape_ = 0;
 
   | 
||
| 
     | 
||
| 
     | 
||
| 
     	switch (ch) {
 
   | 
||
| ... | ... | |
| 
     	case 13:
 
   | 
||
| 
     		status->fire_ = 1; break;
 
   | 
||
| 
     	case 27: // ESCAPE:
 
   | 
||
| 
     		longjmp(exit_jmp_buf, 1);
 
   | 
||
| 
     		status->escape_ = 1; break;
 
   | 
||
| 
     	default: break;
 
   | 
||
| 
     	}
 
   | 
||
| 
     }
 
   | 
||
| firmware/linux/linux_helper.c | ||
|---|---|---|
| 
     #include "linux_helper.h"
 
   | 
||
| 
     | 
||
| 
     jmp_buf exit_jmp_buf;
 
   | 
||
| 
     | 
||
| 
     char* sdcard_filename = 0;
 
   | 
||
| firmware/linux/linux_helper.h | ||
|---|---|---|
| 
     #ifndef LINUX_HELPER_H
 
   | 
||
| 
     #define LINUX_HELPER_H
 
   | 
||
| 
     #include <setjmp.h>
 
   | 
||
| 
     | 
||
| 
     extern jmp_buf exit_jmp_buf;
 
   | 
||
| 
     | 
||
| 
     extern char* sdcard_filename;
 
   | 
||
| 
     | 
||
| 
     #endif
 
   | 
||
| firmware/linux/linux_memory.c | ||
|---|---|---|
| 
     void* SDRAM_BASE;
 
   | 
||
| 
     void* atari_regbase;
 
   | 
||
| 
     void* atari_regmirror;
 
   | 
||
| 
     void* config_regbase;
 
   | 
||
| 
     void* zpu_regbase;
 
   | 
||
| 
     void* pokey_regbase;
 
   | 
||
| 
     void* CARTRIDGE_MEM;
 
   | 
||
| 
     | 
||
| 
     void* FREEZER_RAM_MEM;
 
   | 
||
| ... | ... | |
| 
     	SDRAM_BASE = sdram_memory;
 
   | 
||
| 
     	atari_regbase = atari_memory;
 
   | 
||
| 
     	atari_regmirror = atari_mirror_memory;
 
   | 
||
| 
     	config_regbase = config_memory;
 
   | 
||
| 
     	zpu_regbase = config_memory;
 
   | 
||
| 
     	pokey_regbase = config_memory+0x100*4;
 
   | 
||
| 
     	CARTRIDGE_MEM = cartridge_memory;
 
   | 
||
| 
     	FREEZER_RAM_MEM = freezer_ram_memory;
 
   | 
||
| 
     	FREEZER_ROM_MEM = freezer_rom_memory;
 
   | 
||
| firmware/linux/main.c | ||
|---|---|---|
| 
     | 
||
| 
     	init_memory();
 
   | 
||
| 
     | 
||
| 
     	if (setjmp(exit_jmp_buf) == 0) {
 
   | 
||
| 
     		print_log("starting zpu_main\n");
 
   | 
||
| 
     		zpu_main();
 
   | 
||
| 
     	}
 
   | 
||
| 
     	print_log("starting zpu_main\n");
 
   | 
||
| 
     	zpu_main();
 
   | 
||
| 
     | 
||
| 
     	deinit_curses_screen();
 
   | 
||
| 
     	return 0;
 
   | 
||
| firmware/linux/memory.h | ||
|---|---|---|
| 
     | 
||
| 
     extern void* atari_regbase;
 
   | 
||
| 
     extern void* atari_regmirror;
 
   | 
||
| 
     extern void* config_regbase;
 
   | 
||
| 
     extern void* zpu_regbase;
 
   | 
||
| 
     extern void* pokey_regbase;
 
   | 
||
| 
     | 
||
| 
     void init_memory(void);
 
   | 
||
| 
     | 
||
| firmware/main.h | ||
|---|---|---|
| 
     	// pause counter runs at pokey frequency - should be 1.79MHz
 
   | 
||
| 
     	int unsigned cycles = (num*230)>>7;
 
   | 
||
| 
     	*zpu_pause = cycles;
 
   | 
||
| 
     #ifdef LINUX_BUILD
 
   | 
||
| 
     	usleep(num);
 
   | 
||
| 
     #endif
 
   | 
||
| 
     }
 
   | 
||
| 
     | 
||
| 
     void memset8(void * address, int value, int length)
 
   | 
||
| firmware/native/joystick.c | ||
|---|---|---|
| 
     	status->x_ = 0;
 
   | 
||
| 
     	status->y_ = 0;
 
   | 
||
| 
     	status->fire_ = 0;
 
   | 
||
| 
     	status->escape_ = 0;
 
   | 
||
| 
     | 
||
| 
     	unsigned char porta = *atari_porta;
 
   | 
||
| 
     	if (0==(porta&0x2)) // down
 
   | 
||
| firmware/regs.h | ||
|---|---|---|
| 
     | 
||
| 
     static const int screen_address = 11328;
 
   | 
||
| 
     | 
||
| 
     #define zpu_in1 ((int volatile *)(0*4+config_regbase))
 
   | 
||
| 
     #define zpu_in2 ((int volatile *)(1*4+config_regbase))
 
   | 
||
| 
     #define zpu_in3 ((int volatile *)(2*4+config_regbase))
 
   | 
||
| 
     #define zpu_in4 ((int volatile *)(3*4+config_regbase))
 
   | 
||
| 
     #define zpu_in1 ((int volatile *)(0*4+zpu_regbase))
 
   | 
||
| 
     #define zpu_in2 ((int volatile *)(1*4+zpu_regbase))
 
   | 
||
| 
     #define zpu_in3 ((int volatile *)(2*4+zpu_regbase))
 
   | 
||
| 
     #define zpu_in4 ((int volatile *)(3*4+zpu_regbase))
 
   | 
||
| 
     | 
||
| 
     #define zpu_out1 ((int volatile *)(4*4+config_regbase))
 
   | 
||
| 
     #define zpu_out2 ((int volatile *)(5*4+config_regbase))
 
   | 
||
| 
     #define zpu_out3 ((int volatile *)(6*4+config_regbase))
 
   | 
||
| 
     #define zpu_out4 ((int volatile *)(7*4+config_regbase))
 
   | 
||
| 
     #define zpu_out1 ((int volatile *)(4*4+zpu_regbase))
 
   | 
||
| 
     #define zpu_out2 ((int volatile *)(5*4+zpu_regbase))
 
   | 
||
| 
     #define zpu_out3 ((int volatile *)(6*4+zpu_regbase))
 
   | 
||
| 
     #define zpu_out4 ((int volatile *)(7*4+zpu_regbase))
 
   | 
||
| 
     #define zpu_out5 ((int volatile *)(14*4+zpu_regbase))
 
   | 
||
| 
     #define zpu_out6 ((int volatile *)(15*4+zpu_regbase))
 
   | 
||
| 
     | 
||
| 
     #define zpu_pause ((int volatile *)(8*4+config_regbase))
 
   | 
||
| 
     #define zpu_pause ((int volatile *)(8*4+zpu_regbase))
 
   | 
||
| 
     #define zpu_timer ((int volatile *)(8*4+zpu_regbase))
 
   | 
||
| 
     | 
||
| 
     #define zpu_spi_data ((int volatile *)(9*4+config_regbase))
 
   | 
||
| 
     #define zpu_spi_state ((int volatile *)(10*4+config_regbase))
 
   | 
||
| 
     #define zpu_spi_data ((int volatile *)(9*4+zpu_regbase))
 
   | 
||
| 
     #define zpu_spi_state ((int volatile *)(10*4+zpu_regbase))
 
   | 
||
| 
     | 
||
| 
     #define zpu_sio ((int volatile *)(11*4+config_regbase))
 
   | 
||
| 
     #define zpu_sio ((int volatile *)(11*4+zpu_regbase))
 
   | 
||
| 
     | 
||
| 
     #define zpu_board ((int volatile *)(12*4+config_regbase))
 
   | 
||
| 
     #define zpu_board ((int volatile *)(12*4+zpu_regbase))
 
   | 
||
| 
     | 
||
| 
     #define zpu_spi_dma ((int volatile *)(13*4+config_regbase))
 
   | 
||
| 
     #define zpu_spi_dma ((int volatile *)(13*4+zpu_regbase))
 
   | 
||
| 
     | 
||
| 
     #define zpu_pokey_audf0 ((unsigned char volatile *)(0x10*4+config_regbase))
 
   | 
||
| 
     #define zpu_pokey_audc0 ((unsigned char volatile *)(0x11*4+config_regbase))
 
   | 
||
| 
     #define zpu_pokey_audf1 ((unsigned char volatile *)(0x12*4+config_regbase))
 
   | 
||
| 
     #define zpu_pokey_audc1 ((unsigned char volatile *)(0x13*4+config_regbase))
 
   | 
||
| 
     #define zpu_pokey_audf2 ((unsigned char volatile *)(0x14*4+config_regbase))
 
   | 
||
| 
     #define zpu_pokey_audc2 ((unsigned char volatile *)(0x15*4+config_regbase))
 
   | 
||
| 
     #define zpu_pokey_audf3 ((unsigned char volatile *)(0x16*4+config_regbase))
 
   | 
||
| 
     #define zpu_pokey_audc3 ((unsigned char volatile *)(0x17*4+config_regbase))
 
   | 
||
| 
     #define zpu_pokey_audf0 ((unsigned char volatile *)(0x0*4+pokey_regbase))
 
   | 
||
| 
     #define zpu_pokey_audc0 ((unsigned char volatile *)(0x1*4+pokey_regbase))
 
   | 
||
| 
     #define zpu_pokey_audf1 ((unsigned char volatile *)(0x2*4+pokey_regbase))
 
   | 
||
| 
     #define zpu_pokey_audc1 ((unsigned char volatile *)(0x3*4+pokey_regbase))
 
   | 
||
| 
     #define zpu_pokey_audf2 ((unsigned char volatile *)(0x4*4+pokey_regbase))
 
   | 
||
| 
     #define zpu_pokey_audc2 ((unsigned char volatile *)(0x5*4+pokey_regbase))
 
   | 
||
| 
     #define zpu_pokey_audf3 ((unsigned char volatile *)(0x6*4+pokey_regbase))
 
   | 
||
| 
     #define zpu_pokey_audc3 ((unsigned char volatile *)(0x7*4+pokey_regbase))
 
   | 
||
| 
     | 
||
| 
     #define zpu_pokey_audctl ((unsigned char volatile *)(0x18*4+config_regbase))
 
   | 
||
| 
     #define zpu_pokey_audctl ((unsigned char volatile *)(0x8*4+pokey_regbase))
 
   | 
||
| 
     | 
||
| 
     #define zpu_pokey_skrest ((unsigned char volatile *)(0x1a*4+config_regbase))
 
   | 
||
| 
     #define zpu_pokey_serout ((unsigned char volatile *)(0x1d*4+config_regbase))
 
   | 
||
| 
     #define zpu_pokey_irqen ((unsigned char volatile *)(0x1e*4+config_regbase))
 
   | 
||
| 
     #define zpu_pokey_skctl ((unsigned char volatile *)(0x1f*4+config_regbase))
 
   | 
||
| 
     #define zpu_pokey_skrest ((unsigned char volatile *)(0xa*4+pokey_regbase))
 
   | 
||
| 
     #define zpu_pokey_serout ((unsigned char volatile *)(0xd*4+pokey_regbase))
 
   | 
||
| 
     #define zpu_pokey_irqen ((unsigned char volatile *)(0xe*4+pokey_regbase))
 
   | 
||
| 
     #define zpu_pokey_skctl ((unsigned char volatile *)(0xf*4+pokey_regbase))
 
   | 
||
| 
     | 
||
| 
     #define atari_nmien ((unsigned char volatile *)(0xd40e + atari_regbase))
 
   | 
||
| 
     #define atari_dlistl ((unsigned char volatile *)(0xd402 + atari_regbase))
 
   | 
||
| firmware/sdram_common/memory.h | ||
|---|---|---|
| 
     | 
||
| 
     #define atari_regbase  ((void*) 0x10000)
 
   | 
||
| 
     #define atari_regmirror  ((void*) 0x20000)
 
   | 
||
| 
     #define config_regbase ((void*) 0x40000)
 
   | 
||
| 
     #define zpu_regbase ((void*) 0x40000)
 
   | 
||
| 
     #define pokey_regbase ((void*) 0x40400)
 
   | 
||
| 
     | 
||
| 
     #endif
 
   | 
||
| firmware/usb/events.h | ||
|---|---|---|
| 
     #include "printf.h"
 
   | 
||
| 
     //#include "printf.h"
 
   | 
||
| 
     #include "regs.h"
 
   | 
||
| 
     | 
||
| 
     void event_keyboard(uint8_t i, uint8_t buf[])
 
   | 
||
| 
     #include "keycodes.h"
 
   | 
||
| 
     | 
||
| 
     extern int debug_pos;
 
   | 
||
| 
     | 
||
| 
     uint8_t kbbuf[6];
 
   | 
||
| 
     uint32_t jmaps[4];
 
   | 
||
| 
     | 
||
| 
     int8_t analogx[4];
 
   | 
||
| 
     int8_t analogy[4];
 
   | 
||
| 
     | 
||
| 
     void event_keyboard(uint8_t mod, uint8_t buf[])
 
   | 
||
| 
     {
 
   | 
||
| 
     	//printf("Event keyboard:%d\n", mod);
 
   | 
||
| 
     	/*int changed = 0;
 
   | 
||
| 
     | 
||
| 
     	if (lastmod!=i)
 
   | 
||
| 
     	{
 
   | 
||
| 
     		lastmod = i;
 
   | 
||
| 
     		changed = 1;
 
   | 
||
| 
     	}
 
   | 
||
| 
     	int j;
 
   | 
||
| 
     	printf("Event keyboard:%d\n", i);
 
   | 
||
| 
             for (j=0;j!=6;++j)
 
   | 
||
| 
             for (j=0;j!=8;++j)
 
   | 
||
| 
     	{
 
   | 
||
| 
     		printf("Event keyboard:%d = %x\n", j, buf[j]);
 
   | 
||
| 
     		//printf("Event keyboard:%d = %x\n", j, buf[j]);
 
   | 
||
| 
     		if (buf[j] != kbbuf[j])
 
   | 
||
| 
     		{
 
   | 
||
| 
     			changed = 1;
 
   | 
||
| 
     			kbbuf[j] = buf[j];
 
   | 
||
| 
     		}
 
   | 
||
| 
     	}*/
 
   | 
||
| 
     | 
||
| 
       /* usb modifer bits: 
 
   | 
||
| 
             0     1     2    3    4     5     6    7
 
   | 
||
| 
           LCTRL LSHIFT LALT LGUI RCTRL RSHIFT RALT RGUI
 
   | 
||
| 
       */
 
   | 
||
| 
     | 
||
| 
     	// Convert changes into a serial of release/press notifications
 
   | 
||
| 
     	int i=0;
 
   | 
||
| 
     	for(i=0;i!=8;++i)
 
   | 
||
| 
     	{
 
   | 
||
| 
     		int bit = 1<<i;
 
   | 
||
| 
     		uint32_t pressed = !!(bit&mod);
 
   | 
||
| 
     		uint32_t ps2_key = ps2_modifier[i];
 
   | 
||
| 
     		*zpu_out4 = (pressed<<16)|ps2_key;
 
   | 
||
| 
     	}
 
   | 
||
| 
     | 
||
| 
     	// unpress old keys that are no longer pressed
 
   | 
||
| 
     	for (i=0;i!=6;++i)
 
   | 
||
| 
     	{
 
   | 
||
| 
     		if (kbbuf[i]==MISS) continue;
 
   | 
||
| 
     | 
||
| 
     		uint32_t oldkey = usb2ps2[kbbuf[i]];
 
   | 
||
| 
     		int j=0;
 
   | 
||
| 
     		int found = 0;
 
   | 
||
| 
     		for (j=0;j!=6;++j)
 
   | 
||
| 
     		{
 
   | 
||
| 
     			uint32_t newkey = usb2ps2[buf[i]];
 
   | 
||
| 
     			if (oldkey==newkey) {found=1;break;}
 
   | 
||
| 
     		}
 
   | 
||
| 
     | 
||
| 
     		if (!found)
 
   | 
||
| 
     		{
 
   | 
||
| 
     			*zpu_out4 = oldkey; // unpress
 
   | 
||
| 
     		}
 
   | 
||
| 
     	}
 
   | 
||
| 
     | 
||
| 
     	// press/hold new keys
 
   | 
||
| 
     	for (i=0;i!=6;++i)
 
   | 
||
| 
     	{
 
   | 
||
| 
     		if (buf[i]==MISS) continue;
 
   | 
||
| 
     | 
||
| 
     		uint32_t newkey = usb2ps2[buf[i]];
 
   | 
||
| 
     | 
||
| 
     		// press new one
 
   | 
||
| 
     		*zpu_out4 = (1<<16)|newkey;
 
   | 
||
| 
     	}
 
   | 
||
| 
     | 
||
| 
     	for (i=0;i!=6;++i)
 
   | 
||
| 
     	{
 
   | 
||
| 
     		kbbuf[i] = buf[i]; // store
 
   | 
||
| 
     	}
 
   | 
||
| 
     | 
||
| 
     /*	if (changed)
 
   | 
||
| 
     	{
 
   | 
||
| 
     		debug_pos = 120;
 
   | 
||
| 
     		printf("KB:");
 
   | 
||
| 
     		printf("%02x ",kbi);
 
   | 
||
| 
     		for (j=0;j!=8;++j)
 
   | 
||
| 
     		{
 
   | 
||
| 
     			printf("%04x ",usb2ps2[kbbuf[j]]);
 
   | 
||
| 
     		}
 
   | 
||
| 
     | 
||
| 
     		// lctrl:1, lshift:2, lalt:4, lwin:8, rctrl:10, rshift:20, altgr:40
 
   | 
||
| 
     		uint32_t mod = kbi;
 
   | 
||
| 
     		uint32_t key1 = usb2ps2[kbbuf[0]];
 
   | 
||
| 
     		//uint32_t key2 = usb2ps2[kbbuf[1]];
 
   | 
||
| 
     		//uint32_t key3 = usb2ps2[kbbuf[2]];
 
   | 
||
| 
     | 
||
| 
     		uint32_t res = (key3<<24) | (key2<<16) || (key1<<8) || mod;
 
   | 
||
| 
     		*zpu_out4 = res;
 
   | 
||
| 
     	}*/
 
   | 
||
| 
     }
 
   | 
||
| 
     void event_mouse(uint8_t a, uint8_t b, uint8_t c)
 
   | 
||
| 
     {
 
   | 
||
| 
     	printf("Event mouse:%d %d %d\n",a,b,c);
 
   | 
||
| 
     	//printf("Event mouse:%d %d %d\n",a,b,c);
 
   | 
||
| 
     }
 
   | 
||
| 
     void event_digital_joystick(uint8_t idx, uint8_t jmap)
 
   | 
||
| 
     void event_digital_joystick(uint8_t idx, uint32_t jmap)
 
   | 
||
| 
     {
 
   | 
||
| 
     	printf("Event joystick:%d %x\n", idx,jmap);
 
   | 
||
| 
     	//printf("Event joystick:%d %x\n", idx,jmap);
 
   | 
||
| 
     	/*if (jmaps[idx] != jmap)
 
   | 
||
| 
     	{
 
   | 
||
| 
     		jmaps[idx] = jmap;
 
   | 
||
| 
     		debug_pos = 200 + idx*40;
 
   | 
||
| 
     		printf("JOY:%d:%08x ",idx,jmap);
 
   | 
||
| 
     	}*/
 
   | 
||
| 
     	if (idx == 0)
 
   | 
||
| 
     	{
 
   | 
||
| 
     		*zpu_out2 = jmap;
 
   | 
||
| 
     	}
 
   | 
||
| 
     	if (idx == 1)
 
   | 
||
| 
     	{
 
   | 
||
| 
     		*zpu_out3 = jmap;
 
   | 
||
| 
     	}
 
   | 
||
| 
     }
 
   | 
||
| 
     void event_analog_joystick(uint8_t idx, int8_t x, int8_t y)
 
   | 
||
| 
     {
 
   | 
||
| 
     	printf("Event analog joystick:%d %d %d\n", idx,x,y);
 
   | 
||
| 
     	//printf("Event analog joystick:%d %d %d\n", idx,x,y);
 
   | 
||
| 
     	if (analogx[idx]!=x || analogy[idx]!=y)
 
   | 
||
| 
     	{
 
   | 
||
| 
     		analogx[idx] = x;
 
   | 
||
| 
     		analogy[idx] = y;
 
   | 
||
| 
     		//debug_pos = 360 + idx*40;
 
   | 
||
| 
     		//printf("AJOY:%d:%d:%d ", idx,x,y);
 
   | 
||
| 
     | 
||
| 
     		uint32_t x0 = (uint8_t)analogx[0];
 
   | 
||
| 
     		uint32_t y0 = (uint8_t)analogy[0];
 
   | 
||
| 
     		uint32_t x1 = (uint8_t)analogx[1];
 
   | 
||
| 
     		uint32_t y1 = (uint8_t)analogy[1];
 
   | 
||
| 
     | 
||
| 
     		uint32_t comb = (y1<<24)|(x1<<16)|(y0<<8) |x0;
 
   | 
||
| 
     		*zpu_out5 = comb;
 
   | 
||
| 
     	}
 
   | 
||
| 
     }
 
   | 
||
| 
     | 
||
| 
     #define JOY_RIGHT       0x01
 
   | 
||
| firmware/usb/hid.c | ||
|---|---|---|
| 
     #include "events.h"
 
   | 
||
| 
     #include "debug.h"
 
   | 
||
| 
     #include "usbhostslave.h"
 
   | 
||
| 
     #include "log.h"
 
   | 
||
| 
     | 
||
| 
     static unsigned char kbd_led_state = 0;  // default: all leds off
 
   | 
||
| 
     static unsigned char joysticks = 0;      // number of detected usb joysticks
 
   | 
||
| 
     /*#include "printf.h"
 
   | 
||
| 
     extern unsigned char volatile * baseaddr;
 
   | 
||
| 
     extern int debug_pos;*/
 
   | 
||
| 
     | 
||
| 
     unsigned char kbd_led_state;  // default: all leds off
 
   | 
||
| 
     unsigned char joysticks;      // number of detected usb joysticks
 
   | 
||
| 
     | 
||
| 
     //#define hid_debugf printf
 
   | 
||
| 
     | 
||
| 
     uint16_t bs16(uint8_t * in)
 
   | 
||
| 
     {
 
   | 
||
| 
     	uint16_t low = *in;
 
   | 
||
| 
     	uint16_t high = *(in+1);
 
   | 
||
| 
     	uint16_t res = (high<<8) | low;
 
   | 
||
| 
     	return res;
 
   | 
||
| 
     }
 
   | 
||
| 
     | 
||
| 
     uint8_t hid_get_joysticks(void) {
 
   | 
||
| 
       return joysticks;
 
   | 
||
| 
     }
 
   | 
||
| ... | ... | |
| 
         // we got a report descriptor. Try to parse it
 
   | 
||
| 
         if(parse_report_descriptor(buf, size, &(info->iface[i].conf))) {
 
   | 
||
| 
           if(info->iface[i].conf.type == CONFIG_TYPE_JOYSTICK) {
 
   | 
||
| 
     	//unsigned char * temp = baseaddr;
 
   | 
||
| 
     	//baseaddr = (unsigned char volatile *)(40000 + atari_regbase);
 
   | 
||
| 
     	//debug_pos=160;
 
   | 
||
| 
     	//printf("Detected USB joystick #%d", joysticks);
 
   | 
||
| 
     	hid_debugf("Detected USB joystick #%d", joysticks);
 
   | 
||
| 
     | 
||
| 
     	info->iface[i].device_type = HID_DEVICE_JOYSTICK;
 
   | 
||
| 
     	info->iface[i].jindex = joysticks++;
 
   | 
||
| 
     	//debug_pos=240;
 
   | 
||
| 
     	//printf("assigned index #%d", info->iface[i].jindex);
 
   | 
||
| 
     	//baseaddr = temp;
 
   | 
||
| 
           }
 
   | 
||
| 
         }
 
   | 
||
| 
       }
 
   | 
||
| ... | ... | |
| 
     | 
||
| 
       /* scan through all descriptors */
 
   | 
||
| 
       p = &buf;
 
   | 
||
| 
       //LOG("LenX:%d\n", p->conf_desc.bLength);
 
   | 
||
| 
       while(len > 0) {
 
   | 
||
| 
         //printf("L%02d %02d %02d ",len, p->conf_desc.bLength, p->conf_desc.bDescriptorType);
 
   | 
||
| 
     | 
||
| 
         switch(p->conf_desc.bDescriptorType) {
 
   | 
||
| 
         case USB_DESCRIPTOR_CONFIGURATION:
 
   | 
||
| 
           // hid_debugf("conf descriptor size %d", p->conf_desc.bLength);
 
   | 
||
| ... | ... | |
| 
         }
 
   | 
||
| 
     | 
||
| 
         // advance to next descriptor
 
   | 
||
| 
        //LOG("Len:%d\n", p->conf_desc.bLength);
 
   | 
||
| 
        //timer_delay_msec(1000);
 
   | 
||
| 
         len -= p->conf_desc.bLength;
 
   | 
||
| 
         p = (union buf_u*)(p->raw + p->conf_desc.bLength);
 
   | 
||
| 
       }
 
   | 
||
| ... | ... | |
| 
       uint8_t i;
 
   | 
||
| 
       uint16_t vid, pid;
 
   | 
||
| 
     | 
||
| 
       kbd_led_state = 0;  // default: all leds off
 
   | 
||
| 
     | 
||
| 
       usb_hid_info_t *info = &(dev->hid_info);
 
   | 
||
| 
     | 
||
| 
       union {
 
   | 
||
| ... | ... | |
| 
         return rcode;
 
   | 
||
| 
     | 
||
| 
       // save vid/pid for automatic hack later
 
   | 
||
| 
       vid = buf.dev_desc.idVendor;
 
   | 
||
| 
       pid = buf.dev_desc.idProduct;
 
   | 
||
| 
       vid = bs16(&buf.dev_desc.idVendorL);
 
   | 
||
| 
       pid = bs16(&buf.dev_desc.idProductL);
 
   | 
||
| 
     | 
||
| 
       uint8_t num_of_conf = buf.dev_desc.bNumConfigurations;
 
   | 
||
| 
       //  hid_debugf("number of configurations: %d", num_of_conf);
 
   | 
||
| ... | ... | |
| 
           return rcode;
 
   | 
||
| 
     | 
||
| 
         //    hid_debugf("conf descriptor %d has total size %d", i, buf.conf_desc.wTotalLength);
 
   | 
||
| 
         uint16_t wTotalLength = bs16(&buf.conf_desc.wTotalLengthL);
 
   | 
||
| 
         LOG("conf descriptor %d has total size %d", i, wTotalLength);
 
   | 
||
| 
     | 
||
| 
         // parse directly if it already fitted completely into the buffer
 
   | 
||
| 
         usb_hid_parse_conf(dev, i, buf.conf_desc.wTotalLength);
 
   | 
||
| 
         usb_hid_parse_conf(dev, i, wTotalLength);
 
   | 
||
| 
       }
 
   | 
||
| 
     | 
||
| 
       // check if we found valid hid interfaces
 
   | 
||
| ... | ... | |
| 
       for(i=0; i<info->bNumIfaces; i++) {
 
   | 
||
| 
         // no boot mode, try to parse HID report descriptor
 
   | 
||
| 
         if(!info->iface[i].has_boot_mode) {
 
   | 
||
| 
     | 
||
| 
           //printf("DESC ");
 
   | 
||
| 
           rcode = hid_get_report_descr(dev, i, info->iface[i].report_desc_size);
 
   | 
||
| 
           if(rcode) return rcode;
 
   | 
||
| 
     | 
||
| 
           //printf("TYPE%02x ", info->iface[i].device_type);
 
   | 
||
| 
           if(info->iface[i].device_type == CONFIG_TYPE_JOYSTICK) {
 
   | 
||
| 
     	char k;
 
   | 
||
| 
     | 
||
| ... | ... | |
| 
     		  info->iface[i].conf.joystick.axis[k].logical.min,
 
   | 
||
| 
     		  info->iface[i].conf.joystick.axis[k].logical.max);
 
   | 
||
| 
     | 
||
| 
     	for(k=0;k<4;k++)
 
   | 
||
| 
     	for(k=0;k<24;k++)
 
   | 
||
| 
     	  iprintf("Button%d: @%d/%d\n", k,
 
   | 
||
| 
     		  info->iface[i].conf.joystick.button[k].byte_offset,
 
   | 
||
| 
     		  info->iface[i].conf.joystick.button[k].bitmask);
 
   | 
||
| ... | ... | |
| 
     | 
||
| 
         rcode = hid_set_idle(dev, info->iface[i].iface_idx, 0, 0);
 
   | 
||
| 
         // MWW if (rcode && rcode != hrSTALL)
 
   | 
||
| 
         //printf("RCODE:%02x ",rcode);
 
   | 
||
| 
         if (rcode && rcode != OHS900_STATMASK_STALL_RXED)
 
   | 
||
| 
           return rcode;
 
   | 
||
| 
     | 
||
| 
         //printf("BM ");
 
   | 
||
| 
         // enable boot mode
 
   | 
||
| 
         if(info->iface[i].has_boot_mode)
 
   | 
||
| 
         {
 
   | 
||
| 
           //printf("BM ");
 
   | 
||
| 
           hid_set_protocol(dev, info->iface[i].iface_idx, HID_BOOT_PROTOCOL);
 
   | 
||
| 
         }
 
   | 
||
| 
       }
 
   | 
||
| 
     | 
||
| 
       iprintf("HID configured\n");
 
   | 
||
| ... | ... | |
| 
       // update leds
 
   | 
||
| 
       for(i=0;i<MAX_IFACES;i++)
 
   | 
||
| 
         if(dev->hid_info.iface[i].device_type == HID_DEVICE_KEYBOARD)
 
   | 
||
| 
           hid_set_report(dev, dev->hid_info.iface[i].iface_idx, 2, 0, 1, &kbd_led_state);
 
   | 
||
| 
         {
 
   | 
||
| 
     //      printf("LEDS ");
 
   | 
||
| 
           uint8_t res = hid_set_report(dev, dev->hid_info.iface[i].iface_idx, 2, 0, 1, &kbd_led_state);
 
   | 
||
| 
     //      printf("LEDS res:%02x ", res);
 
   | 
||
| 
         }
 
   | 
||
| 
     | 
||
| 
       info->bPollEnable = true;
 
   | 
||
| 
       return 0;
 
   | 
||
| ... | ... | |
| 
     	  if(iface->device_type == HID_DEVICE_JOYSTICK) {
 
   | 
||
| 
     	    hid_config_t *conf = &iface->conf;
 
   | 
||
| 
     	    if(read >= conf->report_size) {
 
   | 
||
| 
     	      uint8_t jmap = 0;
 
   | 
||
| 
     	      uint32_t jmap = 0;
 
   | 
||
| 
     	      uint16_t a[2];
 
   | 
||
| 
     	      uint8_t idx, i;
 
   | 
||
| 
     | 
||
| ... | ... | |
| 
     | 
||
| 
     	      //	      iprintf("JOY X:%d Y:%d\n", a[0], a[1]);
 
   | 
||
| 
     | 
||
| 
     	      // ... and four buttons
 
   | 
||
| 
     	      for(i=0;i<4;i++)
 
   | 
||
| 
     	      // ... and twenty-four buttons
 
   | 
||
| 
     	      for(i=0;i<24;i++)
 
   | 
||
| 
     		if(buf[conf->joystick.button[i].byte_offset] & 
 
   | 
||
| 
     		   conf->joystick.button[i].bitmask) jmap |= (JOY_BTN1<<i);
 
   | 
||
| 
     | 
||
| 
     	      //	      iprintf("JOY D:%d\n", jmap);
 
   | 
||
| 
     | 
||
| 
     	      // swap joystick 0 and 1 since 1 is the one 
 
   | 
||
| 
     	      // used primarily on most systems
 
   | 
||
| 
     	      idx = iface->jindex;
 
   | 
||
| 
     	      if(idx == 0)      idx = 1;
 
   | 
||
| 
     	      else if(idx == 1) idx = 0;
 
   | 
||
| 
     | 
||
| 
     	      // check if joystick state has changed
 
   | 
||
| 
     	      if(jmap != iface->jmap) {
 
   | 
||
| 
     | 
||
| 
     		//unsigned char * temp = baseaddr;
 
   | 
||
| 
     		//baseaddr = (unsigned char volatile *)(40000 + atari_regbase);
 
   | 
||
| 
     		//debug_pos=80;
 
   | 
||
| 
     		//printf("jmap %d(%d) changed to %x\n", idx, iface->jindex,jmap);
 
   | 
||
| 
     		//baseaddr = temp;
 
   | 
||
| 
     		//	      iprintf("jmap %d changed to %x\n", idx, jmap);
 
   | 
||
| 
     | 
||
| 
     		// and feed into joystick input system
 
   | 
||
| firmware/usb/hid.h | ||
|---|---|---|
| 
       uint16_t report_desc_size;
 
   | 
||
| 
     | 
||
| 
       uint8_t device_type;
 
   | 
||
| 
       bool has_boot_mode: 1;     // device supports boot mode
 
   | 
||
| 
       bool is_5200daptor: 1;     // device is a 5200daptor with special key handling
 
   | 
||
| 
       uint8_t has_boot_mode;     // device supports boot mode
 
   | 
||
| 
       uint8_t is_5200daptor;     // device is a 5200daptor with special key handling
 
   | 
||
| 
       uint16_t key_state;        // needed to detect key state changes in 5200daptor
 
   | 
||
| 
     | 
||
| 
       // additional info extracted from the report descriptor
 
   | 
||
| 
       // (currently only used for joysticks) 
 
   | 
||
| 
       uint8_t jmap;           // last reported joystick state
 
   | 
||
| 
       uint32_t jmap;           // last reported joystick state
 
   | 
||
| 
       uint8_t jindex;         // joystick index
 
   | 
||
| 
       hid_config_t conf;
 
   | 
||
| 
     | 
||
| ... | ... | |
| 
     typedef struct  {
 
   | 
||
| 
       uint8_t         bLength;
 
   | 
||
| 
       uint8_t         bDescriptorType;
 
   | 
||
| 
       uint16_t        bcdHID;                         // HID class specification release
 
   | 
||
| 
       uint8_t        bcdHIDL;                         // HID class specification release
 
   | 
||
| 
       uint8_t        bcdHIDH;                         // HID class specification release
 
   | 
||
| 
       uint8_t         bCountryCode;
 
   | 
||
| 
       uint8_t         bNumDescriptors;                // Number of additional class specific descriptors
 
   | 
||
| 
       uint8_t         bDescrType;                     // Type of class descriptor
 
   | 
||
| firmware/usb/hidparser.c | ||
|---|---|---|
| 
     | 
||
| 
     #include "hidparser.h"
 
   | 
||
| 
     #include "debug.h"
 
   | 
||
| 
     //#include "printf.h"
 
   | 
||
| 
     //#include <stdio.h>
 
   | 
||
| 
     | 
||
| 
     #if 1
 
   | 
||
| 
     #if 0
 
   | 
||
| 
     #define hidp_extreme_debugf(...) hidp_debugf(__VA_ARGS__)
 
   | 
||
| 
     #else
 
   | 
||
| 
     #define hidp_extreme_debugf(...)
 
   | 
||
| 
     #endif
 
   | 
||
| 
     | 
||
| 
     //#define hidp_debugf printf
 
   | 
||
| 
     | 
||
| 
     typedef struct {
 
   | 
||
| 
       uint8_t bSize: 2;
 
   | 
||
| 
       uint8_t bType: 2;
 
   | 
||
| ... | ... | |
| 
       // that e.g. both axes and the button of a joystick are ready to be used
 
   | 
||
| 
       uint8_t setup_complete = 0;
 
   | 
||
| 
     | 
||
| 
       /*printf("PARSE:");
 
   | 
||
| 
       int j = 0;
 
   | 
||
| 
       for (j=0; j!=rep_size; ++j)
 
   | 
||
| 
       {
 
   | 
||
| 
         printf("%02x",rep[j]);
 
   | 
||
| 
       }
 
   | 
||
| 
       printf(" ");*/
 
   | 
||
| 
     | 
||
| 
       // joystick/mouse components
 
   | 
||
| 
       int8_t axis[2]; // MWW = { -1, -1}; (this instantiates memcpy!)
 
   | 
||
| 
       axis[0] = -1;
 
   | 
||
| ... | ... | |
| 
     | 
||
| 
       while(rep_size) {
 
   | 
||
| 
         // extract short item
 
   | 
||
| 
         uint8_t tag = ((item_t*)rep)->bTag;
 
   | 
||
| 
     /*    uint8_t tag = ((item_t*)rep)->bTag;
 
   | 
||
| 
         uint8_t type = ((item_t*)rep)->bType;
 
   | 
||
| 
         uint8_t size = ((item_t*)rep)->bSize;
 
   | 
||
| 
         uint8_t size = ((item_t*)rep)->bSize;*/
 
   | 
||
| 
     /*typedef struct {
 
   | 
||
| 
       uint8_t bSize: 2;
 
   | 
||
| 
       uint8_t bType: 2;
 
   | 
||
| 
       uint8_t bTag: 4;
 
   | 
||
| 
     } __attribute__((packed)) item_t;*/
 
   | 
||
| 
         // MWW - bitfields are not working
 
   | 
||
| 
         uint8_t tag = (rep[0]&0xf0)>>4;
 
   | 
||
| 
         uint8_t type = (rep[0]&0x0c)>>2;
 
   | 
||
| 
         uint8_t size = rep[0]&0x03;
 
   | 
||
| 
     //    printf("WTF:%02x %02x %02x %02x\n",rep[0],tag,type,size);
 
   | 
||
| 
     | 
||
| 
         rep++;
 
   | 
||
| 
         rep_size--;   // one byte consumed
 
   | 
||
| ... | ... | |
| 
     	  // 
 
   | 
||
| 
     	  if(btns) {
 
   | 
||
| 
     	    if(conf->type == CONFIG_TYPE_JOYSTICK) {
 
   | 
||
| 
     	      // scan for up to four buttons
 
   | 
||
| 
     	      // scan for up to 24 buttons
 
   | 
||
| 
     	      char b;
 
   | 
||
| 
     	      for(b=0;b<4;b++) {
 
   | 
||
| 
     	      for(b=0;b<24;b++) {
 
   | 
||
| 
     		if(report_count > b) {
 
   | 
||
| 
     		  uint16_t this_bit = bit_count+b;
 
   | 
||
| 
     | 
||
| firmware/usb/hidparser.h | ||
|---|---|---|
| 
     	uint8_t byte_offset;
 
   | 
||
| 
     	uint8_t size;          // 8 or 16 bits supported
 
   | 
||
| 
     	struct {
 
   | 
||
| 
     /*	  uint8_t minl;
 
   | 
||
| 
     	  uint8_t minh;
 
   | 
||
| 
     	  uint8_t maxl;
 
   | 
||
| 
     	  uint8_t maxh;*/
 
   | 
||
| 
     	  uint16_t min;
 
   | 
||
| 
     	  uint16_t max;
 
   | 
||
| 
     	} logical;
 
   | 
||
| ... | ... | |
| 
           struct {
 
   | 
||
| 
     	uint8_t byte_offset;
 
   | 
||
| 
     	uint8_t bitmask;
 
   | 
||
| 
           } button[4];             // 4 buttons
 
   | 
||
| 
           } button[24];             // 24 buttons
 
   | 
||
| 
         } joystick;
 
   | 
||
| 
       };
 
   | 
||
| 
     } hid_config_t;
 
   | 
||
| firmware/usb/hub.c | ||
|---|---|---|
| 
     #include "timer.h"
 
   | 
||
| 
     #include "debug.h"
 
   | 
||
| 
     | 
||
| 
     //#include "printf.h"
 
   | 
||
| 
     | 
||
| 
     //#define iprintf printf
 
   | 
||
| 
     | 
||
| 
     uint16_t bs16(uint8_t * in);
 
   | 
||
| 
     | 
||
| 
     uint32_t bs32(uint8_t * in)
 
   | 
||
| 
     {
 
   | 
||
| 
     	uint32_t a = *in;
 
   | 
||
| 
     	uint32_t b = *(in+1);
 
   | 
||
| 
     	uint32_t c = *(in+2);
 
   | 
||
| 
     	uint32_t d = *(in+3);
 
   | 
||
| 
     	uint32_t res = (d<<24) | (c<<16) | (b<<8) | a;
 
   | 
||
| 
     	return res;
 
   | 
||
| 
     }
 
   | 
||
| 
     | 
||
| 
     static uint8_t usb_hub_clear_hub_feature(usb_device_t *dev, uint8_t fid )  {
 
   | 
||
| 
       return( usb_ctrl_req( dev, USB_HUB_REQ_CLEAR_HUB_FEATURE, 
 
   | 
||
| 
            USB_REQUEST_CLEAR_FEATURE, fid, 0, 0, 0, NULL));
 
   | 
||
| ... | ... | |
| 
     | 
||
| 
     // Get Port Status
 
   | 
||
| 
     static uint8_t usb_hub_get_port_status(usb_device_t *dev, uint8_t port, uint16_t nbytes, uint8_t* dataptr )  {
 
   | 
||
| 
       return( usb_ctrl_req( dev, USB_HUB_REQ_GET_PORT_STATUS, 
 
   | 
||
| 
       uint8_t res = ( usb_ctrl_req( dev, USB_HUB_REQ_GET_PORT_STATUS, 
 
   | 
||
| 
            USB_REQUEST_GET_STATUS, 0, 0, port, nbytes, dataptr));
 
   | 
||
| 
     | 
||
| 
       iprintf("portstat:%d bytes:%d res:%02x ",port,nbytes,res);
 
   | 
||
| 
       return res;
 
   | 
||
| 
     }
 
   | 
||
| 
     | 
||
| 
     static uint8_t usb_hub_init(usb_device_t *dev) {
 
   | 
||
| ... | ... | |
| 
     | 
||
| 
       // Save number of ports for future use
 
   | 
||
| 
       info->bNbrPorts = buf.hub_desc.bNbrPorts;
 
   | 
||
| 
       iprintf("ports:%d ",buf.hub_desc.bNbrPorts); // MWW
 
   | 
||
| 
     | 
||
| 
       // Read configuration Descriptor in Order To Obtain Proper Configuration Value
 
   | 
||
| 
       rcode = usb_get_conf_descr(dev, sizeof(usb_configuration_descriptor_t), 0, &buf.conf_desc);
 
   | 
||
| ... | ... | |
| 
     | 
||
| 
       // Power on all ports
 
   | 
||
| 
       for (i=1; i<=info->bNbrPorts; i++)
 
   | 
||
| 
         usb_hub_set_port_feature(dev, HUB_FEATURE_PORT_POWER, i, 0);	// HubPortPowerOn(i);
 
   | 
||
| 
       {
 
   | 
||
| 
         rcode = usb_hub_set_port_feature(dev, HUB_FEATURE_PORT_POWER, i, 0);	// HubPortPowerOn(i);
 
   | 
||
| 
         iprintf("PWR:%d:%02x ",i,rcode);
 
   | 
||
| 
       }
 
   | 
||
| 
     | 
||
| 
       if(!dev->parent)
 
   | 
||
| 
         usb_SetHubPreMask();
 
   | 
||
| 
     | 
||
| 
       iprintf("HUB pollingOn "); // MWW
 
   | 
||
| 
       info->bPollEnable = true;
 
   | 
||
| 
     | 
||
| 
       return 0;
 
   | 
||
| ... | ... | |
| 
     static uint8_t usb_hub_release(usb_device_t *dev) {
 
   | 
||
| 
       iprintf("%s\n",__FUNCTION__);
 
   | 
||
| 
     | 
||
| 
       // root hub unplugged
 
   | 
||
| 
       if(!dev->parent)
 
   | 
||
| 
         usb_ResetHubPreMask();
 
   | 
||
| 
     | 
||
| 
       return 0;
 
   | 
||
| 
     }
 
   | 
||
| 
     | 
||
| ... | ... | |
| 
     static uint8_t usb_hub_port_status_change(usb_device_t *dev, uint8_t port, hub_event_t evt) {
 
   | 
||
| 
       usb_hub_info_t *info = &(dev->hub_info);
 
   | 
||
| 
     | 
||
| 
       iprintf("status change on port %d, 0x%x\n", port, evt.bmEvent);
 
   | 
||
| 
       usb_hub_show_port_status(port, evt.bmStatus, evt.bmChange);
 
   | 
||
| 
       iprintf("status change on port %d, 0x%x\n", port, bs32(&evt.bmEventLL));
 
   | 
||
| 
       usb_hub_show_port_status(port, bs16(&evt.bmStatusL), bs16(&evt.bmChangeL));
 
   | 
||
| 
     | 
||
| 
       static bool bResetInitiated = false;
 
   | 
||
| 
     | 
||
| 
       switch (evt.bmEvent) {
 
   | 
||
| 
       switch (bs32(&evt.bmEventLL)) {
 
   | 
||
| 
         // Device connected event
 
   | 
||
| 
       case USB_HUB_PORT_EVENT_CONNECT:
 
   | 
||
| 
       case USB_HUB_PORT_EVENT_LS_CONNECT:
 
   | 
||
| ... | ... | |
| 
         usb_hub_clear_port_feature(dev, HUB_FEATURE_C_PORT_CONNECTION, port, 0);
 
   | 
||
| 
     | 
||
| 
         usb_configure(dev->bAddress, port, 
 
   | 
||
| 
     	  (evt.bmStatus & USB_HUB_PORT_STATUS_PORT_LOW_SPEED)!=0 );
 
   | 
||
| 
     	  (bs16(&evt.bmStatusL) & USB_HUB_PORT_STATUS_PORT_LOW_SPEED)!=0 );
 
   | 
||
| 
     | 
||
| 
         bResetInitiated = false;
 
   | 
||
| 
         break;
 
   | 
||
| ... | ... | |
| 
       uint8_t	buf[8];
 
   | 
||
| 
       uint16_t	read = 1;
 
   | 
||
| 
     | 
||
| 
       //   iprintf("%s(addr=%x)\n", __FUNCTION__, dev->bAddress);
 
   | 
||
| 
       //iprintf("%s(addr=%x)\n", __FUNCTION__, dev->bAddress);
 
   | 
||
| 
     | 
||
| 
       rcode = usb_in_transfer(dev, &(info->ep), &read, buf);
 
   | 
||
| 
       if(rcode)
 
   | 
||
| 
       {
 
   | 
||
| 
         //iprintf("RC:%02x ",rcode);
 
   | 
||
| 
         return rcode;
 
   | 
||
| 
       }
 
   | 
||
| 
     | 
||
| 
       uint8_t port, mask;
 
   | 
||
| 
       for(port=1,mask=0x02; port<8; mask<<=1, port++) {
 
   | 
||
| 
         if (buf[0] & mask) {
 
   | 
||
| 
           hub_event_t evt;
 
   | 
||
| 
           evt.bmEvent = 0;
 
   | 
||
| 
           evt.bmEventLL = evt.bmEventLL2 = evt.bmEventLL3 = evt.bmEventLL4 = 0;
 
   | 
||
| 
     | 
||
| 
           rcode = usb_hub_get_port_status(dev, port, sizeof(evt.evtBuff), evt.evtBuff);
 
   | 
||
| 
           if (rcode)
 
   | 
||
| ... | ... | |
| 
     | 
||
| 
       for (port=1; port<=ports; port++) {
 
   | 
||
| 
         hub_event_t	evt;
 
   | 
||
| 
         evt.bmEvent = 0;
 
   | 
||
| 
         evt.bmEventLL = evt.bmEventLL2 = evt.bmEventLL3 = evt.bmEventLL4 = 0;
 
   | 
||
| 
     | 
||
| 
         rcode = usb_hub_get_port_status(dev, port, 4, evt.evtBuff);
 
   | 
||
| 
         if (rcode)
 
   | 
||
| 
           continue;
 
   | 
||
| 
     | 
||
| 
         if ((evt.bmStatus & USB_HUB_PORT_STATE_CHECK_DISABLED) != USB_HUB_PORT_STATE_DISABLED)
 
   | 
||
| 
         if ((bs16(&evt.bmStatusL) & USB_HUB_PORT_STATE_CHECK_DISABLED) != USB_HUB_PORT_STATE_DISABLED)
 
   | 
||
| 
           continue;
 
   | 
||
| 
     | 
||
| 
         // Emulate connection event for the port
 
   | 
||
| 
         evt.bmChange |= USB_HUB_PORT_STATUS_PORT_CONNECTION;
 
   | 
||
| 
         evt.bmChangeL |= 0xff&(USB_HUB_PORT_STATUS_PORT_CONNECTION);
 
   | 
||
| 
         evt.bmChangeH |= (USB_HUB_PORT_STATUS_PORT_CONNECTION)>>8;
 
   | 
||
| 
     | 
||
| 
         rcode = usb_hub_port_status_change(dev, port, evt);
 
   | 
||
| 
         if (rcode == HUB_ERROR_PORT_HAS_BEEN_RESET)
 
   | 
||
| ... | ... | |
| 
     | 
||
| 
       if (info->qNextPollTime <= timer_get_msec()) {
 
   | 
||
| 
         rcode = usb_hub_check_hub_status(dev, info->bNbrPorts);
 
   | 
||
| 
         info->qNextPollTime = timer_get_msec() + 100;   // poll 10 times a second
 
   | 
||
| 
         //info->qNextPollTime = timer_get_msec() + 100;   // poll 10 times a second 
 
   | 
||
| 
         info->qNextPollTime = timer_get_msec() + 2000;   // poll every 2 seconds
 
   | 
||
| 
       }
 
   | 
||
| 
     | 
||
| 
       return rcode;
 
   | 
||
| firmware/usb/hub.h | ||
|---|---|---|
| 
       uint8_t bDescriptorType;	// descriptor type
 
   | 
||
| 
       uint8_t bNbrPorts;		// number of ports a hub equiped with
 
   | 
||
| 
     | 
||
| 
       struct {
 
   | 
||
| 
      /* struct {
 
   | 
||
| 
         uint16_t LogPwrSwitchMode	     : 2;
 
   | 
||
| 
         uint16_t CompoundDevice	     : 1;
 
   | 
||
| 
         uint16_t OverCurrentProtectMode  : 2;
 
   | 
||
| 
         uint16_t TTThinkTime	     : 2;
 
   | 
||
| 
         uint16_t PortIndicatorsSupported : 1;
 
   | 
||
| 
         uint16_t Reserved		     : 8;
 
   | 
||
| 
       } __attribute__((packed));
 
   | 
||
| 
       } __attribute__((packed));*/
 
   | 
||
| 
       uint8_t bCharacteristicsL;
 
   | 
||
| 
       uint8_t bCharacteristicsH;
 
   | 
||
| 
     | 
||
| 
       uint8_t bPwrOn2PwrGood;
 
   | 
||
| 
       uint8_t bHubContrCurrent;
 
   | 
||
| ... | ... | |
| 
     typedef struct {
 
   | 
||
| 
       union {
 
   | 
||
| 
         struct {
 
   | 
||
| 
           uint16_t bmStatus;	// port status bits
 
   | 
||
| 
           uint16_t bmChange;	// port status change bits
 
   | 
||
| 
           uint8_t bmStatusL;	// port status bits
 
   | 
||
| 
           uint8_t bmStatusH;	// port status bits
 
   | 
||
| 
           uint8_t bmChangeL;	// port status change bits
 
   | 
||
| 
           uint8_t bmChangeH;	// port status change bits
 
   | 
||
| 
         } __attribute__((packed));
 
   | 
||
| 
         uint32_t bmEvent;
 
   | 
||
| 
         uint8_t bmEventLL;
 
   | 
||
| 
         uint8_t bmEventLL2;
 
   | 
||
| 
         uint8_t bmEventLL3;
 
   | 
||
| 
         uint8_t bmEventLL4;
 
   | 
||
| 
         uint8_t  evtBuff[4];
 
   | 
||
| 
       } __attribute__((packed));
 
   | 
||
| 
     }__attribute__((packed)) hub_event_t;
 
   | 
||
| firmware/usb/keycodes.h | ||
|---|---|---|
| 
     // http://wiki.amigaos.net/index.php/Keymap_Library
 
   | 
||
| 
     // http://www.win.tue.nl/~aeb/linux/kbd/scancodes-14.html
 
   | 
||
| 
     | 
||
| 
     #define MISS  0xff
 
   | 
||
| 
     #define KEYCODE_MAX (0x6f)
 
   | 
||
| 
     | 
||
| 
     // The original minimig had the keyboard connected to the FPGA. Thus all key events (even for OSD)
 
   | 
||
| 
     // came from the FPGA core. The MIST has the keyboard attached to the arm controller. To be compatible
 
   | 
||
| 
     // with the minimig core all keys (incl. OSD!) are forwarded to the FPGA and the OSD keys are returned.
 
   | 
||
| 
     // These keys are tagged with the "OSD" flag
 
   | 
||
| 
     // The atari/mist core does not forwards keys through the FPGA but queues them inside the arm controller.
 
   | 
||
| 
     // These keys are tagged with the "OSD_LOC" flag. The keycodes itself used are identical between OSD
 
   | 
||
| 
     // and OSD_LOC
 
   | 
||
| 
     | 
||
| 
     #define OSD               0x0100     // to be used by OSD, not the core itself
 
   | 
||
| 
     #define OSD_LOC           0x0200     // OSD key not forwarded to core, but queued in arm controller
 
   | 
||
| 
     #define CAPS_LOCK_TOGGLE  0x0400     // caps lock toggle behaviour
 
   | 
||
| 
     #define NUM_LOCK_TOGGLE   0x0800
 
   | 
||
| 
     #define EXT               0x1000     // extended PS/2 keycode
 
   | 
||
| 
     | 
||
| 
     const unsigned short ps2_modifier[] = 
 
   | 
||
| 
           { 0x14, 0x12, 0x11, EXT|0x1f, EXT|0x14, 0x59, EXT|0x11, EXT|0x27 };
 
   | 
||
| 
     | 
||
| 
     // keycode translation table for ps2 emulation
 
   | 
||
| 
     const unsigned short usb2ps2[] = {
 
   | 
||
| 
       MISS,  // 00: NoEvent
 
   | 
||
| 
       MISS,  // 01: Overrun Error
 
   | 
||
| 
       MISS,  // 02: POST fail
 
   | 
||
| 
       MISS,  // 03: ErrorUndefined
 
   | 
||
| 
       0x1c,  // 04: a
 
   | 
||
| 
       0x32,  // 05: b
 
   | 
||
| 
       0x21,  // 06: c
 
   | 
||
| 
       0x23,  // 07: d
 
   | 
||
| 
       0x24,  // 08: e
 
   | 
||
| 
       0x2b,  // 09: f
 
   | 
||
| 
       0x34,  // 0a: g
 
   | 
||
| 
       0x33,  // 0b: h
 
   | 
||
| 
       0x43,  // 0c: i
 
   | 
||
| 
       0x3b,  // 0d: j
 
   | 
||
| 
       0x42,  // 0e: k
 
   | 
||
| 
       0x4b,  // 0f: l
 
   | 
||
| 
       0x3a,  // 10: m
 
   | 
||
| 
       0x31,  // 11: n
 
   | 
||
| 
       0x44,  // 12: o
 
   | 
||
| 
       0x4d,  // 13: p
 
   | 
||
| 
       0x15,  // 14: q
 
   | 
||
| 
       0x2d,  // 15: r
 
   | 
||
| 
       0x1b,  // 16: s
 
   | 
||
| 
       0x2c,  // 17: t
 
   | 
||
| 
       0x3c,  // 18: u
 
   | 
||
| 
       0x2a,  // 19: v
 
   | 
||
| 
       0x1d,  // 1a: w
 
   | 
||
| 
       0x22,  // 1b: x
 
   | 
||
| 
       0x35,  // 1c: y
 
   | 
||
| 
       0x1a,  // 1d: z
 
   | 
||
| 
       0x16,  // 1e: 1
 
   | 
||
| 
       0x1e,  // 1f: 2
 
   | 
||
| 
       0x26,  // 20: 3
 
   | 
||
| 
       0x25,  // 21: 4
 
   | 
||
| 
       0x2e,  // 22: 5
 
   | 
||
| 
       0x36,  // 23: 6
 
   | 
||
| 
       0x3d,  // 24: 7
 
   | 
||
| 
       0x3e,  // 25: 8
 
   | 
||
| 
       0x46,  // 26: 9
 
   | 
||
| 
       0x45,  // 27: 0
 
   | 
||
| 
       0x5a,  // 28: Return
 
   | 
||
| 
       0x76,  // 29: Escape
 
   | 
||
| 
       0x66,  // 2a: Backspace
 
   | 
||
| 
       0x0d,  // 2b: Tab
 
   | 
||
| 
       0x29,  // 2c: Space
 
   | 
||
| 
       0x4e,  // 2d: -
 
   | 
||
| 
       0x55,  // 2e: =
 
   | 
||
| 
       0x54,  // 2f: [
 
   | 
||
| 
       0x5b,  // 30: ]
 
   | 
||
| 
       0x5d,  // 31: backslash
 
   | 
||
| 
       0x5d,  // 32: Europe 1
 
   | 
||
| 
       0x4c,  // 33: ; 
 
   | 
||
| 
       0x52,  // 34: '
 
   | 
||
| 
       0x0e,  // 35: `
 
   | 
||
| 
       0x41,  // 36: ,
 
   | 
||
| 
       0x49,  // 37: .
 
   | 
||
| 
       0x4a,  // 38: /
 
   | 
||
| 
       0x58,  // 39: Caps Lock
 
   | 
||
| 
       0x05,  // 3a: F1
 
   | 
||
| 
       0x06,  // 3b: F2
 
   | 
||
| 
       0x04,  // 3c: F3
 
   | 
||
| 
       0x0c,  // 3d: F4
 
   | 
||
| 
       0x03,  // 3e: F5
 
   | 
||
| 
       0x0b,  // 3f: F6
 
   | 
||
| 
       0x83,  // 40: F7
 
   | 
||
| 
       0x0a,  // 41: F8
 
   | 
||
| 
       0x01,  // 42: F9
 
   | 
||
| 
       0x09,  // 43: F10
 
   | 
||
| 
       0x78,  // 44: F11
 
   | 
||
| 
       OSD_LOC | 0x07,  // 45: F12 (OSD)
 
   | 
||
| 
       EXT | 0x7c, // 46: Print Screen
 
   | 
||
| 
       NUM_LOCK_TOGGLE,  // 47: Scroll Lock
 
   | 
||
| 
       0x77,  // 48: Pause (special key handled inside user_io)
 
   | 
||
| 
       EXT | 0x70, // 49: Insert
 
   | 
||
| 
       EXT | 0x6c, // 4a: Home
 
   | 
||
| 
       EXT | 0x7d, // 4b: Page Up
 
   | 
||
| 
       EXT | 0x71, // 4c: Delete
 
   | 
||
| 
       EXT | 0x69, // 4d: End
 
   | 
||
| 
       EXT | 0x7a, // 4e: Page Down
 
   | 
||
| 
       EXT | 0x74, // 4f: Right Arrow
 
   | 
||
| 
       EXT | 0x6b, // 50: Left Arrow
 
   | 
||
| 
       EXT | 0x72, // 51: Down Arrow
 
   | 
||
| 
       EXT | 0x75, // 52: Up Arrow
 
   | 
||
| 
       NUM_LOCK_TOGGLE,  // 53: Num Lock
 
   | 
||
| 
       EXT | 0x4a, // 54: KP /
 
   | 
||
| 
       0x7c,  // 55: KP *
 
   | 
||
| 
       0x7b,  // 56: KP -
 
   | 
||
| 
       0x79,  // 57: KP +
 
   | 
||
| 
       EXT | 0x5a, // 58: KP Enter
 
   | 
||
| 
       0x69,  // 59: KP 1
 
   | 
||
| 
       0x72,  // 5a: KP 2
 
   | 
||
| 
       0x7a,  // 5b: KP 3
 
   | 
||
| 
       0x6b,  // 5c: KP 4
 
   | 
||
| 
       0x73,  // 5d: KP 5
 
   | 
||
| 
       0x74,  // 5e: KP 6
 
   | 
||
| 
       0x6c,  // 5f: KP 7
 
   | 
||
| 
       0x75,  // 60: KP 8
 
   | 
||
| 
       0x7d,  // 61: KP 9
 
   | 
||
| 
       0x70,  // 62: KP 0
 
   | 
||
| 
       0x71,  // 63: KP .
 
   | 
||
| 
       0x61,  // 64: Europe 2
 
   | 
||
| 
       EXT | 0x2f, // 65: App
 
   | 
||
| 
       EXT | 0x37, // 66: Power
 
   | 
||
| 
       0x0f,  // 67: KP =
 
   | 
||
| 
       0x08,  // 68: F13
 
   | 
||
| 
       0x10,  // 69: F14
 
   | 
||
| 
       0x18,  // 6a: F15
 
   | 
||
| 
       0x20,  // 6b: F16
 
   | 
||
| 
       0x28,  // 6c: F17
 
   | 
||
| 
       0x30,  // 6d: F18
 
   | 
||
| 
       0x38,  // 6e: F19
 
   | 
||
| 
       0x40   // 6f: F20
 
   | 
||
| 
     };
 
   | 
||
| 
     | 
||
| firmware/usb/timer.c | ||
|---|---|---|
| 
     #include "timer.h"
 
   | 
||
| 
     #include "regs.h"
 
   | 
||
| 
     | 
||
| 
     // this is a 32 bit counter which overflows after 2^32 milliseconds
 
   | 
||
| 
     // -> after 46 days
 
   | 
||
| ... | ... | |
| 
     void wait_us(int unsigned num);
 
   | 
||
| 
     | 
||
| 
     void timer_init() {
 
   | 
||
| 
     	// TODO - set zpu to 0...
 
   | 
||
| 
     }
 
   | 
||
| 
     | 
||
| 
     #ifdef LINUX_BUILD
 
   | 
||
| 
     #include <sys/time.h>
 
   | 
||
| 
     msec_t timer_get_msec() {
 
   | 
||
| 
     	return 0; // TODO - read from ZPU
 
   | 
||
| 
     	struct timeval x;
 
   | 
||
| 
     	gettimeofday(&x,0);
 
   | 
||
| 
     	return (x.tv_sec*1000+(x.tv_usec/1000));
 
   | 
||
| 
     }
 
   | 
||
| 
     #else
 
   | 
||
| 
     msec_t timer_get_msec() {
 
   | 
||
| 
     	int res = *zpu_timer;
 
   | 
||
| 
     	return res;
 
   | 
||
| 
     }
 
   | 
||
| 
     #endif
 
   | 
||
| 
     | 
||
USB now working, feeding events to core. Still some bugs remaining - such as clash with drive emulation.