ADB fixes
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@965 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
		
							parent
							
								
									637f6cd735
								
							
						
					
					
						commit
						e2733d20b2
					
				
							
								
								
									
										248
									
								
								hw/adb.c
								
								
								
								
							
							
						
						
									
										248
									
								
								hw/adb.c
								
								
								
								
							| 
						 | 
				
			
			@ -43,53 +43,53 @@
 | 
			
		|||
#define ADB_MODEM	5
 | 
			
		||||
#define ADB_MISC	7
 | 
			
		||||
 | 
			
		||||
#define ADB_RET_OK			0
 | 
			
		||||
#define ADB_RET_INUSE			1
 | 
			
		||||
#define ADB_RET_NOTPRESENT		2
 | 
			
		||||
#define ADB_RET_TIMEOUT			3
 | 
			
		||||
#define ADB_RET_UNEXPECTED_RESULT	4
 | 
			
		||||
#define ADB_RET_REQUEST_ERROR		5
 | 
			
		||||
#define ADB_RET_BUS_ERROR		6
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void adb_send_packet1(ADBBusState *s, uint8_t reply)
 | 
			
		||||
{
 | 
			
		||||
    adb_send_packet(s, &reply, 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void adb_receive_packet(ADBBusState *s, const uint8_t *buf, int len)
 | 
			
		||||
int adb_request(ADBBusState *s, uint8_t *obuf, const uint8_t *buf, int len)
 | 
			
		||||
{
 | 
			
		||||
    ADBDevice *d;
 | 
			
		||||
    int devaddr, cmd, i;
 | 
			
		||||
    uint8_t obuf[4];
 | 
			
		||||
 | 
			
		||||
    cmd = buf[0] & 0xf;
 | 
			
		||||
    devaddr = buf[0] >> 4;
 | 
			
		||||
    if (buf[1] == ADB_BUSRESET) {
 | 
			
		||||
        obuf[0] = 0x00;
 | 
			
		||||
        obuf[1] = 0x00;
 | 
			
		||||
        adb_send_packet(s, obuf, 2);
 | 
			
		||||
        return;
 | 
			
		||||
        return 2;
 | 
			
		||||
    }
 | 
			
		||||
    if (cmd == ADB_FLUSH) {
 | 
			
		||||
        obuf[0] = 0x00;
 | 
			
		||||
        obuf[1] = 0x00;
 | 
			
		||||
        adb_send_packet(s, obuf, 2);
 | 
			
		||||
        return;
 | 
			
		||||
        return 2;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for(i = 0; i < s->nb_devices; i++) {
 | 
			
		||||
        d = &s->devices[i];
 | 
			
		||||
        if (d->devaddr == devaddr) {
 | 
			
		||||
            d->receive_packet(d, buf, len);
 | 
			
		||||
            return;
 | 
			
		||||
            return d->devreq(d, obuf, buf, len);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    adb_send_packet1(s, ADB_RET_NOTPRESENT);
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int adb_poll(ADBBusState *s, uint8_t *obuf)
 | 
			
		||||
{
 | 
			
		||||
    ADBDevice *d;
 | 
			
		||||
    int olen, i;
 | 
			
		||||
 | 
			
		||||
    olen = 0;
 | 
			
		||||
    for(i = 0; i < s->nb_devices; i++) {
 | 
			
		||||
        if (s->poll_index >= s->nb_devices)
 | 
			
		||||
            s->poll_index = 0;
 | 
			
		||||
        d = &s->devices[s->poll_index];
 | 
			
		||||
        olen = d->devreq(d, obuf, NULL, 0);
 | 
			
		||||
        s->poll_index++;
 | 
			
		||||
        if (olen)
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
    return olen;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ADBDevice *adb_register_device(ADBBusState *s, int devaddr, 
 | 
			
		||||
                               ADBDeviceReceivePacket *receive_packet, 
 | 
			
		||||
                               ADBDeviceRequest *devreq, 
 | 
			
		||||
                               void *opaque)
 | 
			
		||||
{
 | 
			
		||||
    ADBDevice *d;
 | 
			
		||||
| 
						 | 
				
			
			@ -98,7 +98,7 @@ ADBDevice *adb_register_device(ADBBusState *s, int devaddr,
 | 
			
		|||
    d = &s->devices[s->nb_devices++];
 | 
			
		||||
    d->bus = s;
 | 
			
		||||
    d->devaddr = devaddr;
 | 
			
		||||
    d->receive_packet = receive_packet;
 | 
			
		||||
    d->devreq = devreq;
 | 
			
		||||
    d->opaque = opaque;
 | 
			
		||||
    return d;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -106,80 +106,108 @@ ADBDevice *adb_register_device(ADBBusState *s, int devaddr,
 | 
			
		|||
/***************************************************************/
 | 
			
		||||
/* Keyboard ADB device */
 | 
			
		||||
 | 
			
		||||
typedef struct KBDState {
 | 
			
		||||
    uint8_t data[128];
 | 
			
		||||
    int rptr, wptr, count;
 | 
			
		||||
} KBDState;
 | 
			
		||||
 | 
			
		||||
static const uint8_t pc_to_adb_keycode[256] = {
 | 
			
		||||
  0, 53, 18, 19, 20, 21, 23, 22, 26, 28, 25, 29, 27, 24, 51, 48,
 | 
			
		||||
 12, 13, 14, 15, 17, 16, 32, 34, 31, 35, 33, 30, 36, 54,  0,  1,
 | 
			
		||||
  2,  3,  5,  4, 38, 40, 37, 41, 39, 50, 56, 42,  6,  7,  8,  9,
 | 
			
		||||
 11, 45, 46, 43, 47, 44,123, 67, 58, 49, 57,122,120, 99,118, 96,
 | 
			
		||||
 97, 98,100,101,109, 71,107, 89, 91, 92, 78, 86, 87, 88, 69, 83,
 | 
			
		||||
 84, 85, 82, 65,  0,  0, 10,103,111,  0,  0,  0,  0,  0,  0,  0,
 | 
			
		||||
 76,125, 75,105,124,110,115, 62,116, 59, 60,119, 61,121,114,117,
 | 
			
		||||
  0,  0,  0,  0,127, 81,  0,113,  0,  0,  0,  0, 95, 55,  0,  0,
 | 
			
		||||
  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
 | 
			
		||||
  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
 | 
			
		||||
  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
 | 
			
		||||
  0,  0,  0,  0,  0, 94,  0, 93,  0,  0,  0,  0,  0,  0,104,102,
 | 
			
		||||
  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
 | 
			
		||||
 84, 85, 82, 65,  0,  0, 10,103,111,  0,  0,110, 81,  0,  0,  0,
 | 
			
		||||
  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
 | 
			
		||||
  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
 | 
			
		||||
  0,  0,  0, 94,  0, 93,  0,  0,  0,  0,  0,  0,104,102,  0,  0,
 | 
			
		||||
  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 76,125,  0,  0,
 | 
			
		||||
  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,105,  0,  0,  0,  0,  0,
 | 
			
		||||
  0,  0,  0,  0,  0, 75,  0,  0,124,  0,  0,  0,  0,  0,  0,  0,
 | 
			
		||||
  0,  0,  0,  0,  0,  0,  0,115, 62,116,  0, 59,  0, 60,  0,119,
 | 
			
		||||
 61,121,114,117,  0,  0,  0,  0,  0,  0,  0, 55,126,  0,127,  0,
 | 
			
		||||
  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
 | 
			
		||||
  0,  0,  0,  0,  0, 95,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void adb_kbd_put_keycode(void *opaque, int keycode)
 | 
			
		||||
{
 | 
			
		||||
    static int ext_keycode;
 | 
			
		||||
    ADBDevice *d = opaque;
 | 
			
		||||
    uint8_t buf[4];
 | 
			
		||||
    int adb_keycode;
 | 
			
		||||
    
 | 
			
		||||
    if (keycode == 0xe0) {
 | 
			
		||||
        ext_keycode = 1;
 | 
			
		||||
    } else {
 | 
			
		||||
        
 | 
			
		||||
        if (ext_keycode)
 | 
			
		||||
            adb_keycode =  pc_to_adb_keycode[keycode | 0x80];
 | 
			
		||||
        else
 | 
			
		||||
            adb_keycode =  pc_to_adb_keycode[keycode & 0x7f];
 | 
			
		||||
            
 | 
			
		||||
        buf[0] = 0x40;
 | 
			
		||||
        buf[1] = (d->devaddr << 4) | 0x0c;
 | 
			
		||||
        buf[2] = adb_keycode | (keycode & 0x80);
 | 
			
		||||
        buf[3] = 0xff;
 | 
			
		||||
        adb_send_packet(d->bus, buf, 4);
 | 
			
		||||
        ext_keycode = 0;
 | 
			
		||||
    KBDState *s = d->opaque;
 | 
			
		||||
 | 
			
		||||
    if (s->count < sizeof(s->data)) {
 | 
			
		||||
        s->data[s->wptr] = keycode;
 | 
			
		||||
        if (++s->wptr == sizeof(s->data))
 | 
			
		||||
            s->wptr = 0;
 | 
			
		||||
        s->count++;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void adb_kbd_receive_packet(ADBDevice *d, const uint8_t *buf, int len)
 | 
			
		||||
static int adb_kbd_poll(ADBDevice *d, uint8_t *obuf)
 | 
			
		||||
{
 | 
			
		||||
    int cmd, reg;
 | 
			
		||||
    uint8_t obuf[4];
 | 
			
		||||
    static int ext_keycode;
 | 
			
		||||
    KBDState *s = d->opaque;
 | 
			
		||||
    int adb_keycode, keycode;
 | 
			
		||||
    int olen;
 | 
			
		||||
 | 
			
		||||
    olen = 0;
 | 
			
		||||
    for(;;) {
 | 
			
		||||
        if (s->count == 0)
 | 
			
		||||
            break;
 | 
			
		||||
        keycode = s->data[s->rptr];
 | 
			
		||||
        if (++s->rptr == sizeof(s->data))
 | 
			
		||||
            s->rptr = 0;
 | 
			
		||||
        s->count--;
 | 
			
		||||
 | 
			
		||||
        if (keycode == 0xe0) {
 | 
			
		||||
            ext_keycode = 1;
 | 
			
		||||
        } else {
 | 
			
		||||
            if (ext_keycode)
 | 
			
		||||
                adb_keycode =  pc_to_adb_keycode[keycode | 0x80];
 | 
			
		||||
            else
 | 
			
		||||
                adb_keycode =  pc_to_adb_keycode[keycode & 0x7f];
 | 
			
		||||
            obuf[0] = (d->devaddr << 4) | 0x0c;
 | 
			
		||||
            obuf[1] = adb_keycode | (keycode & 0x80);
 | 
			
		||||
            obuf[2] = 0xff;
 | 
			
		||||
            olen = 3;
 | 
			
		||||
            ext_keycode = 0;
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return olen;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int adb_kbd_request(ADBDevice *d, uint8_t *obuf,
 | 
			
		||||
                           const uint8_t *buf, int len)
 | 
			
		||||
{
 | 
			
		||||
    int cmd, reg, olen;
 | 
			
		||||
 | 
			
		||||
    if (!buf) {
 | 
			
		||||
        return adb_kbd_poll(d, obuf);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    cmd = buf[0] & 0xc;
 | 
			
		||||
    reg = buf[0] & 0x3;
 | 
			
		||||
    olen = 0;
 | 
			
		||||
    switch(cmd) {
 | 
			
		||||
    case ADB_WRITEREG:
 | 
			
		||||
        switch(reg) {
 | 
			
		||||
        case 2:
 | 
			
		||||
            /* LED status */
 | 
			
		||||
            adb_send_packet1(d->bus, ADB_RET_OK);
 | 
			
		||||
            break;
 | 
			
		||||
        case 3:
 | 
			
		||||
            switch(buf[2]) {
 | 
			
		||||
            case ADB_CMD_SELF_TEST:
 | 
			
		||||
                adb_send_packet1(d->bus, ADB_RET_OK);
 | 
			
		||||
                break;
 | 
			
		||||
            case ADB_CMD_CHANGE_ID:
 | 
			
		||||
            case ADB_CMD_CHANGE_ID_AND_ACT:
 | 
			
		||||
            case ADB_CMD_CHANGE_ID_AND_ENABLE:
 | 
			
		||||
                d->devaddr = buf[1] & 0xf;
 | 
			
		||||
                adb_send_packet1(d->bus, ADB_RET_OK);
 | 
			
		||||
                break;
 | 
			
		||||
            default:
 | 
			
		||||
                /* XXX: check this */
 | 
			
		||||
                d->devaddr = buf[1] & 0xf;
 | 
			
		||||
                d->handler = buf[2];
 | 
			
		||||
                adb_send_packet1(d->bus, ADB_RET_OK);
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -187,98 +215,122 @@ static void adb_kbd_receive_packet(ADBDevice *d, const uint8_t *buf, int len)
 | 
			
		|||
    case ADB_READREG:
 | 
			
		||||
        switch(reg) {
 | 
			
		||||
        case 1:
 | 
			
		||||
            adb_send_packet1(d->bus, ADB_RET_OK);
 | 
			
		||||
            break;
 | 
			
		||||
        case 2:
 | 
			
		||||
            obuf[0] = ADB_RET_OK;
 | 
			
		||||
            obuf[1] = 0x00; /* XXX: check this */
 | 
			
		||||
            obuf[2] = 0x07; /* led status */
 | 
			
		||||
            adb_send_packet(d->bus, obuf, 3);
 | 
			
		||||
            obuf[0] = 0x00; /* XXX: check this */
 | 
			
		||||
            obuf[1] = 0x07; /* led status */
 | 
			
		||||
            olen = 2;
 | 
			
		||||
            break;
 | 
			
		||||
        case 3:
 | 
			
		||||
            obuf[0] = ADB_RET_OK;
 | 
			
		||||
            obuf[1] = d->handler;
 | 
			
		||||
            obuf[2] = d->devaddr;
 | 
			
		||||
            adb_send_packet(d->bus, obuf, 3);
 | 
			
		||||
            obuf[0] = d->handler;
 | 
			
		||||
            obuf[1] = d->devaddr;
 | 
			
		||||
            olen = 2;
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
    return olen;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void adb_kbd_init(ADBBusState *bus)
 | 
			
		||||
{
 | 
			
		||||
    ADBDevice *d;
 | 
			
		||||
 | 
			
		||||
    d = adb_register_device(bus, ADB_KEYBOARD, adb_kbd_receive_packet, NULL);
 | 
			
		||||
    KBDState *s;
 | 
			
		||||
    s = qemu_mallocz(sizeof(KBDState));
 | 
			
		||||
    d = adb_register_device(bus, ADB_KEYBOARD, adb_kbd_request, s);
 | 
			
		||||
    d->handler = 1;
 | 
			
		||||
    qemu_add_kbd_event_handler(adb_kbd_put_keycode, d);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/***************************************************************/
 | 
			
		||||
/* Mouse ADB device */
 | 
			
		||||
 | 
			
		||||
typedef struct MouseState {
 | 
			
		||||
    int buttons_state, last_buttons_state;
 | 
			
		||||
    int dx, dy, dz;
 | 
			
		||||
} MouseState;
 | 
			
		||||
 | 
			
		||||
static void adb_mouse_event(void *opaque,
 | 
			
		||||
                            int dx1, int dy1, int dz1, int buttons_state)
 | 
			
		||||
{
 | 
			
		||||
    ADBDevice *d = opaque;
 | 
			
		||||
    uint8_t buf[4];
 | 
			
		||||
    MouseState *s = d->opaque;
 | 
			
		||||
 | 
			
		||||
    s->dx += dx1;
 | 
			
		||||
    s->dy += dy1;
 | 
			
		||||
    s->dz += dz1;
 | 
			
		||||
    s->buttons_state = buttons_state;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static int adb_mouse_poll(ADBDevice *d, uint8_t *obuf)
 | 
			
		||||
{
 | 
			
		||||
    MouseState *s = d->opaque;
 | 
			
		||||
    int dx, dy;
 | 
			
		||||
 | 
			
		||||
    dx = dx1;
 | 
			
		||||
    if (s->last_buttons_state == s->buttons_state &&
 | 
			
		||||
        s->dx == 0 && s->dy == 0)
 | 
			
		||||
        return 0;
 | 
			
		||||
        
 | 
			
		||||
    dx = s->dx;
 | 
			
		||||
    if (dx < -63)
 | 
			
		||||
        dx = -63;
 | 
			
		||||
    else if (dx > 63)
 | 
			
		||||
        dx = 63;
 | 
			
		||||
 | 
			
		||||
    dy = dy1;
 | 
			
		||||
    
 | 
			
		||||
    dy = s->dy;
 | 
			
		||||
    if (dy < -63)
 | 
			
		||||
        dy = -63;
 | 
			
		||||
    else if (dy > 63)
 | 
			
		||||
        dy = 63;
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
    s->dx -= dx;
 | 
			
		||||
    s->dy -= dy;
 | 
			
		||||
    s->last_buttons_state = s->buttons_state;
 | 
			
		||||
    
 | 
			
		||||
    dx &= 0x7f;
 | 
			
		||||
    dy &= 0x7f;
 | 
			
		||||
 | 
			
		||||
    if (buttons_state & MOUSE_EVENT_LBUTTON)
 | 
			
		||||
    
 | 
			
		||||
    if (s->buttons_state & MOUSE_EVENT_LBUTTON)
 | 
			
		||||
        dy |= 0x80;
 | 
			
		||||
    if (buttons_state & MOUSE_EVENT_RBUTTON)
 | 
			
		||||
    if (s->buttons_state & MOUSE_EVENT_RBUTTON)
 | 
			
		||||
        dx |= 0x80;
 | 
			
		||||
 | 
			
		||||
    buf[0] = 0x40;
 | 
			
		||||
    buf[1] = (d->devaddr << 4) | 0x0c;
 | 
			
		||||
    buf[2] = dy;
 | 
			
		||||
    buf[3] = dx;
 | 
			
		||||
    adb_send_packet(d->bus, buf, 4);
 | 
			
		||||
    
 | 
			
		||||
    obuf[0] = (d->devaddr << 4) | 0x0c;
 | 
			
		||||
    obuf[1] = dy;
 | 
			
		||||
    obuf[2] = dx;
 | 
			
		||||
    return 3;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void adb_mouse_receive_packet(ADBDevice *d, const uint8_t *buf, int len)
 | 
			
		||||
static int adb_mouse_request(ADBDevice *d, uint8_t *obuf,
 | 
			
		||||
                             const uint8_t *buf, int len)
 | 
			
		||||
{
 | 
			
		||||
    int cmd, reg;
 | 
			
		||||
    uint8_t obuf[4];
 | 
			
		||||
    int cmd, reg, olen;
 | 
			
		||||
    
 | 
			
		||||
    if (!buf) {
 | 
			
		||||
        return adb_mouse_poll(d, obuf);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    cmd = buf[0] & 0xc;
 | 
			
		||||
    reg = buf[0] & 0x3;
 | 
			
		||||
    olen = 0;
 | 
			
		||||
    switch(cmd) {
 | 
			
		||||
    case ADB_WRITEREG:
 | 
			
		||||
        switch(reg) {
 | 
			
		||||
        case 2:
 | 
			
		||||
            adb_send_packet1(d->bus, ADB_RET_OK);
 | 
			
		||||
            break;
 | 
			
		||||
        case 3:
 | 
			
		||||
            switch(buf[2]) {
 | 
			
		||||
            case ADB_CMD_SELF_TEST:
 | 
			
		||||
                adb_send_packet1(d->bus, ADB_RET_OK);
 | 
			
		||||
                break;
 | 
			
		||||
            case ADB_CMD_CHANGE_ID:
 | 
			
		||||
            case ADB_CMD_CHANGE_ID_AND_ACT:
 | 
			
		||||
            case ADB_CMD_CHANGE_ID_AND_ENABLE:
 | 
			
		||||
                d->devaddr = buf[1] & 0xf;
 | 
			
		||||
                adb_send_packet1(d->bus, ADB_RET_OK);
 | 
			
		||||
                break;
 | 
			
		||||
            default:
 | 
			
		||||
                /* XXX: check this */
 | 
			
		||||
                d->devaddr = buf[1] & 0xf;
 | 
			
		||||
                adb_send_packet1(d->bus, ADB_RET_OK);
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -286,23 +338,25 @@ static void adb_mouse_receive_packet(ADBDevice *d, const uint8_t *buf, int len)
 | 
			
		|||
    case ADB_READREG:
 | 
			
		||||
        switch(reg) {
 | 
			
		||||
        case 1:
 | 
			
		||||
            adb_send_packet1(d->bus, ADB_RET_OK);
 | 
			
		||||
            break;
 | 
			
		||||
        case 3:
 | 
			
		||||
            obuf[0] = ADB_RET_OK;
 | 
			
		||||
            obuf[1] = d->handler;
 | 
			
		||||
            obuf[2] = d->devaddr;
 | 
			
		||||
            adb_send_packet(d->bus, obuf, 3);
 | 
			
		||||
            obuf[0] = d->handler;
 | 
			
		||||
            obuf[1] = d->devaddr;
 | 
			
		||||
            olen = 2;
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
    return olen;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void adb_mouse_init(ADBBusState *bus)
 | 
			
		||||
{
 | 
			
		||||
    ADBDevice *d;
 | 
			
		||||
    MouseState *s;
 | 
			
		||||
 | 
			
		||||
    d = adb_register_device(bus, ADB_MOUSE, adb_mouse_receive_packet, NULL);
 | 
			
		||||
    s = qemu_mallocz(sizeof(MouseState));
 | 
			
		||||
    d = adb_register_device(bus, ADB_MOUSE, adb_mouse_request, s);
 | 
			
		||||
    d->handler = 2;
 | 
			
		||||
    qemu_add_mouse_event_handler(adb_mouse_event, d);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										50
									
								
								hw/cuda.c
								
								
								
								
							
							
						
						
									
										50
									
								
								hw/cuda.c
								
								
								
								
							| 
						 | 
				
			
			@ -85,6 +85,7 @@
 | 
			
		|||
#define CUDA_COMBINED_FORMAT_IIC	0x25
 | 
			
		||||
 | 
			
		||||
#define CUDA_TIMER_FREQ (4700000 / 6)
 | 
			
		||||
#define CUDA_ADB_POLL_FREQ 50
 | 
			
		||||
 | 
			
		||||
typedef struct CUDATimer {
 | 
			
		||||
    unsigned int latch;
 | 
			
		||||
| 
						 | 
				
			
			@ -121,6 +122,7 @@ typedef struct CUDAState {
 | 
			
		|||
    uint8_t autopoll;
 | 
			
		||||
    uint8_t data_in[128];
 | 
			
		||||
    uint8_t data_out[16];
 | 
			
		||||
    QEMUTimer *adb_poll_timer;
 | 
			
		||||
} CUDAState;
 | 
			
		||||
 | 
			
		||||
static CUDAState cuda_state;
 | 
			
		||||
| 
						 | 
				
			
			@ -469,15 +471,42 @@ void adb_send_packet(ADBBusState *bus, const uint8_t *buf, int len)
 | 
			
		|||
    cuda_send_packet_to_host(s, data, len + 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cuda_adb_poll(void *opaque)
 | 
			
		||||
{
 | 
			
		||||
    CUDAState *s = opaque;
 | 
			
		||||
    uint8_t obuf[ADB_MAX_OUT_LEN + 2];
 | 
			
		||||
    int olen;
 | 
			
		||||
 | 
			
		||||
    olen = adb_poll(&adb_bus, obuf + 2);
 | 
			
		||||
    if (olen > 0) {
 | 
			
		||||
        obuf[0] = ADB_PACKET;
 | 
			
		||||
        obuf[1] = 0x40; /* polled data */
 | 
			
		||||
        cuda_send_packet_to_host(s, obuf, olen + 2);
 | 
			
		||||
    }
 | 
			
		||||
    qemu_mod_timer(s->adb_poll_timer, 
 | 
			
		||||
                   qemu_get_clock(vm_clock) + 
 | 
			
		||||
                   (ticks_per_sec / CUDA_ADB_POLL_FREQ));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void cuda_receive_packet(CUDAState *s, 
 | 
			
		||||
                                const uint8_t *data, int len)
 | 
			
		||||
{
 | 
			
		||||
    uint8_t obuf[16];
 | 
			
		||||
    int ti;
 | 
			
		||||
    int ti, autopoll;
 | 
			
		||||
 | 
			
		||||
    switch(data[0]) {
 | 
			
		||||
    case CUDA_AUTOPOLL:
 | 
			
		||||
        s->autopoll = data[1];
 | 
			
		||||
        autopoll = (data[1] != 0);
 | 
			
		||||
        if (autopoll != s->autopoll) {
 | 
			
		||||
            s->autopoll = autopoll;
 | 
			
		||||
            if (autopoll) {
 | 
			
		||||
                qemu_mod_timer(s->adb_poll_timer, 
 | 
			
		||||
                               qemu_get_clock(vm_clock) + 
 | 
			
		||||
                               (ticks_per_sec / CUDA_ADB_POLL_FREQ));
 | 
			
		||||
            } else {
 | 
			
		||||
                qemu_del_timer(s->adb_poll_timer);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        obuf[0] = CUDA_PACKET;
 | 
			
		||||
        obuf[1] = data[1];
 | 
			
		||||
        cuda_send_packet_to_host(s, obuf, 2);
 | 
			
		||||
| 
						 | 
				
			
			@ -522,7 +551,20 @@ static void cuda_receive_packet_from_host(CUDAState *s,
 | 
			
		|||
#endif
 | 
			
		||||
    switch(data[0]) {
 | 
			
		||||
    case ADB_PACKET:
 | 
			
		||||
        adb_receive_packet(&adb_bus, data + 1, len - 1);
 | 
			
		||||
        {
 | 
			
		||||
            uint8_t obuf[ADB_MAX_OUT_LEN + 2];
 | 
			
		||||
            int olen;
 | 
			
		||||
            olen = adb_request(&adb_bus, obuf + 2, data + 1, len - 1);
 | 
			
		||||
            if (olen != 0) {
 | 
			
		||||
                obuf[0] = ADB_PACKET;
 | 
			
		||||
                obuf[1] = 0x00;
 | 
			
		||||
            } else {
 | 
			
		||||
                /* empty reply */
 | 
			
		||||
                obuf[0] = ADB_PACKET;
 | 
			
		||||
                obuf[1] = 0x02;
 | 
			
		||||
            }
 | 
			
		||||
            cuda_send_packet_to_host(s, obuf, olen + 2);
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
    case CUDA_PACKET:
 | 
			
		||||
        cuda_receive_packet(s, data + 1, len - 1);
 | 
			
		||||
| 
						 | 
				
			
			@ -574,6 +616,8 @@ int cuda_init(openpic_t *openpic, int irq)
 | 
			
		|||
    s->timers[1].latch = 0x10000;
 | 
			
		||||
    s->ier = T1_INT | SR_INT;
 | 
			
		||||
    set_counter(s, &s->timers[1], 0xffff);
 | 
			
		||||
 | 
			
		||||
    s->adb_poll_timer = qemu_new_timer(vm_clock, cuda_adb_poll, s);
 | 
			
		||||
    cuda_mem_index = cpu_register_io_memory(0, cuda_read, cuda_write, s);
 | 
			
		||||
    return cuda_mem_index;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										20
									
								
								vl.h
								
								
								
								
							
							
						
						
									
										20
									
								
								vl.h
								
								
								
								
							| 
						 | 
				
			
			@ -528,8 +528,7 @@ PCIBus *pci_pmac_init(void);
 | 
			
		|||
/* openpic.c */
 | 
			
		||||
typedef struct openpic_t openpic_t;
 | 
			
		||||
void openpic_set_irq (openpic_t *opp, int n_IRQ, int level);
 | 
			
		||||
openpic_t *openpic_init (PCIBus *bus,
 | 
			
		||||
                         uint32_t isu_base, uint32_t idu_base, int nb_cpus);
 | 
			
		||||
openpic_t *openpic_init (PCIBus *bus, int *pmem_index, int nb_cpus);
 | 
			
		||||
 | 
			
		||||
/* vga.c */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -727,28 +726,33 @@ int PPC_NVRAM_set_params (m48t59_t *nvram, uint16_t NVRAM_size,
 | 
			
		|||
 | 
			
		||||
#define MAX_ADB_DEVICES 16
 | 
			
		||||
 | 
			
		||||
#define ADB_MAX_OUT_LEN 16
 | 
			
		||||
 | 
			
		||||
typedef struct ADBDevice ADBDevice;
 | 
			
		||||
 | 
			
		||||
typedef void ADBDeviceReceivePacket(ADBDevice *d, const uint8_t *buf, int len);
 | 
			
		||||
 | 
			
		||||
/* buf = NULL means polling */
 | 
			
		||||
typedef int ADBDeviceRequest(ADBDevice *d, uint8_t *buf_out,
 | 
			
		||||
                              const uint8_t *buf, int len);
 | 
			
		||||
struct ADBDevice {
 | 
			
		||||
    struct ADBBusState *bus;
 | 
			
		||||
    int devaddr;
 | 
			
		||||
    int handler;
 | 
			
		||||
    ADBDeviceReceivePacket *receive_packet;
 | 
			
		||||
    ADBDeviceRequest *devreq;
 | 
			
		||||
    void *opaque;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef struct ADBBusState {
 | 
			
		||||
    ADBDevice devices[MAX_ADB_DEVICES];
 | 
			
		||||
    int nb_devices;
 | 
			
		||||
    int poll_index;
 | 
			
		||||
} ADBBusState;
 | 
			
		||||
 | 
			
		||||
void adb_receive_packet(ADBBusState *s, const uint8_t *buf, int len);
 | 
			
		||||
void adb_send_packet(ADBBusState *s, const uint8_t *buf, int len);
 | 
			
		||||
int adb_request(ADBBusState *s, uint8_t *buf_out,
 | 
			
		||||
                const uint8_t *buf, int len);
 | 
			
		||||
int adb_poll(ADBBusState *s, uint8_t *buf_out);
 | 
			
		||||
 | 
			
		||||
ADBDevice *adb_register_device(ADBBusState *s, int devaddr, 
 | 
			
		||||
                               ADBDeviceReceivePacket *receive_packet, 
 | 
			
		||||
                               ADBDeviceRequest *devreq, 
 | 
			
		||||
                               void *opaque);
 | 
			
		||||
void adb_kbd_init(ADBBusState *bus);
 | 
			
		||||
void adb_mouse_init(ADBBusState *bus);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue