/* * root hub control */ static int musb_submit_rh_msg(struct usb_device *dev, unsigned long pipe, void *buffer, int transfer_len, struct devrequest *cmd) { int leni = transfer_len; int len = 0; int stat = 0; u32 datab[4]; const u8 *data_buf = (u8 *) datab; u16 bmRType_bReq; u16 wValue; u16 wIndex; u16 wLength; u16 int_usb; if ((pipe & PIPE_INTERRUPT) == PIPE_INTERRUPT) { debug("Root-Hub submit IRQ: NOT implemented\n"); return 0; } bmRType_bReq = cmd->requesttype | (cmd->request << 8); wValue = swap_16(cmd->value); wIndex = swap_16(cmd->index); wLength = swap_16(cmd->length); debug("--- HUB ----------------------------------------\n"); debug("submit rh urb, req=%x val=%#x index=%#x len=%d\n", bmRType_bReq, wValue, wIndex, wLength); debug("------------------------------------------------\n"); switch (bmRType_bReq) { case RH_GET_STATUS: debug("RH_GET_STATUS\n"); *(__u16 *) data_buf = swap_16(1); len = 2; break; case RH_GET_STATUS | RH_INTERFACE: debug("RH_GET_STATUS | RH_INTERFACE\n"); *(__u16 *) data_buf = swap_16(0); len = 2; break; case RH_GET_STATUS | RH_ENDPOINT: debug("RH_GET_STATUS | RH_ENDPOINT\n"); *(__u16 *) data_buf = swap_16(0); len = 2; break; case RH_GET_STATUS | RH_CLASS: debug("RH_GET_STATUS | RH_CLASS\n"); *(__u32 *) data_buf = swap_32(0); len = 4; break; case RH_GET_STATUS | RH_OTHER | RH_CLASS: debug("RH_GET_STATUS | RH_OTHER | RH_CLASS\n"); int_usb = readw(&musbr->intrusb); if (int_usb & MUSB_INTR_CONNECT) { port_status |= USB_PORT_STAT_CONNECTION | (USB_PORT_STAT_C_CONNECTION << 16); port_status |= USB_PORT_STAT_HIGH_SPEED | USB_PORT_STAT_ENABLE; } if (port_status & USB_PORT_STAT_RESET) musb_port_reset(0); *(__u32 *) data_buf = swap_32(port_status); len = 4; break; case RH_CLEAR_FEATURE | RH_ENDPOINT: debug("RH_CLEAR_FEATURE | RH_ENDPOINT\n"); switch (wValue) { case RH_ENDPOINT_STALL: debug("C_HUB_ENDPOINT_STALL\n"); len = 0; break; } port_status &= ~(1 << wValue); break; case RH_CLEAR_FEATURE | RH_CLASS: debug("RH_CLEAR_FEATURE | RH_CLASS\n"); switch (wValue) { case RH_C_HUB_LOCAL_POWER: debug("C_HUB_LOCAL_POWER\n"); len = 0; break; case RH_C_HUB_OVER_CURRENT: debug("C_HUB_OVER_CURRENT\n"); len = 0; break; } port_status &= ~(1 << wValue); break; case RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS: debug("RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS\n"); switch (wValue) { case RH_PORT_ENABLE: len = 0; break; case RH_PORT_SUSPEND: len = 0; break; case RH_PORT_POWER: len = 0; break; case RH_C_PORT_CONNECTION: len = 0; break; case RH_C_PORT_ENABLE: len = 0; break; case RH_C_PORT_SUSPEND: len = 0; break; case RH_C_PORT_OVER_CURRENT: len = 0; break; case RH_C_PORT_RESET: len = 0; break; default: debug("invalid wValue\n"); stat = USB_ST_STALLED; } port_status &= ~(1 << wValue); break; case RH_SET_FEATURE | RH_OTHER | RH_CLASS: debug("RH_SET_FEATURE | RH_OTHER | RH_CLASS\n"); switch (wValue) { case RH_PORT_SUSPEND: len = 0; break; case RH_PORT_RESET: musb_port_reset(1); len = 0; break; case RH_PORT_POWER: len = 0; break; case RH_PORT_ENABLE: len = 0; break; default: debug("invalid wValue\n"); stat = USB_ST_STALLED; } port_status |= 1 << wValue; break; case RH_SET_ADDRESS: debug("RH_SET_ADDRESS\n"); rh_devnum = wValue; len = 0; break; case RH_GET_DESCRIPTOR: debug("RH_GET_DESCRIPTOR: %x, %d\n", wValue, wLength); switch (wValue) { case (USB_DT_DEVICE << 8): /* device descriptor */ len = min_t(unsigned int, leni, min_t(unsigned int, sizeof(root_hub_dev_des), wLength)); data_buf = root_hub_dev_des; break; case (USB_DT_CONFIG << 8): /* configuration descriptor */ len = min_t(unsigned int, leni, min_t(unsigned int, sizeof(root_hub_config_des), wLength)); data_buf = root_hub_config_des; break; case ((USB_DT_STRING << 8) | 0x00): /* string 0 descriptors */ len = min_t(unsigned int, leni, min_t(unsigned int, sizeof(root_hub_str_index0), wLength)); data_buf = root_hub_str_index0; break; case ((USB_DT_STRING << 8) | 0x01): /* string 1 descriptors */ len = min_t(unsigned int, leni, min_t(unsigned int, sizeof(root_hub_str_index1), wLength)); data_buf = root_hub_str_index1; break; default: debug("invalid wValue\n"); stat = USB_ST_STALLED; } break; case RH_GET_DESCRIPTOR | RH_CLASS: { u8 *_data_buf = (u8 *) datab; debug("RH_GET_DESCRIPTOR | RH_CLASS\n"); _data_buf[0] = 0x09; /* min length; */ _data_buf[1] = 0x29; _data_buf[2] = 0x1; /* 1 port */ _data_buf[3] = 0x01; /* per-port power switching */ _data_buf[3] |= 0x10; /* no overcurrent reporting */ /* Corresponds to data_buf[4-7] */ _data_buf[4] = 0; _data_buf[5] = 5; _data_buf[6] = 0; _data_buf[7] = 0x02; _data_buf[8] = 0xff; len = min_t(unsigned int, leni, min_t(unsigned int, data_buf[0], wLength)); break; } case RH_GET_CONFIGURATION: debug("RH_GET_CONFIGURATION\n"); *(__u8 *) data_buf = 0x01; len = 1; break; case RH_SET_CONFIGURATION: debug("RH_SET_CONFIGURATION\n"); len = 0; break; default: debug("*** *** *** unsupported root hub command *** *** ***\n"); stat = USB_ST_STALLED; } len = min_t(int, len, leni); if (buffer != data_buf) memcpy(buffer, data_buf, len); dev->act_len = len; dev->status = stat; debug("dev act_len %d, status %d\n", dev->act_len, dev->status); return stat; }
static int filter_out(struct af_instance *af) { af_ac3enc_t *s = af->priv; if (!s->pending) return 0; AVFrame *frame = av_frame_alloc(); if (!frame) { MP_FATAL(af, "Could not allocate memory \n"); return -1; } int err = -1; AVPacket pkt = {0}; av_init_packet(&pkt); #if HAVE_AVCODEC_NEW_CODEC_API // Send input as long as it wants. while (1) { err = read_input_frame(af, frame); if (err < 0) goto done; if (err == 0) break; err = -1; int lavc_ret = avcodec_send_frame(s->lavc_actx, frame); // On EAGAIN, we're supposed to read remaining output. if (lavc_ret == AVERROR(EAGAIN)) break; if (lavc_ret < 0) { MP_FATAL(af, "Encode failed.\n"); goto done; } s->encoder_buffered += s->input->samples; s->input->samples = 0; } int lavc_ret = avcodec_receive_packet(s->lavc_actx, &pkt); if (lavc_ret == AVERROR(EAGAIN)) { // Need to buffer more input. err = 0; goto done; } if (lavc_ret < 0) { MP_FATAL(af, "Encode failed.\n"); goto done; } #else err = read_input_frame(af, frame); if (err < 0) goto done; if (err == 0) goto done; err = -1; int ok; int lavc_ret = avcodec_encode_audio2(s->lavc_actx, &pkt, frame, &ok); s->input->samples = 0; if (lavc_ret < 0 || !ok) { MP_FATAL(af, "Encode failed.\n"); goto done; } #endif MP_DBG(af, "avcodec_encode_audio got %d, pending %d.\n", pkt.size, s->pending->samples + s->input->samples); s->encoder_buffered -= AC3_FRAME_SIZE; struct mp_audio *out = mp_audio_pool_get(af->out_pool, af->data, s->out_samples); if (!out) goto done; mp_audio_copy_attributes(out, s->pending); int frame_size = pkt.size; int header_len = 0; char hdr[8]; if (s->cfg_add_iec61937_header && pkt.size > 5) { int bsmod = pkt.data[5] & 0x7; int len = frame_size; frame_size = AC3_FRAME_SIZE * 2 * 2; header_len = 8; AV_WL16(hdr, 0xF872); // iec 61937 syncword 1 AV_WL16(hdr + 2, 0x4E1F); // iec 61937 syncword 2 hdr[5] = bsmod; // bsmod hdr[4] = 0x01; // data-type ac3 AV_WL16(hdr + 6, len << 3); // number of bits in payload } if (frame_size > out->samples * out->sstride) abort(); char *buf = (char *)out->planes[0]; memcpy(buf, hdr, header_len); memcpy(buf + header_len, pkt.data, pkt.size); memset(buf + header_len + pkt.size, 0, frame_size - (header_len + pkt.size)); swap_16((uint16_t *)(buf + header_len), pkt.size / 2); out->samples = frame_size / out->sstride; af_add_output_frame(af, out); err = 0; done: av_packet_unref(&pkt); av_frame_free(&frame); update_delay(af); return err; }
void process_endpoints(unsigned short usb2d0_intrin) { /*will hold the packet received */ struct usb_device_descriptor usb_device_packet; struct usb_configuration_descriptor usb_config_packet; struct usb_string_descriptor usb_string_packet; struct devrequest setup_packet; unsigned int *setup_packet_pt; unsigned char *packet_pt = NULL; int temp, temp1; int i; /*printf("{USB device} - endpoint 0x%X \n", usb2d0_intrin); */ /*set usb address, seems to not work unless it is done in the next interrupt, so that is why it is done this way */ if (set_value != -1) *(unsigned char *)USB2D0_FADDR_8 = (unsigned char)set_value; /*endpoint 1 */ if (usb2d0_intrin & 0x01) { setup_packet_pt = (unsigned int *)&setup_packet; /*copy packet */ setup_packet_pt[0] = *(unsigned int *)USB2D0_FIFO_0; setup_packet_pt[1] = *(unsigned int *)USB2D0_FIFO_0; temp = *(unsigned int *)USB2D0_FIFO_0; temp1 = *(unsigned int *)USB2D0_FIFO_0; /*do some swapping */ setup_packet.value = swap_16(setup_packet.value); setup_packet.index = swap_16(setup_packet.index); setup_packet.length = swap_16(setup_packet.length); /*clear rx packet */ *(unsigned short *)USB2D0_INCSR0_8 = 0x48; /*printf("0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X\n", setup_packet.requesttype, setup_packet.request, setup_packet.value, setup_packet.index, setup_packet.length, temp, temp1 ); */ switch (setup_packet.request) { case USB_REQ_GET_DESCRIPTOR: switch (setup_packet.value >> 8) { case USB_DT_DEVICE: /*create packet */ usb_device_packet.bLength = 18; usb_device_packet.bDescriptorType = USB_DT_DEVICE; #ifdef USB_2_0_DEVICE usb_device_packet.bcdUSB = swap_16(0x200); #else usb_device_packet.bcdUSB = swap_16(0x110); #endif usb_device_packet.bDeviceClass = 0xff; usb_device_packet.bDeviceSubClass = 0; usb_device_packet.bDeviceProtocol = 0; usb_device_packet.bMaxPacketSize0 = 32; usb_device_packet.idVendor = swap_16(1); usb_device_packet.idProduct = swap_16(2); usb_device_packet.bcdDevice = swap_16(0x300); usb_device_packet.iManufacturer = 1; usb_device_packet.iProduct = 1; usb_device_packet.iSerialNumber = 1; usb_device_packet.bNumConfigurations = 1; /*put packet in fifo */ packet_pt = (unsigned char *)&usb_device_packet; break; case USB_DT_CONFIG: /*create packet */ usb_config_packet.bLength = 9; usb_config_packet.bDescriptorType = USB_DT_CONFIG; usb_config_packet.wTotalLength = swap_16(25); usb_config_packet.bNumInterfaces = 1; usb_config_packet.bConfigurationValue = 1; usb_config_packet.iConfiguration = 0; usb_config_packet.bmAttributes = 0x40; usb_config_packet.bMaxPower = 0; /*put packet in fifo */ packet_pt = (unsigned char *)&usb_config_packet; break; case USB_DT_STRING: /*create packet */ usb_string_packet.bLength = 2; usb_string_packet.bDescriptorType = USB_DT_STRING; usb_string_packet.wData[0] = 0x0094; /*put packet in fifo */ packet_pt = (unsigned char *)&usb_string_packet; break; } /*put packet in fifo */ for (i = 0; i < (setup_packet.length); i++) { *(unsigned char *)USB2D0_FIFO_0 = packet_pt[i]; } /*give tx command */ *(unsigned short *)USB2D0_INCSR0_8 = 0x0a; break; case USB_REQ_SET_ADDRESS: /*copy usb address */ set_value = setup_packet.value; break; } }
void flip_ucac3_star( UCAC3_STAR *star) { swap_32( &star->ra); swap_32( &star->spd); swap_16( &star->mag1); swap_16( &star->mag2); swap_16( &star->mag_sigma); swap_16( &star->ra_sigma); swap_16( &star->dec_sigma); swap_16( &star->epoch_ra); swap_16( &star->epoch_dec); swap_32( &star->pm_ra); swap_32( &star->pm_dec); swap_16( &star->pm_ra_sigma); swap_16( &star->pm_dec_sigma); swap_32( &star->twomass_id); swap_16( &star->mag_j); swap_16( &star->mag_h); swap_16( &star->mag_k); swap_16( &star->sc_bmag); swap_16( &star->sc_rmag); swap_16( &star->sc_imag); swap_32( &star->running_number); }
void BIOSCALL int13_cdrom(uint16_t EHBX, disk_regs_t r) { uint16_t ebda_seg = read_word(0x0040,0x000E); uint8_t device, status, locks; cdb_atapi atapicmd; uint32_t lba; uint16_t count, segment, offset, size; bio_dsk_t __far *bios_dsk; int13ext_t __far *i13x; dpt_t __far *dpt; bios_dsk = ebda_seg :> &EbdaData->bdisk; BX_DEBUG_INT13_CD("%s: AX=%04x BX=%04x CX=%04x DX=%04x ES=%04x\n", __func__, AX, BX, CX, DX, ES); SET_DISK_RET_STATUS(0x00); /* basic check : device should be 0xE0+ */ if( (GET_ELDL() < 0xE0) || (GET_ELDL() >= 0xE0 + BX_MAX_STORAGE_DEVICES) ) { BX_DEBUG("%s: function %02x, ELDL out of range %02x\n", __func__, GET_AH(), GET_ELDL()); goto int13_fail; } // Get the ata channel device = bios_dsk->cdidmap[GET_ELDL()-0xE0]; /* basic check : device has to be valid */ if (device >= BX_MAX_STORAGE_DEVICES) { BX_DEBUG("%s: function %02x, unmapped device for ELDL=%02x\n", __func__, GET_AH(), GET_ELDL()); goto int13_fail; } switch (GET_AH()) { // all those functions return SUCCESS case 0x00: /* disk controller reset */ case 0x09: /* initialize drive parameters */ case 0x0c: /* seek to specified cylinder */ case 0x0d: /* alternate disk reset */ case 0x10: /* check drive ready */ case 0x11: /* recalibrate */ case 0x14: /* controller internal diagnostic */ case 0x16: /* detect disk change */ goto int13_success; break; // all those functions return disk write-protected case 0x03: /* write disk sectors */ case 0x05: /* format disk track */ case 0x43: // IBM/MS extended write SET_AH(0x03); goto int13_fail_noah; break; case 0x01: /* read disk status */ status = read_byte(0x0040, 0x0074); SET_AH(status); SET_DISK_RET_STATUS(0); /* set CF if error status read */ if (status) goto int13_fail_nostatus; else goto int13_success_noah; break; case 0x15: /* read disk drive size */ SET_AH(0x02); goto int13_fail_noah; break; case 0x41: // IBM/MS installation check BX = 0xaa55; // install check SET_AH(0x30); // EDD 2.1 CX = 0x0007; // ext disk access, removable and edd goto int13_success_noah; break; case 0x42: // IBM/MS extended read case 0x44: // IBM/MS verify sectors case 0x47: // IBM/MS extended seek /* Load the I13X struct pointer. */ i13x = MK_FP(DS, SI); count = i13x->count; segment = i13x->segment; offset = i13x->offset; // Can't use 64 bits lba lba = i13x->lba2; if (lba != 0L) { BX_PANIC("%s: function %02x. Can't use 64bits lba\n", __func__, GET_AH()); goto int13_fail; } // Get 32 bits lba lba = i13x->lba1; // If verify or seek if (( GET_AH() == 0x44 ) || ( GET_AH() == 0x47 )) goto int13_success; BX_DEBUG_INT13_CD("%s: read %u sectors @ LBA %lu to %04X:%04X\n", __func__, count, lba, segment, offset); _fmemset(&atapicmd, 0, sizeof(atapicmd)); atapicmd.command = 0x28; // READ 10 command atapicmd.lba = swap_32(lba); atapicmd.nsect = swap_16(count); bios_dsk->drqp.nsect = count; bios_dsk->drqp.sect_sz = 2048; status = pktacc[bios_dsk->devices[device].type](device, 12, (char __far *)&atapicmd, 0, count*2048L, ATA_DATA_IN, MK_FP(segment,offset)); count = (uint16_t)(bios_dsk->drqp.trsfbytes >> 11); i13x->count = count; if (status != 0) { BX_INFO("%s: function %02x, status %02x !\n", __func__, GET_AH(), status); SET_AH(0x0c); goto int13_fail_noah; } goto int13_success; break; case 0x45: // IBM/MS lock/unlock drive if (GET_AL() > 2) goto int13_fail; locks = bios_dsk->devices[device].lock; switch (GET_AL()) { case 0 : // lock if (locks == 0xff) { SET_AH(0xb4); SET_AL(1); goto int13_fail_noah; } bios_dsk->devices[device].lock = ++locks; SET_AL(1); break; case 1 : // unlock if (locks == 0x00) { SET_AH(0xb0); SET_AL(0); goto int13_fail_noah; } bios_dsk->devices[device].lock = --locks; SET_AL(locks==0?0:1); break; case 2 : // status SET_AL(locks==0?0:1); break; } goto int13_success; break; case 0x46: // IBM/MS eject media locks = bios_dsk->devices[device].lock; if (locks != 0) { SET_AH(0xb1); // media locked goto int13_fail_noah; } // FIXME should handle 0x31 no media in device // FIXME should handle 0xb5 valid request failed #if 0 /// @todo implement! // Call removable media eject ASM_START push bp mov bp, sp mov ah, #0x52 int #0x15 mov _int13_cdrom.status + 2[bp], ah jnc int13_cdrom_rme_end mov _int13_cdrom.status, #1 int13_cdrom_rme_end: pop bp ASM_END #endif if (status != 0) { SET_AH(0xb1); // media locked goto int13_fail_noah; } goto int13_success; break; /// @todo Part of this should be merged with analogous code in disk.c case 0x48: // IBM/MS get drive parameters dpt = DS :> (dpt_t *)SI; size = dpt->size; // Buffer is too small if (size < 0x1a) goto int13_fail; // EDD 1.x if (size >= 0x1a) { uint16_t blksize; blksize = bios_dsk->devices[device].blksize; dpt->size = 0x1a; dpt->infos = 0x74; /* Removable, media change, lockable, max values */ dpt->cylinders = 0xffffffff; dpt->heads = 0xffffffff; dpt->spt = 0xffffffff; dpt->blksize = blksize; dpt->sector_count1 = 0xffffffff; // FIXME should be Bit64 dpt->sector_count2 = 0xffffffff; } // EDD 2.x if(size >= 0x1e) { uint8_t channel, irq, mode, checksum, i; uint16_t iobase1, iobase2, options; dpt->size = 0x1e; dpt->dpte_segment = ebda_seg; dpt->dpte_offset = (uint16_t)&EbdaData->bdisk.dpte; // Fill in dpte channel = device / 2; iobase1 = bios_dsk->channels[channel].iobase1; iobase2 = bios_dsk->channels[channel].iobase2; irq = bios_dsk->channels[channel].irq; mode = bios_dsk->devices[device].mode; // FIXME atapi device options = (1<<4); // lba translation options |= (1<<5); // removable device options |= (1<<6); // atapi device #if VBOX_BIOS_CPU >= 80386 options |= (mode==ATA_MODE_PIO32?1:0<<7); #endif bios_dsk->dpte.iobase1 = iobase1; bios_dsk->dpte.iobase2 = iobase2; bios_dsk->dpte.prefix = (0xe | (device % 2))<<4; bios_dsk->dpte.unused = 0xcb; bios_dsk->dpte.irq = irq; bios_dsk->dpte.blkcount = 1 ; bios_dsk->dpte.dma = 0; bios_dsk->dpte.pio = 0; bios_dsk->dpte.options = options; bios_dsk->dpte.reserved = 0; bios_dsk->dpte.revision = 0x11; checksum = 0; for (i = 0; i < 15; ++i) checksum += read_byte(ebda_seg, (uint16_t)&EbdaData->bdisk.dpte + i); checksum = -checksum; bios_dsk->dpte.checksum = checksum; } // EDD 3.x if(size >= 0x42) { uint8_t channel, iface, checksum, i; uint16_t iobase1; channel = device / 2; iface = bios_dsk->channels[channel].iface; iobase1 = bios_dsk->channels[channel].iobase1; dpt->size = 0x42; dpt->key = 0xbedd; dpt->dpi_length = 0x24; dpt->reserved1 = 0; dpt->reserved2 = 0; if (iface == ATA_IFACE_ISA) { dpt->host_bus[0] = 'I'; dpt->host_bus[1] = 'S'; dpt->host_bus[2] = 'A'; dpt->host_bus[3] = ' '; } else { // FIXME PCI } dpt->iface_type[0] = 'A'; dpt->iface_type[1] = 'T'; dpt->iface_type[2] = 'A'; dpt->iface_type[3] = ' '; dpt->iface_type[4] = ' '; dpt->iface_type[5] = ' '; dpt->iface_type[6] = ' '; dpt->iface_type[7] = ' '; if (iface == ATA_IFACE_ISA) { ((uint16_t __far *)dpt->iface_path)[0] = iobase1; ((uint16_t __far *)dpt->iface_path)[1] = 0; ((uint32_t __far *)dpt->iface_path)[1] = 0; } else { // FIXME PCI } ((uint16_t __far *)dpt->device_path)[0] = device & 1; ((uint16_t __far *)dpt->device_path)[1] = 0; ((uint32_t __far *)dpt->device_path)[1] = 0; checksum = 0; for (i = 30; i < 64; ++i) checksum += ((uint8_t __far *)dpt)[i]; checksum = -checksum; dpt->checksum = checksum; } goto int13_success; break; case 0x49: // IBM/MS extended media change // always send changed ?? SET_AH(06); goto int13_fail_nostatus; break; case 0x4e: // // IBM/MS set hardware configuration // DMA, prefetch, PIO maximum not supported switch (GET_AL()) { case 0x01: case 0x03: case 0x04: case 0x06: goto int13_success; break; default : goto int13_fail; } break; // all those functions return unimplemented case 0x02: /* read sectors */ case 0x04: /* verify sectors */ case 0x08: /* read disk drive parameters */ case 0x0a: /* read disk sectors with ECC */ case 0x0b: /* write disk sectors with ECC */ case 0x18: /* set media type for format */ case 0x50: // ? - send packet command default: BX_INFO("%s: unsupported AH=%02x\n", __func__, GET_AH()); goto int13_fail; break; } int13_fail: SET_AH(0x01); // defaults to invalid function in AH or invalid parameter int13_fail_noah: SET_DISK_RET_STATUS(GET_AH()); int13_fail_nostatus: SET_CF(); // error occurred return; int13_success: SET_AH(0x00); // no error int13_success_noah: SET_DISK_RET_STATUS(0x00); CLEAR_CF(); // no error return; }
void BIOSCALL int13_cdemu(disk_regs_t r) { /// @todo a macro or a function for getting the EBDA segment uint16_t ebda_seg=read_word(0x0040,0x000E); uint8_t device, status; uint16_t vheads, vspt, vcylinders; uint16_t head, sector, cylinder, nbsectors; uint32_t vlba, ilba, slba, elba; uint16_t before, segment, offset; cdb_atapi atapicmd; cdemu_t __far *cdemu; bio_dsk_t __far *bios_dsk; cdemu = ebda_seg :> &EbdaData->cdemu; bios_dsk = ebda_seg :> &EbdaData->bdisk; BX_DEBUG_INT13_ET("%s: AX=%04x BX=%04x CX=%04x DX=%04x ES=%04x\n", __func__, AX, BX, CX, DX, ES); /* at this point, we are emulating a floppy/harddisk */ // Recompute the device number device = cdemu->controller_index * 2; device += cdemu->device_spec; SET_DISK_RET_STATUS(0x00); /* basic checks : emulation should be active, dl should equal the emulated drive */ if (!cdemu->active || (cdemu->emulated_drive != GET_DL())) { BX_INFO("%s: function %02x, emulation not active for DL= %02x\n", __func__, GET_AH(), GET_DL()); goto int13_fail; } switch (GET_AH()) { case 0x00: /* disk controller reset */ if (pktacc[bios_dsk->devices[device].type]) { status = softrst[bios_dsk->devices[device].type](device); } goto int13_success; break; // all those functions return SUCCESS case 0x09: /* initialize drive parameters */ case 0x0c: /* seek to specified cylinder */ case 0x0d: /* alternate disk reset */ // FIXME ElTorito Various. should really reset ? case 0x10: /* check drive ready */ // FIXME ElTorito Various. should check if ready ? case 0x11: /* recalibrate */ case 0x14: /* controller internal diagnostic */ case 0x16: /* detect disk change */ goto int13_success; break; // all those functions return disk write-protected case 0x03: /* write disk sectors */ case 0x05: /* format disk track */ SET_AH(0x03); goto int13_fail_noah; break; case 0x01: /* read disk status */ status=read_byte(0x0040, 0x0074); SET_AH(status); SET_DISK_RET_STATUS(0); /* set CF if error status read */ if (status) goto int13_fail_nostatus; else goto int13_success_noah; break; case 0x02: // read disk sectors case 0x04: // verify disk sectors vspt = cdemu->vdevice.spt; vcylinders = cdemu->vdevice.cylinders; vheads = cdemu->vdevice.heads; ilba = cdemu->ilba; sector = GET_CL() & 0x003f; cylinder = (GET_CL() & 0x00c0) << 2 | GET_CH(); head = GET_DH(); nbsectors = GET_AL(); segment = ES; offset = BX; BX_DEBUG_INT13_ET("%s: read to %04x:%04x @ VCHS %u/%u/%u (%u sectors)\n", __func__, ES, BX, cylinder, head, sector, nbsectors); // no sector to read ? if(nbsectors==0) goto int13_success; // sanity checks sco openserver needs this! if ((sector > vspt) || (cylinder >= vcylinders) || (head >= vheads)) { goto int13_fail; } // After validating the input, verify does nothing if (GET_AH() == 0x04) goto int13_success; segment = ES+(BX / 16); offset = BX % 16; // calculate the virtual lba inside the image vlba=((((uint32_t)cylinder*(uint32_t)vheads)+(uint32_t)head)*(uint32_t)vspt)+((uint32_t)(sector-1)); // In advance so we don't lose the count SET_AL(nbsectors); // start lba on cd slba = (uint32_t)vlba / 4; before = (uint32_t)vlba % 4; // end lba on cd elba = (uint32_t)(vlba + nbsectors - 1) / 4; _fmemset(&atapicmd, 0, sizeof(atapicmd)); atapicmd.command = 0x28; // READ 10 command atapicmd.lba = swap_32(ilba + slba); atapicmd.nsect = swap_16(elba - slba + 1); bios_dsk->drqp.nsect = nbsectors; bios_dsk->drqp.sect_sz = 512; bios_dsk->drqp.skip_b = before * 512; bios_dsk->drqp.skip_a = ((4 - nbsectors % 4 - before) * 512) % 2048; status = pktacc[bios_dsk->devices[device].type](device, 12, (char __far *)&atapicmd, before*512, nbsectors*512L, ATA_DATA_IN, MK_FP(segment,offset)); bios_dsk->drqp.skip_b = 0; bios_dsk->drqp.skip_a = 0; if (status != 0) { BX_INFO("%s: function %02x, error %02x !\n", __func__, GET_AH(), status); SET_AH(0x02); SET_AL(0); goto int13_fail_noah; } goto int13_success; break; case 0x08: /* read disk drive parameters */ vspt = cdemu->vdevice.spt; vcylinders = cdemu->vdevice.cylinders - 1; vheads = cdemu->vdevice.heads - 1; SET_AL( 0x00 ); SET_BL( 0x00 ); SET_CH( vcylinders & 0xff ); SET_CL((( vcylinders >> 2) & 0xc0) | ( vspt & 0x3f )); SET_DH( vheads ); SET_DL( 0x02 ); // FIXME ElTorito Various. should send the real count of drives 1 or 2 // FIXME ElTorito Harddisk. should send the HD count switch (cdemu->media) { case 0x01: SET_BL( 0x02 ); break; /* 1.2 MB */ case 0x02: SET_BL( 0x04 ); break; /* 1.44 MB */ case 0x03: SET_BL( 0x05 ); break; /* 2.88 MB */ } /* Only set the DPT pointer for emulated floppies. */ if (cdemu->media < 4) { DI = (uint16_t)&diskette_param_table; /// @todo should this depend on emulated medium? ES = 0xF000; /// @todo how to make this relocatable? } goto int13_success; break; case 0x15: /* read disk drive size */ // FIXME ElTorito Harddisk. What geometry to send ? SET_AH(0x03); goto int13_success_noah; break; // all those functions return unimplemented case 0x0a: /* read disk sectors with ECC */ case 0x0b: /* write disk sectors with ECC */ case 0x18: /* set media type for format */ case 0x41: // IBM/MS installation check // FIXME ElTorito Harddisk. Darwin would like to use EDD case 0x42: // IBM/MS extended read case 0x43: // IBM/MS extended write case 0x44: // IBM/MS verify sectors case 0x45: // IBM/MS lock/unlock drive case 0x46: // IBM/MS eject media case 0x47: // IBM/MS extended seek case 0x48: // IBM/MS get drive parameters case 0x49: // IBM/MS extended media change case 0x4e: // ? - set hardware configuration case 0x50: // ? - send packet command default: BX_INFO("%s: function AH=%02x unsupported, returns fail\n", __func__, GET_AH()); goto int13_fail; break; } int13_fail: SET_AH(0x01); // defaults to invalid function in AH or invalid parameter int13_fail_noah: SET_DISK_RET_STATUS(GET_AH()); int13_fail_nostatus: SET_CF(); // error occurred return; int13_success: SET_AH(0x00); // no error int13_success_noah: SET_DISK_RET_STATUS(0x00); CLEAR_CF(); // no error return; }
// // Returns ah: emulated drive, al: error code // uint16_t cdrom_boot(void) { /// @todo a macro or a function for getting the EBDA segment uint16_t ebda_seg=read_word(0x0040,0x000E); uint8_t buffer[2048]; cdb_atapi atapicmd; uint32_t lba; uint16_t boot_segment, nbsectors, i, error; uint8_t device; uint8_t read_try; cdemu_t __far *cdemu; bio_dsk_t __far *bios_dsk; cdemu = ebda_seg :> &EbdaData->cdemu; bios_dsk = ebda_seg :> &EbdaData->bdisk; /* Find the first CD-ROM. */ for (device = 0; device < BX_MAX_STORAGE_DEVICES; ++device) { if (device_is_cdrom(device)) break; } /* Fail if not found. */ if (device >= BX_MAX_STORAGE_DEVICES) return 2; /* Read the Boot Record Volume Descriptor (BRVD). */ _fmemset(&atapicmd, 0, sizeof(atapicmd)); atapicmd.command = 0x28; // READ 10 command atapicmd.lba = swap_32(0x11); atapicmd.nsect = swap_16(1); bios_dsk->drqp.nsect = 1; bios_dsk->drqp.sect_sz = 2048; for (read_try = 0; read_try <= 4; ++read_try) { error = pktacc[bios_dsk->devices[device].type](device, 12, (char __far *)&atapicmd, 0, 2048L, ATA_DATA_IN, &buffer); if (!error) break; } if (error) return 3; /* Check for a valid BRVD. */ if (buffer[0] != 0) return 4; /// @todo what's wrong with memcmp()? for (i = 0; i < 5; ++i) { if (buffer[1+i] != isotag[i]) return 5; } for (i = 0; i < 23; ++i) if (buffer[7+i] != eltorito[i]) return 6; // ok, now we calculate the Boot catalog address lba = *((uint32_t *)&buffer[0x47]); BX_DEBUG_ELTORITO("BRVD at LBA %lx\n", lba); /* Now we read the Boot Catalog. */ atapicmd.command = 0x28; // READ 10 command atapicmd.lba = swap_32(lba); atapicmd.nsect = swap_16(1); #if 0 // Not necessary as long as previous values are reused bios_dsk->drqp.nsect = 1; bios_dsk->drqp.sect_sz = 512; #endif error = pktacc[bios_dsk->devices[device].type](device, 12, (char __far *)&atapicmd, 0, 2048L, ATA_DATA_IN, &buffer); if (error != 0) return 7; /// @todo Define a struct for the Boot Catalog, the hardcoded offsets are so dumb... /* Check if the Boot Catalog looks valid. */ if (buffer[0x00] != 0x01) return 8; // Header if (buffer[0x01] != 0x00) return 9; // Platform if (buffer[0x1E] != 0x55) return 10; // key 1 if (buffer[0x1F] != 0xAA) return 10; // key 2 // Initial/Default Entry if (buffer[0x20] != 0x88) return 11; // Bootable cdemu->media = buffer[0x21]; if (buffer[0x21] == 0) { // FIXME ElTorito Hardcoded. cdrom is hardcoded as device 0xE0. // Win2000 cd boot needs to know it booted from cd cdemu->emulated_drive = 0xE0; } else if (buffer[0x21] < 4) cdemu->emulated_drive = 0x00; else cdemu->emulated_drive = 0x80; cdemu->controller_index = device / 2; cdemu->device_spec = device % 2; boot_segment = *((uint16_t *)&buffer[0x22]); if (boot_segment == 0) boot_segment = 0x07C0; cdemu->load_segment = boot_segment; cdemu->buffer_segment = 0x0000; nbsectors = ((uint16_t *)buffer)[0x26 / 2]; cdemu->sector_count = nbsectors; /* Sanity check the sector count. In incorrectly mastered CDs, it might * be zero. If it's more than 512K, reject it as well. */ if (nbsectors == 0 || nbsectors > 1024) return 12; lba = *((uint32_t *)&buffer[0x28]); cdemu->ilba = lba; BX_DEBUG_ELTORITO("Emulate drive %02x, type %02x, LBA %lu\n", cdemu->emulated_drive, cdemu->media, cdemu->ilba); /* Read the disk image's boot sector into memory. */ atapicmd.command = 0x28; // READ 10 command atapicmd.lba = swap_32(lba); atapicmd.nsect = swap_16(1 + (nbsectors - 1) / 4); bios_dsk->drqp.nsect = 1 + (nbsectors - 1) / 4; bios_dsk->drqp.sect_sz = 512; bios_dsk->drqp.skip_a = (2048 - nbsectors * 512) % 2048; error = pktacc[bios_dsk->devices[device].type](device, 12, (char __far *)&atapicmd, 0, nbsectors*512L, ATA_DATA_IN, MK_FP(boot_segment,0)); bios_dsk->drqp.skip_a = 0; if (error != 0) return 13; BX_DEBUG_ELTORITO("Emulate drive %02x, type %02x, LBA %lu\n", cdemu->emulated_drive, cdemu->media, cdemu->ilba); /* Set up emulated drive geometry based on the media type. */ switch (cdemu->media) { case 0x01: /* 1.2M floppy */ cdemu->vdevice.spt = 15; cdemu->vdevice.cylinders = 80; cdemu->vdevice.heads = 2; break; case 0x02: /* 1.44M floppy */ cdemu->vdevice.spt = 18; cdemu->vdevice.cylinders = 80; cdemu->vdevice.heads = 2; break; case 0x03: /* 2.88M floppy */ cdemu->vdevice.spt = 36; cdemu->vdevice.cylinders = 80; cdemu->vdevice.heads = 2; break; case 0x04: /* Hard disk */ cdemu->vdevice.spt = read_byte(boot_segment,446+6)&0x3f; cdemu->vdevice.cylinders = (read_byte(boot_segment,446+6)<<2) + read_byte(boot_segment,446+7) + 1; cdemu->vdevice.heads = read_byte(boot_segment,446+5) + 1; break; } BX_DEBUG_ELTORITO("VCHS=%u/%u/%u\n", cdemu->vdevice.cylinders, cdemu->vdevice.heads, cdemu->vdevice.spt); if (cdemu->media != 0) { /* Increase BIOS installed number of drives (floppy or fixed). */ if (cdemu->emulated_drive == 0x00) write_byte(0x40,0x10,read_byte(0x40,0x10)|0x41); else write_byte(ebda_seg,(uint16_t)&EbdaData->bdisk.hdcount, read_byte(ebda_seg, (uint16_t)&EbdaData->bdisk.hdcount) + 1); } // everything is ok, so from now on, the emulation is active if (cdemu->media != 0) cdemu->active = 0x01; // return the boot drive + no error return (cdemu->emulated_drive*0x100)+0; }
int HandleServerMessage(tSDL_vnc *vnc) { int i, num_pixels, num_rectangles, num_subrectangles, hx, hy, bx, by, cx, cy, rowindex, bitindex, byteindex; int result, bytes_to_read, bytes_read; tSDL_vnc_serverMessage serverMessage; tSDL_vnc_serverUpdate serverUpdate; tSDL_vnc_serverRectangle serverRectangle; tSDL_vnc_serverColormap serverColormap; tSDL_vnc_serverText serverText; tSDL_vnc_serverCopyrect serverCopyrect; tSDL_vnc_serverRRE serverRRE; tSDL_vnc_serverRREdata serverRREdata; tSDL_vnc_serverCoRRE serverCoRRE; tSDL_vnc_serverCoRREdata serverCoRREdata; tSDL_vnc_serverHextile serverHextile; tSDL_vnc_serverHextileBg serverHextileBg; tSDL_vnc_serverHextileFg serverHextileFg; tSDL_vnc_serverHextileSubrects serverHextileSubrects; tSDL_vnc_serverHextileColored serverHextileColored; tSDL_vnc_serverHextileRect serverHextileRect; unsigned char *target; unsigned int *uitarget; unsigned char *cursormask; SDL_Rect trec, srec; DBMESSAGE ("HandleServerMessage\n"); /* Read message type */ result = Recv(vnc->socket,&serverMessage,1,0); if (result==1) { switch (serverMessage.messagetype) { case 0: DBMESSAGE ("Message: update\n"); result = Recv(vnc->socket,&serverUpdate,3,0); if (result==3) { /* ??? Protocol sais U16, TightVNC server sends U8 */ serverUpdate.rectangles=serverUpdate.rectangles & 0x00ff; DBMESSAGE ("Number of rectangles: %u (%04x)\n",serverUpdate.rectangles,serverUpdate.rectangles); num_rectangles=0; while (num_rectangles<serverUpdate.rectangles) { num_rectangles++; result = Recv(vnc->socket,&serverRectangle,12,0); if (result==12) { serverRectangle.x=swap_16(serverRectangle.x); serverRectangle.y=swap_16(serverRectangle.y); serverRectangle.width=swap_16(serverRectangle.width); serverRectangle.height=swap_16(serverRectangle.height); serverRectangle.encoding=swap_32(serverRectangle.encoding); // DBMESSAGE ("Rectangle %i of %i: @ %u,%u size %u,%u encoding %u\n",num_rectangles,serverUpdate.rectangles,serverRectangle.x,serverRectangle.y,serverRectangle.width,serverRectangle.height,serverRectangle.encoding); /* Sanity check values */ if (serverRectangle.x>vnc->serverFormat.width) { DBMESSAGE("Bad rectangle: x=%u setting to 0\n",serverRectangle.x); serverRectangle.x=0; } if (serverRectangle.y>vnc->serverFormat.height) { DBMESSAGE("Bad rectangle: y=%u setting to 0\n",serverRectangle.y); serverRectangle.y=0; } if ((serverRectangle.width<=0) || (serverRectangle.width>vnc->serverFormat.width)) { DBMESSAGE("Bad rectangle: width=%u setting to 1\n",serverRectangle.width); serverRectangle.width=1; } if ((serverRectangle.height<=0) || (serverRectangle.height>vnc->serverFormat.height)) { DBMESSAGE("Bad rectangle: height=%u setting to 1\n",serverRectangle.height); serverRectangle.height=1; } /* Do we have a scratchbuffer */ if (vnc->scratchbuffer) { /* Check size */ if ( (!(vnc->scratchbuffer->w == serverRectangle.width)) || (!(vnc->scratchbuffer->h == serverRectangle.height)) ) { /* Clean out existing scratchbuffer */ SDL_FreeSurface(vnc->scratchbuffer); vnc->scratchbuffer=NULL; DBMESSAGE ("Deleted existing scratchbuffer.\n"); } } if (!(vnc->scratchbuffer)) { /* Create new scratchbuffer */ vnc->scratchbuffer = SDL_CreateRGBSurface(SDL_SWSURFACE,serverRectangle.width,serverRectangle.height,32, vnc->rmask,vnc->gmask,vnc->bmask,0); if (vnc->scratchbuffer) { SDL_SetAlpha(vnc->scratchbuffer,0,0); DBMESSAGE ("Created new scratchbuffer.\n"); } else { DBERROR ("Error creating scratchbuffer.\n"); return 0; } } /* Rectangle Data */ switch (serverRectangle.encoding) { case 0: DBMESSAGE ("RAW encoding.\n"); bytes_to_read = serverRectangle.width*serverRectangle.height*4; result = Recv(vnc->socket,(unsigned char *)vnc->scratchbuffer->pixels,bytes_to_read,0); if (result==bytes_to_read) { DBMESSAGE ("Blitting %i bytes of raw pixel data.\n",bytes_to_read); trec.x=serverRectangle.x; trec.y=serverRectangle.y; trec.w=serverRectangle.width; trec.h=serverRectangle.height; SDL_LockMutex(vnc->mutex); SDL_BlitSurface(vnc->scratchbuffer, NULL, vnc->framebuffer, &trec); GrowUpdateRegion(vnc,&trec); SDL_UnlockMutex(vnc->mutex); DBMESSAGE ("Blitted raw pixel data.\n"); } else { DBERROR ("Error on pixel data. Got %i of %i bytes.\n",result,bytes_to_read); return 0; } break; case 1: DBMESSAGE ("CopyRect encoding.\n"); result = Recv(vnc->socket,&serverCopyrect,4,0); if (result==4) { serverCopyrect.x=swap_16(serverCopyrect.x); serverCopyrect.y=swap_16(serverCopyrect.y); // DBMESSAGE ("Copyrect from %u,%u\n",serverCopyrect.x,serverCopyrect.y); // srec.x=serverCopyrect.x; srec.y=serverCopyrect.y; srec.w=serverRectangle.width; srec.h=serverRectangle.height; trec.x=serverRectangle.x; trec.y=serverRectangle.y; trec.w=serverRectangle.width; trec.h=serverRectangle.height; SDL_LockMutex(vnc->mutex); SDL_BlitSurface(vnc->framebuffer, &srec, vnc->scratchbuffer, NULL); SDL_BlitSurface(vnc->scratchbuffer, NULL, vnc->framebuffer, &trec); GrowUpdateRegion(vnc,&trec); SDL_UnlockMutex(vnc->mutex); DBMESSAGE ("Blitted copyrect pixels.\n"); } else { DBERROR ("Error on copyrect data. Got %i of %i bytes.\n",result,4); return 0; } break; case 2: DBMESSAGE ("RRE encoding.\n"); result = Recv(vnc->socket,&serverRRE,8,0); if (result==8) { serverRRE.number=swap_32(serverRRE.number); // DBMESSAGE ("RRE of %u rectangles. Background color 0x%06x\n",serverRRE.number,serverRRE.background); SDL_FillRect(vnc->scratchbuffer, NULL, serverRRE.background); /* Draw subrectangles */ num_subrectangles=0; while (num_subrectangles<serverRRE.number) { num_subrectangles++; result = Recv(vnc->socket,&serverRREdata,12,0); if (result==12) { serverRREdata.x=swap_16(serverRREdata.x); serverRREdata.y=swap_16(serverRREdata.y); serverRREdata.width=swap_16(serverRREdata.width); serverRREdata.height=swap_16(serverRREdata.height); srec.x=serverRREdata.x; srec.y=serverRREdata.y; srec.w=serverRREdata.width; srec.h=serverRREdata.height; SDL_FillRect(vnc->scratchbuffer,&srec,serverRREdata.color); } else { DBERROR ("Error on RRE data. Got %i of %i bytes.\n",result,12); return 0; } } DBMESSAGE ("Drawn %i subrectangles.\n", num_subrectangles); trec.x=serverRectangle.x; trec.y=serverRectangle.y; trec.w=serverRectangle.width; trec.h=serverRectangle.height; SDL_LockMutex(vnc->mutex); SDL_BlitSurface(vnc->scratchbuffer, NULL, vnc->framebuffer, &trec); GrowUpdateRegion(vnc,&trec); SDL_UnlockMutex(vnc->mutex); DBMESSAGE ("Blitted RRE pixels.\n"); } else { DBERROR ("Error on RRE header. Got %i of %i bytes.\n",result,8); return 0; } break; case 4: DBMESSAGE ("CoRRE encoding.\n"); result = Recv(vnc->socket,&serverCoRRE,8,0); if (result==8) { serverCoRRE.number=swap_32(serverCoRRE.number); // DBMESSAGE ("CoRRE of %u rectangles. Background color 0x%06x\n",serverCoRRE.number,serverCoRRE.background); SDL_FillRect(vnc->scratchbuffer, NULL, serverCoRRE.background); /* Draw subrectangles */ num_subrectangles=0; while (num_subrectangles<serverCoRRE.number) { num_subrectangles++; result = Recv(vnc->socket,&serverCoRREdata,8,0); if (result==8) { srec.x=serverCoRREdata.x; srec.y=serverCoRREdata.y; srec.w=serverCoRREdata.width; srec.h=serverCoRREdata.height; SDL_FillRect(vnc->scratchbuffer,&srec,serverCoRREdata.color); } else { DBERROR ("Error on CoRRE data. Got %i of %i bytes.\n",result,8); return 0; } } DBMESSAGE ("Drawn %i subrectangles.\n", num_subrectangles); trec.x=serverRectangle.x; trec.y=serverRectangle.y; trec.w=serverRectangle.width; trec.h=serverRectangle.height; SDL_LockMutex(vnc->mutex); SDL_BlitSurface(vnc->scratchbuffer, NULL, vnc->framebuffer, &trec); GrowUpdateRegion(vnc,&trec); SDL_UnlockMutex(vnc->mutex); DBMESSAGE ("Blitted CoRRE pixels.\n"); } else { DBERROR ("Error on CoRRE header. Got %i of %i bytes.\n",result,8); return 0; } break; case 5: DBMESSAGE ("Hextile encoding.\n"); // if (!(vnc->tilebuffer)) { /* Create new tilebuffer */ vnc->tilebuffer = SDL_CreateRGBSurface(SDL_SWSURFACE,16,16,32, vnc->rmask,vnc->gmask,vnc->bmask,0); if (vnc->tilebuffer) { SDL_SetAlpha(vnc->tilebuffer,0,0); DBMESSAGE ("Created new tilebuffer.\n"); } else { DBERROR ("Error creating tilebuffer.\n"); return 0; } } // /* Iterate over all tiles */ // row loop for (hy=0; hy<serverRectangle.height; hy += 16) { /* Determine height of tile */ if ((hy+16)>serverRectangle.height) { by=serverRectangle.height % 16; } else { by=16; } // column loop for (hx=0; hx<serverRectangle.width; hx += 16) { /* Determine width of tile */ if ((hx+16)>serverRectangle.width) { bx=serverRectangle.width % 16; } else { bx=16; } result = Recv(vnc->socket,&serverHextile,1,0); if (result==1) { if (serverHextile.mode & 1) { /* Read raw data for tile in lines */ bytes_to_read = bx*by*4; if ((bx==16) && (by==16)) { // complete tile result = Recv(vnc->socket,(unsigned char *)vnc->tilebuffer->pixels,bytes_to_read,0); } else { // partial tile result = 0; target=(unsigned char *)vnc->tilebuffer->pixels; rowindex=by; while (rowindex) { result += Recv(vnc->socket,target,bx*4,0); target += 16*4; rowindex--; } } if (result==bytes_to_read) { trec.x=hx; trec.y=hy; trec.w=16; trec.h=16; SDL_BlitSurface(vnc->tilebuffer, NULL, vnc->scratchbuffer, &trec); } else { DBERROR ("Error on pixel data. Got %i of %i bytes.\n",result,bytes_to_read); return 0; } } else { /* no raw data */ if (serverHextile.mode & 2) { /* Read background */ result = Recv(vnc->socket,&serverHextileBg,4,0); if (result==4) { /* All OK */ } else { DBERROR ("Error on Hextile background. Got %i of %i bytes.\n",result,4); return 0; } } SDL_FillRect(vnc->tilebuffer,NULL,serverHextileBg.color); if (serverHextile.mode & 4) { /* Read foreground */ result = Recv(vnc->socket,&serverHextileFg,4,0); if (result==4) { /* All OK */ } else { DBERROR ("Error on Hextile foreground. Got %i of %i bytes.\n",result,4); return 0; } } if (serverHextile.mode & 8) { result = Recv(vnc->socket,&serverHextileSubrects,1,0); if (result==1) { /* All OK */ } else { DBERROR ("Error on Hextile subrects. Got %i of %i bytes.\n",result,1); return 0; } /* Read subrects */ num_subrectangles=0; while (num_subrectangles<serverHextileSubrects.number) { num_subrectangles++; // /* Check color mode */ if (serverHextile.mode & 16) { /* Colored subrect */ result = Recv(vnc->socket,&serverHextileColored,6,0); if (result==6) { /* Render colored subrect */ srec.x=(serverHextileColored.xy >> 4) & 0x0f; srec.y=serverHextileColored.xy & 0x0f; srec.w=((serverHextileColored.wh >> 4) & 0x0f)+1; srec.h=(serverHextileColored.wh & 0x0f)+1; SDL_FillRect(vnc->tilebuffer,&srec,serverHextileColored.color); } else { DBERROR ("Error on Hextile color subrect data. Got %i of %i bytes.\n",result,6); return 0; } } else { /* Non-colored Subrect */ result = Recv(vnc->socket,&serverHextileRect,2,0); if (result==2) { /* Render colored subrect */ srec.x=(serverHextileRect.xy >> 4) & 0x0f; srec.y=serverHextileRect.xy & 0x0f; srec.w=((serverHextileRect.wh >> 4) & 0x0f)+1; srec.h=(serverHextileRect.wh & 0x0f)+1; SDL_FillRect(vnc->tilebuffer,&srec,serverHextileFg.color); } else { DBERROR ("Error on Hextile subrect data. Got %i of %i bytes.\n",result,2); return 0; } } // color mode check } // subrect loop // } // have subrects /* Draw tile */ trec.x=hx; trec.y=hy; trec.w=16; trec.h=16; SDL_BlitSurface(vnc->tilebuffer, NULL, vnc->scratchbuffer, &trec); } // raw data check } else {