diff --git a/src/86box.h b/src/86box.h index c5121da72..eaac682d3 100644 --- a/src/86box.h +++ b/src/86box.h @@ -8,7 +8,7 @@ * * Main include file for the application. * - * Version: @(#)86box.h 1.0.22 2018/03/28 + * Version: @(#)86box.h 1.0.23 2018/05/25 * * Authors: Miran Grca, * Fred N. van Kempen, @@ -90,8 +90,7 @@ extern int vid_cga_contrast, /* (C) video */ video_fullscreen_scale, /* (C) video */ enable_overscan, /* (C) video */ force_43, /* (C) video */ - gfxcard, /* (C) graphics/video card */ - video_speed; /* (C) video */ + gfxcard; /* (C) graphics/video card */ extern int serial_enabled[], /* (C) enable serial ports */ lpt_enabled, /* (C) enable LPT ports */ bugger_enabled; /* (C) enable ISAbugger */ @@ -127,6 +126,7 @@ extern wchar_t cfg_path[1024]; /* full path of config file */ extern FILE *stdlog; /* file to log output to */ extern int scrnsz_x, /* current screen size, X */ scrnsz_y; /* current screen size, Y */ +extern int efscrnsz_y; extern int config_changed; /* config has changed */ diff --git a/src/Makefile.local b/src/Makefile.local index 6c21328fe..a93152007 100644 --- a/src/Makefile.local +++ b/src/Makefile.local @@ -10,7 +10,7 @@ # settings, so we can avoid changing the main one for all of # our local setups. # -# Version: @(#)Makefile.local 1.0.13 2018/04/29 +# Version: @(#)Makefile.local 1.0.14 2018/05/26 # # Author: Fred N. van Kempen, # @@ -129,6 +129,7 @@ STUFF := # -DENABLE_DDRAW_LOG=N sets logging level at N. # -DENABLE_DYNLD_LOG=N sets logging level at N. # -DENABLE_JOYSTICK_LOG=N sets logging level at N. +# -DENABLE_SDL_LOG=N sets logging level at N. # -DENABLE_WIN_LOG=N sets logging level at N. EXTRAS := diff --git a/src/cdrom/cdrom.c b/src/cdrom/cdrom.c index 22d605bb3..4ab96d37a 100644 --- a/src/cdrom/cdrom.c +++ b/src/cdrom/cdrom.c @@ -9,7 +9,7 @@ * Implementation of the CD-ROM drive with SCSI(-like) * commands, for both ATAPI and SCSI usage. * - * Version: @(#)cdrom.c 1.0.47 2018/05/10 + * Version: @(#)cdrom.c 1.0.48 2018/05/28 * * Author: Miran Grca, * @@ -62,22 +62,8 @@ cdrom_t *cdrom[CDROM_NUM]; cdrom_image_t cdrom_image[CDROM_NUM]; cdrom_drive_t cdrom_drives[CDROM_NUM]; uint8_t atapi_cdrom_drives[8] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; -uint8_t scsi_cdrom_drives[16][8] = { { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } }; +uint8_t scsi_cdrom_drives[16] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; #pragma pack(push,1) @@ -106,90 +92,90 @@ static struct /* Table of all SCSI commands and their flags, needed for the new disc change / not ready handler. */ const uint8_t cdrom_command_flags[0x100] = { - IMPLEMENTED | CHECK_READY | NONDATA, - IMPLEMENTED | ALLOW_UA | NONDATA | SCSI_ONLY, - 0, - IMPLEMENTED | ALLOW_UA, - 0, 0, 0, 0, - IMPLEMENTED | CHECK_READY, - 0, 0, - IMPLEMENTED | CHECK_READY | NONDATA, - 0, 0, 0, 0, 0, 0, - IMPLEMENTED | ALLOW_UA, - IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, - 0, - IMPLEMENTED, - 0, 0, 0, 0, - IMPLEMENTED, - IMPLEMENTED | CHECK_READY, - 0, 0, - IMPLEMENTED | CHECK_READY, - 0, 0, 0, 0, 0, 0, - IMPLEMENTED | CHECK_READY, - 0, 0, - IMPLEMENTED | CHECK_READY, - 0, 0, - IMPLEMENTED | CHECK_READY | NONDATA, - 0, 0, 0, - IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, - IMPLEMENTED | CHECK_READY, - IMPLEMENTED | CHECK_READY, /* Read TOC - can get through UNIT_ATTENTION, per VIDE-CDD.SYS + IMPLEMENTED | CHECK_READY | NONDATA, /* 0x00 */ + IMPLEMENTED | ALLOW_UA | NONDATA | SCSI_ONLY, /* 0x01 */ + 0, /* 0x02 */ + IMPLEMENTED | ALLOW_UA, /* 0x03 */ + 0, 0, 0, 0, /* 0x04-0x07 */ + IMPLEMENTED | CHECK_READY, /* 0x08 */ + 0, 0, /* 0x09-0x0A */ + IMPLEMENTED | CHECK_READY | NONDATA, /* 0x0B */ + 0, 0, 0, 0, 0, 0, /* 0x0C-0x11 */ + IMPLEMENTED | ALLOW_UA, /* 0x12 */ + IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, /* 0x13 */ + 0, /* 0x14 */ + IMPLEMENTED, /* 0x15 */ + 0, 0, 0, 0, /* 0x16-0x19 */ + IMPLEMENTED, /* 0x1A */ + IMPLEMENTED | CHECK_READY, /* 0x1B */ + 0, 0, /* 0x1C-0x1D */ + IMPLEMENTED | CHECK_READY, /* 0x1E */ + 0, 0, 0, 0, 0, 0, /* 0x1F-0x24 */ + IMPLEMENTED | CHECK_READY, /* 0x25 */ + 0, 0, /* 0x26-0x27 */ + IMPLEMENTED | CHECK_READY, /* 0x28 */ + 0, 0, /* 0x29-0x2A */ + IMPLEMENTED | CHECK_READY | NONDATA, /* 0x2B */ + 0, 0, 0, /* 0x2C-0x2E */ + IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, /* 0x2F */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x30-0x3F */ + 0, 0, /* 0x40-0x41 */ + IMPLEMENTED | CHECK_READY, /* 0x42 */ + IMPLEMENTED | CHECK_READY, /* 0x43 - Read TOC - can get through UNIT_ATTENTION, per VIDE-CDD.SYS NOTE: The ATAPI reference says otherwise, but I think this is a question of interpreting things right - the UNIT ATTENTION condition we have here is a tradition from not ready to ready, by definition the drive eventually becomes ready, make the condition go away. */ - IMPLEMENTED | CHECK_READY, - IMPLEMENTED | CHECK_READY, - IMPLEMENTED | ALLOW_UA, - IMPLEMENTED | CHECK_READY, - IMPLEMENTED | CHECK_READY, - 0, - IMPLEMENTED | ALLOW_UA, - IMPLEMENTED | CHECK_READY, - 0, 0, - IMPLEMENTED | CHECK_READY, - 0, 0, - IMPLEMENTED | CHECK_READY, - IMPLEMENTED | CHECK_READY, - 0, 0, - IMPLEMENTED, - 0, 0, 0, 0, - IMPLEMENTED, - 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - IMPLEMENTED | CHECK_READY, - 0, 0, - IMPLEMENTED | CHECK_READY, - 0, 0, 0, 0, - IMPLEMENTED | CHECK_READY, - 0, - IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, - 0, 0, 0, 0, - IMPLEMENTED | CHECK_READY | ATAPI_ONLY, - 0, 0, 0, - IMPLEMENTED | CHECK_READY | ATAPI_ONLY, - IMPLEMENTED | CHECK_READY, - IMPLEMENTED | CHECK_READY, - IMPLEMENTED, - IMPLEMENTED | CHECK_READY, - IMPLEMENTED, - IMPLEMENTED | CHECK_READY, - IMPLEMENTED | CHECK_READY, - 0, 0, - IMPLEMENTED | CHECK_READY | SCSI_ONLY, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - IMPLEMENTED | CHECK_READY | SCSI_ONLY, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - IMPLEMENTED | SCSI_ONLY, - 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 + IMPLEMENTED | CHECK_READY, /* 0x44 */ + IMPLEMENTED | CHECK_READY, /* 0x45 */ + IMPLEMENTED | ALLOW_UA, /* 0x46 */ + IMPLEMENTED | CHECK_READY, /* 0x47 */ + IMPLEMENTED | CHECK_READY, /* 0x48 */ + 0, /* 0x49 */ + IMPLEMENTED | ALLOW_UA, /* 0x4A */ + IMPLEMENTED | CHECK_READY, /* 0x4B */ + 0, 0, /* 0x4C-0x4D */ + IMPLEMENTED | CHECK_READY, /* 0x4E */ + 0, 0, /* 0x4F-0x50 */ + IMPLEMENTED | CHECK_READY, /* 0x51 */ + IMPLEMENTED | CHECK_READY, /* 0x52 */ + 0, 0, /* 0x53-0x54 */ + IMPLEMENTED, /* 0x55 */ + 0, 0, 0, 0, /* 0x56-0x59 */ + IMPLEMENTED, /* 0x5A */ + 0, 0, 0, 0, 0, /* 0x5B-0x5F */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60-0x6F */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x70-0x7F */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80-0x8F */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90-0x9F */ + 0, 0, 0, 0, 0, /* 0xA0-0xA4 */ + IMPLEMENTED | CHECK_READY, /* 0xA5 */ + 0, 0, /* 0xA6-0xA7 */ + IMPLEMENTED | CHECK_READY, /* 0xA8 */ + 0, 0, 0, 0, /* 0xA9-0xAC */ + IMPLEMENTED | CHECK_READY, /* 0xAD */ + 0, /* 0xAE */ + IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, /* 0xAF */ + 0, 0, 0, 0, /* 0xB0-0xB3 */ + IMPLEMENTED | CHECK_READY | ATAPI_ONLY, /* 0xB4 */ + 0, 0, 0, /* 0xB5-0xB7 */ + IMPLEMENTED | CHECK_READY | ATAPI_ONLY, /* 0xB8 */ + IMPLEMENTED | CHECK_READY, /* 0xB9 */ + IMPLEMENTED | CHECK_READY, /* 0xBA */ + IMPLEMENTED, /* 0xBB */ + IMPLEMENTED | CHECK_READY, /* 0xBC */ + IMPLEMENTED, /* 0xBD */ + IMPLEMENTED | CHECK_READY, /* 0xBE */ + IMPLEMENTED | CHECK_READY, /* 0xBF */ + 0, 0, /* 0xC0-0xC1 */ + IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xC2 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xC3-0xCC */ + IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xCD */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xCE-0xD9 */ + IMPLEMENTED | SCSI_ONLY, /* 0xDA */ + 0, 0, 0, 0, 0, /* 0xDB-0xDF */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xE0-0xEF */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* 0xF0-0xFF */ }; static uint64_t cdrom_mode_sense_page_flags = (GPMODEP_R_W_ERROR_PAGE | @@ -397,12 +383,12 @@ build_atapi_cdrom_map() int -find_cdrom_for_scsi_id(uint8_t scsi_id, uint8_t scsi_lun) +find_cdrom_for_scsi_id(uint8_t scsi_id) { uint8_t i = 0; for (i = 0; i < CDROM_NUM; i++) { - if ((cdrom_drives[i].bus_type == CDROM_BUS_SCSI) && (cdrom_drives[i].scsi_device_id == scsi_id) && (cdrom_drives[i].scsi_device_lun == scsi_lun)) + if ((cdrom_drives[i].bus_type == CDROM_BUS_SCSI) && (cdrom_drives[i].scsi_device_id == scsi_id)) return i; } return 0xff; @@ -413,15 +399,11 @@ void build_scsi_cdrom_map() { uint8_t i = 0; - uint8_t j = 0; + + memset(scsi_cdrom_drives, 0xff, 16); for (i = 0; i < 16; i++) - memset(scsi_cdrom_drives[i], 0xff, 8); - - for (i = 0; i < 16; i++) { - for (j = 0; j < 8; j++) - scsi_cdrom_drives[i][j] = find_cdrom_for_scsi_id(i, j); - } + scsi_cdrom_drives[i] = find_cdrom_for_scsi_id(i); } @@ -772,6 +754,8 @@ cdrom_update_request_length(cdrom_t *dev, int len, int block_len) if ((len <= dev->max_transfer_len) && (len >= min_len)) dev->request_length = dev->max_transfer_len = len; + else if (len > dev->max_transfer_len) + dev->request_length = dev->max_transfer_len; return; } @@ -1008,7 +992,7 @@ static void cdrom_data_command_finish(cdrom_t *dev, int len, int block_len, int { cdrom_log("CD-ROM %i: Finishing command (%02X): %i, %i, %i, %i, %i\n", dev->id, dev->current_cdb[0], len, block_len, alloc_len, direction, dev->request_length); - dev->pos=0; + dev->pos = 0; if (alloc_len >= 0) { if (alloc_len < len) len = alloc_len; @@ -1053,12 +1037,11 @@ static void cdrom_set_phase(cdrom_t *dev, uint8_t phase) { uint8_t scsi_id = dev->drv->scsi_device_id; - uint8_t scsi_lun = dev->drv->scsi_device_lun; if (dev->drv->bus_type != CDROM_BUS_SCSI) return; - SCSIDevices[scsi_id][scsi_lun].Phase = phase; + SCSIDevices[scsi_id].Phase = phase; } @@ -1482,7 +1465,7 @@ cdrom_pre_execution_check(cdrom_t *dev, uint8_t *cdb) int ready = 0, status = 0; if (dev->drv->bus_type == CDROM_BUS_SCSI) { - if (((dev->request_length >> 5) & 7) != dev->drv->scsi_device_lun) { + if ((cdb[0] != GPCMD_REQUEST_SENSE) && (cdb[1] & 0xe0)) { cdrom_log("CD-ROM %i: Attempting to execute a unknown command targeted at SCSI LUN %i\n", dev->id, ((dev->request_length >> 5) & 7)); cdrom_invalid_lun(dev); @@ -1733,7 +1716,7 @@ cdrom_command(cdrom_t *dev, uint8_t *cdb) uint32_t profiles[2] = { MMC_PROFILE_CD_ROM, MMC_PROFILE_DVD_ROM }; if (dev->drv->bus_type == CDROM_BUS_SCSI) { - BufLen = &SCSIDevices[dev->drv->scsi_device_id][dev->drv->scsi_device_lun].BufferLength; + BufLen = &SCSIDevices[dev->drv->scsi_device_id].BufferLength; dev->status &= ~ERR_STAT; } else { BufLen = &blen; @@ -2772,7 +2755,6 @@ cdrom_phase_data_out(cdrom_t *dev) static void cdrom_pio_request(cdrom_t *dev, uint8_t out) { - int old_pos = 0; int ret = 0; if (dev->drv->bus_type < CDROM_BUS_SCSI) { @@ -2807,10 +2789,13 @@ cdrom_pio_request(cdrom_t *dev, uint8_t out) cdrom_log("CD-ROM %i: Packet length %i, request length %i\n", dev->id, dev->packet_len, dev->max_transfer_len); - old_pos = dev->pos; dev->packet_status = out ? CDROM_PHASE_DATA_OUT : CDROM_PHASE_DATA_IN; - cdrom_command_common(dev); - dev->pos = old_pos; + + dev->status = BUSY_STAT; + dev->phase = 1; + cdrom_phase_callback(dev); + dev->callback = 0LL; + cdrom_set_callback(dev); dev->request_pos = 0; } @@ -2849,12 +2834,12 @@ cdrom_read_from_ide_dma(uint8_t channel) static int -cdrom_read_from_scsi_dma(uint8_t scsi_id, uint8_t scsi_lun) +cdrom_read_from_scsi_dma(uint8_t scsi_id) { cdrom_t *dev; - uint8_t id = scsi_cdrom_drives[scsi_id][scsi_lun]; - int32_t *BufLen = &SCSIDevices[scsi_id][scsi_lun].BufferLength; + uint8_t id = scsi_cdrom_drives[scsi_id]; + int32_t *BufLen = &SCSIDevices[scsi_id].BufferLength; if (id > CDROM_NUM) return 0; @@ -2862,7 +2847,7 @@ cdrom_read_from_scsi_dma(uint8_t scsi_id, uint8_t scsi_lun) dev = cdrom[id]; cdrom_log("Reading from SCSI DMA: SCSI ID %02X, init length %i\n", scsi_id, *BufLen); - memcpy(cdbufferb, SCSIDevices[scsi_id][scsi_lun].CmdBuffer, *BufLen); + memcpy(cdbufferb, SCSIDevices[scsi_id].CmdBuffer, *BufLen); return 1; } @@ -2878,11 +2863,11 @@ cdrom_irq_raise(cdrom_t *dev) static int cdrom_read_from_dma(cdrom_t *dev) { - int32_t *BufLen = &SCSIDevices[dev->drv->scsi_device_id][dev->drv->scsi_device_lun].BufferLength; + int32_t *BufLen = &SCSIDevices[dev->drv->scsi_device_id].BufferLength; int ret = 0; if (dev->drv->bus_type == CDROM_BUS_SCSI) - ret = cdrom_read_from_scsi_dma(dev->drv->scsi_device_id, dev->drv->scsi_device_lun); + ret = cdrom_read_from_scsi_dma(dev->drv->scsi_device_id); else ret = cdrom_read_from_ide_dma(dev->drv->ide_channel); @@ -2933,12 +2918,12 @@ cdrom_write_to_ide_dma(uint8_t channel) static int -cdrom_write_to_scsi_dma(uint8_t scsi_id, uint8_t scsi_lun) +cdrom_write_to_scsi_dma(uint8_t scsi_id) { cdrom_t *dev; - uint8_t id = scsi_cdrom_drives[scsi_id][scsi_lun]; - int32_t *BufLen = &SCSIDevices[scsi_id][scsi_lun].BufferLength; + uint8_t id = scsi_cdrom_drives[scsi_id]; + int32_t *BufLen = &SCSIDevices[scsi_id].BufferLength; if (id > CDROM_NUM) return 0; @@ -2946,15 +2931,15 @@ cdrom_write_to_scsi_dma(uint8_t scsi_id, uint8_t scsi_lun) dev = cdrom[id]; cdrom_log("Writing to SCSI DMA: SCSI ID %02X, init length %i\n", scsi_id, *BufLen); - memcpy(SCSIDevices[scsi_id][scsi_lun].CmdBuffer, cdbufferb, *BufLen); + memcpy(SCSIDevices[scsi_id].CmdBuffer, cdbufferb, *BufLen); cdrom_log("CD-ROM %i: Data from CD buffer: %02X %02X %02X %02X %02X %02X %02X %02X\n", id, cdbufferb[0], cdbufferb[1], cdbufferb[2], cdbufferb[3], cdbufferb[4], cdbufferb[5], cdbufferb[6], cdbufferb[7]); cdrom_log("CD-ROM %i: Data from SCSI DMA : %02X %02X %02X %02X %02X %02X %02X %02X\n", id, - SCSIDevices[scsi_id][scsi_lun].CmdBuffer[0], SCSIDevices[scsi_id][scsi_lun].CmdBuffer[1], - SCSIDevices[scsi_id][scsi_lun].CmdBuffer[2], SCSIDevices[scsi_id][scsi_lun].CmdBuffer[3], - SCSIDevices[scsi_id][scsi_lun].CmdBuffer[4], SCSIDevices[scsi_id][scsi_lun].CmdBuffer[5], - SCSIDevices[scsi_id][scsi_lun].CmdBuffer[6], SCSIDevices[scsi_id][scsi_lun].CmdBuffer[7]); + SCSIDevices[scsi_id].CmdBuffer[0], SCSIDevices[scsi_id].CmdBuffer[1], + SCSIDevices[scsi_id].CmdBuffer[2], SCSIDevices[scsi_id].CmdBuffer[3], + SCSIDevices[scsi_id].CmdBuffer[4], SCSIDevices[scsi_id].CmdBuffer[5], + SCSIDevices[scsi_id].CmdBuffer[6], SCSIDevices[scsi_id].CmdBuffer[7]); return 1; } @@ -2962,12 +2947,12 @@ cdrom_write_to_scsi_dma(uint8_t scsi_id, uint8_t scsi_lun) static int cdrom_write_to_dma(cdrom_t *dev) { - int32_t *BufLen = &SCSIDevices[dev->drv->scsi_device_id][dev->drv->scsi_device_lun].BufferLength; + int32_t *BufLen = &SCSIDevices[dev->drv->scsi_device_id].BufferLength; int ret = 0; if (dev->drv->bus_type == CDROM_BUS_SCSI) { - cdrom_log("Write to SCSI DMA: (%02X:%02X)\n", dev->drv->scsi_device_id, dev->drv->scsi_device_lun); - ret = cdrom_write_to_scsi_dma(dev->drv->scsi_device_id, dev->drv->scsi_device_lun); + cdrom_log("Write to SCSI DMA: (ID %02X)\n", dev->drv->scsi_device_id); + ret = cdrom_write_to_scsi_dma(dev->drv->scsi_device_id); } else ret = cdrom_write_to_ide_dma(dev->drv->ide_channel); @@ -2980,7 +2965,6 @@ cdrom_write_to_dma(cdrom_t *dev) } -/* If the result is 1, issue an IRQ, otherwise not. */ void cdrom_phase_callback(cdrom_t *dev) { @@ -2989,13 +2973,13 @@ cdrom_phase_callback(cdrom_t *dev) switch(dev->packet_status) { case CDROM_PHASE_IDLE: cdrom_log("CD-ROM %i: CDROM_PHASE_IDLE\n", dev->id); - dev->pos=0; + dev->pos = 0; dev->phase = 1; dev->status = READY_STAT | DRQ_STAT | (dev->status & ERR_STAT); return; case CDROM_PHASE_COMMAND: cdrom_log("CD-ROM %i: CDROM_PHASE_COMMAND\n", dev->id); - dev->status = BUSY_STAT | (dev->status &ERR_STAT); + dev->status = BUSY_STAT | (dev->status & ERR_STAT); memcpy(dev->atapi_cdb, cdbufferb, dev->cdb_len); cdrom_command(dev, dev->atapi_cdb); return; @@ -3040,14 +3024,14 @@ cdrom_phase_callback(cdrom_t *dev) ret = cdrom_write_to_dma(dev); if ((ret == 1) || (dev->drv->bus_type == CDROM_BUS_SCSI)) { - cdrom_log("CD-ROM %i: DMA data in phase done\n"); + cdrom_log("CD-ROM %i: DMA data in phase done\n", dev->id); cdrom_buf_free(dev); cdrom_command_complete(dev); } else if (ret == 2) { - cdrom_log("CD-ROM %i: DMA in not enabled, wait\n"); + cdrom_log("CD-ROM %i: DMA in not enabled, wait\n", dev->id); cdrom_command_bus(dev); } else { - cdrom_log("CD-ROM %i: DMA data in phase failure\n"); + cdrom_log("CD-ROM %i: DMA data in phase failure\n", dev->id); cdrom_buf_free(dev); } return; @@ -3109,17 +3093,17 @@ cdrom_read(uint8_t channel, int length) } if (dev->packet_status == CDROM_PHASE_DATA_IN) { + cdrom_log("CD-ROM %i: Returning: %04X (buffer position: %05i, request position: %05i)\n", + id, temp, (dev->pos - 2) & 0xffff, (dev->request_pos - 2) & 0xffff); if ((dev->request_pos >= dev->max_transfer_len) || (dev->pos >= dev->packet_len)) { /* Time for a DRQ. */ cdrom_log("CD-ROM %i: Issuing read callback\n", id); cdrom_pio_request(dev, 0); } - cdrom_log("CD-ROM %i: Returning: %02X (buffer position: %i, request position: %i)\n", id, - temp, dev->pos, dev->request_pos); return temp; } else { - cdrom_log("CD-ROM %i: Returning zero (buffer position: %i, request position: %i)\n", id, - dev->pos, dev->request_pos); + cdrom_log("CD-ROM %i: Returning: 0000 (buffer position: %05i, request position: %05i)\n", + id, (dev->pos - 2) & 0xffff, (dev->request_pos - 2) & 0xffff); return 0; } } @@ -3169,7 +3153,6 @@ cdrom_write(uint8_t channel, uint32_t val, int length) return; } - cdrom_log("CD-ROM %i: Write: %u\n", id, dev->pos); if (dev->packet_status == CDROM_PHASE_DATA_OUT) { if ((dev->request_pos >= dev->max_transfer_len) || (dev->pos >= dev->packet_len)) { /* Time for a DRQ. */ @@ -3178,8 +3161,7 @@ cdrom_write(uint8_t channel, uint32_t val, int length) return; } else if (dev->packet_status == CDROM_PHASE_IDLE) { if (dev->pos >= dev->cdb_len) { - cdrom_log("CD-ROM %i: Write: %u > 12\n", id, dev->pos); - dev->pos=0; + dev->pos = 0; dev->status = BUSY_STAT; dev->packet_status = CDROM_PHASE_COMMAND; timer_process(); @@ -3198,10 +3180,6 @@ cdrom_global_init(void) /* Clear the global data. */ memset(cdrom, 0x00, sizeof(cdrom)); memset(cdrom_drives, 0x00, sizeof(cdrom_drives)); - - /* Set all drives to NULL mode. */ - /* If this even needed? cdrom_hard_reset() is called before anything - attempts to talk to it, and that intializes everything. */ } @@ -3213,7 +3191,7 @@ cdrom_hard_reset(void) for (c = 0; c < CDROM_NUM; c++) { if (cdrom_drives[c].bus_type) { - cdrom_log("CDROM hard_reset drive=%d host=%02x\n", c, cdrom_drives[c].host_drive); + cdrom_log("CDROM hard_reset drive=%d\n", c); if (!cdrom[c]) { cdrom[c] = (cdrom_t *) malloc(sizeof(cdrom_t)); diff --git a/src/cdrom/cdrom.h b/src/cdrom/cdrom.h index 337c62285..9f6f4d476 100644 --- a/src/cdrom/cdrom.h +++ b/src/cdrom/cdrom.h @@ -9,7 +9,7 @@ * Implementation of the CD-ROM drive with SCSI(-like) * commands, for both ATAPI and SCSI usage. * - * Version: @(#)cdrom.h 1.0.12 2018/04/30 + * Version: @(#)cdrom.h 1.0.13 2018/06/18 * * Author: Miran Grca, * @@ -82,8 +82,7 @@ typedef struct { bus_mode; /* Bit 0 = PIO suported; Bit 1 = DMA supportd. */ - unsigned int scsi_device_id, scsi_device_lun, - sound_on; + unsigned int scsi_device_id, sound_on; } cdrom_drive_t; typedef struct { @@ -139,7 +138,7 @@ extern cdrom_t *cdrom[CDROM_NUM]; extern cdrom_drive_t cdrom_drives[CDROM_NUM]; extern cdrom_image_t cdrom_image[CDROM_NUM]; extern uint8_t atapi_cdrom_drives[8]; -extern uint8_t scsi_cdrom_drives[16][8]; +extern uint8_t scsi_cdrom_drives[16]; #define cdrom_sense_error dev->sense[0] #define cdrom_sense_key dev->sense[2] @@ -178,7 +177,7 @@ extern void cdrom_request_sense_for_scsi(cdrom_t *dev, uint8_t *buffer, uint8_t extern void cdrom_update_cdb(uint8_t *cdb, int lba_pos, int number_of_blocks); extern void cdrom_insert(cdrom_t *dev); -extern int find_cdrom_for_scsi_id(uint8_t scsi_id, uint8_t scsi_lun); +extern int find_cdrom_for_scsi_id(uint8_t scsi_id); extern int cdrom_read_capacity(cdrom_t *dev, uint8_t *cdb, uint8_t *buffer, uint32_t *len); extern void cdrom_global_init(void); diff --git a/src/config.c b/src/config.c index 6a799d71f..f419539da 100644 --- a/src/config.c +++ b/src/config.c @@ -8,7 +8,7 @@ * * Configuration file handler. * - * Version: @(#)config.c 1.0.47 2018/04/29 + * Version: @(#)config.c 1.0.48 2018/05/25 * * Authors: Sarah Walker, * Miran Grca, @@ -40,7 +40,6 @@ #include "disk/hdd.h" #include "disk/hdc.h" #include "disk/hdc_ide.h" -#include "disk/zip.h" #include "floppy/fdd.h" #include "floppy/fdc.h" #include "game/gameport.h" @@ -49,6 +48,7 @@ #include "network/network.h" #include "scsi/scsi.h" #include "cdrom/cdrom.h" +#include "disk/zip.h" #include "sound/sound.h" #include "sound/midi.h" #include "sound/snd_dbopl.h" @@ -559,8 +559,6 @@ load_video(void) gfxcard = video_get_video_from_internal_name(p); } - video_speed = config_get_int(cat, "video_speed", -1); - voodoo_enabled = !!config_get_int(cat, "voodoo", 0); } @@ -679,9 +677,9 @@ load_network(void) if (p != NULL) { if ((network_dev_to_id(p) == -1) || (network_ndev == 1)) { if ((network_ndev == 1) && strcmp(network_host, "none")) { - ui_msgbox(MBX_ERROR, (wchar_t *)IDS_2140); + ui_msgbox(MBX_ERROR, (wchar_t *)IDS_2103); } else if (network_dev_to_id(p) == -1) { - ui_msgbox(MBX_ERROR, (wchar_t *)IDS_2141); + ui_msgbox(MBX_ERROR, (wchar_t *)IDS_2104); } strcpy(network_host, "none"); @@ -786,6 +784,8 @@ load_hard_disks(void) wchar_t *wp; uint32_t max_spt, max_hpc, max_tracks; uint32_t board = 0, dev = 0; + /* FIXME: Remove in a month. */ + int lun; memset(temp, '\0', sizeof(temp)); for (c=0; c 15) hdd[c].scsi_id = 15; - if (hdd[c].scsi_lun > 7) - hdd[c].scsi_lun = 7; - } else { + } else config_delete_var(cat, temp); + + /* FIXME: Remove in a month. */ + sprintf(temp, "hdd_%02i_scsi_location", c+1); + if (hdd[c].bus == HDD_BUS_SCSI) { + p = config_get_string(cat, temp, NULL); + + if (p) { + sscanf(p, "%02i:%02i", + (int *)&hdd[c].scsi_id, (int *)&lun); + + if (hdd[c].scsi_id > 15) + hdd[c].scsi_id = 15; + } } + config_delete_var(cat, temp); memset(hdd[c].fn, 0x00, sizeof(hdd[c].fn)); memset(hdd[c].prev_fn, 0x00, sizeof(hdd[c].prev_fn)); @@ -930,6 +938,10 @@ load_hard_disks(void) sprintf(temp, "hdd_%02i_ide_channels", c+1); config_delete_var(cat, temp); + sprintf(temp, "hdd_%02i_scsi_id", c+1); + config_delete_var(cat, temp); + + /* FIXME: Remove in a month. */ sprintf(temp, "hdd_%02i_scsi_location", c+1); config_delete_var(cat, temp); @@ -1028,6 +1040,8 @@ load_other_removable_devices(void) unsigned int board = 0, dev = 0; wchar_t *wp; int c; + /* FIXME: Remove in a month. */ + int lun; memset(temp, 0x00, sizeof(temp)); for (c=0; c 7) cdrom_drives[c].ide_channel = 7; } else { - sprintf(temp, "cdrom_%02i_scsi_location", c+1); + sprintf(temp, "cdrom_%02i_scsi_id", c+1); if (cdrom_drives[c].bus_type == CDROM_BUS_SCSI) { - sprintf(tmp2, "%02u:%02u", c+2, 0); - p = config_get_string(cat, temp, tmp2); - sscanf(p, "%02u:%02u", - &cdrom_drives[c].scsi_device_id, - &cdrom_drives[c].scsi_device_lun); + cdrom_drives[c].scsi_device_id = config_get_int(cat, temp, c+2); if (cdrom_drives[c].scsi_device_id > 15) cdrom_drives[c].scsi_device_id = 15; - if (cdrom_drives[c].scsi_device_lun > 7) - cdrom_drives[c].scsi_device_lun = 7; - } else { + } else config_delete_var(cat, temp); + + /* FIXME: Remove in a month. */ + sprintf(temp, "cdrom_%02i_scsi_location", c+1); + if (cdrom_drives[c].bus_type == CDROM_BUS_SCSI) { + p = config_get_string(cat, temp, NULL); + if (p) { + sscanf(p, "%02u:%02u", + &cdrom_drives[c].scsi_device_id, &lun); + + if (cdrom_drives[c].scsi_device_id > 15) + cdrom_drives[c].scsi_device_id = 15; + } } + config_delete_var(cat, temp); } sprintf(temp, "cdrom_%02i_image_path", c+1); @@ -1118,6 +1139,10 @@ load_other_removable_devices(void) sprintf(temp, "cdrom_%02i_ide_channel", c+1); config_delete_var(cat, temp); + sprintf(temp, "cdrom_%02i_scsi_id", c+1); + config_delete_var(cat, temp); + + /* FIXME: Remove in a month. */ sprintf(temp, "cdrom_%02i_scsi_location", c+1); config_delete_var(cat, temp); @@ -1154,21 +1179,28 @@ load_other_removable_devices(void) if (zip_drives[c].ide_channel > 7) zip_drives[c].ide_channel = 7; } else { - sprintf(temp, "zip_%02i_scsi_location", c+1); + sprintf(temp, "zip_%02i_scsi_id", c+1); if (zip_drives[c].bus_type == CDROM_BUS_SCSI) { - sprintf(tmp2, "%02u:%02u", c+2, 0); - p = config_get_string(cat, temp, tmp2); - sscanf(p, "%02u:%02u", - &zip_drives[c].scsi_device_id, - &zip_drives[c].scsi_device_lun); + zip_drives[c].scsi_device_id = config_get_int(cat, temp, c+2); if (zip_drives[c].scsi_device_id > 15) zip_drives[c].scsi_device_id = 15; - if (zip_drives[c].scsi_device_lun > 7) - zip_drives[c].scsi_device_lun = 7; - } else { + } else config_delete_var(cat, temp); + + /* FIXME: Remove in a month. */ + sprintf(temp, "zip_%02i_scsi_location", c+1); + if (zip_drives[c].bus_type == CDROM_BUS_SCSI) { + p = config_get_string(cat, temp, NULL); + if (p) { + sscanf(p, "%02u:%02u", + &zip_drives[c].scsi_device_id, &lun); + + if (zip_drives[c].scsi_device_id > 15) + zip_drives[c].scsi_device_id = 15; + } } + config_delete_var(cat, temp); } sprintf(temp, "zip_%02i_image_path", c+1); @@ -1204,6 +1236,10 @@ load_other_removable_devices(void) sprintf(temp, "zip_%02i_ide_channel", c+1); config_delete_var(cat, temp); + sprintf(temp, "zip_%02i_scsi_id", c+1); + config_delete_var(cat, temp); + + /* FIXME: Remove in a month. */ sprintf(temp, "zip_%02i_scsi_location", c+1); config_delete_var(cat, temp); @@ -1242,7 +1278,6 @@ config_load(void) machine = machine_get_machine_from_internal_name("ibmpc"); gfxcard = GFX_CGA; vid_api = plat_vidapi("default"); - video_speed = -1; enable_sync = 1; joystick_type = 7; if (hdc_name) { @@ -1438,11 +1473,6 @@ save_video(void) config_set_string(cat, "gfxcard", video_get_internal_name(video_old_to_new(gfxcard))); - if (video_speed == 3) - config_delete_var(cat, "video_speed"); - else - config_set_int(cat, "video_speed", video_speed); - if (voodoo_enabled == 0) config_delete_var(cat, "voodoo"); else @@ -1705,7 +1735,7 @@ save_hard_disks(void) sprintf(temp, "hdd_%02i_esdi_channel", c+1); if (hdd_is_valid(c) && (hdd[c].bus == HDD_BUS_ESDI)) config_set_int(cat, temp, hdd[c].esdi_channel); - else + else config_delete_var(cat, temp); sprintf(temp, "hdd_%02i_ide_channel", c+1); @@ -1716,18 +1746,16 @@ save_hard_disks(void) config_set_string(cat, temp, tmp2); } - sprintf(temp, "hdd_%02i_scsi_location", c+1); - if (! hdd_is_valid(c) || (hdd[c].bus != HDD_BUS_SCSI)) { + sprintf(temp, "hdd_%02i_scsi_id", c+1); + if (hdd_is_valid(c) && (hdd[c].bus == HDD_BUS_SCSI)) + config_set_int(cat, temp, hdd[c].scsi_id); + else config_delete_var(cat, temp); - } else { - sprintf(tmp2, "%02u:%02u", hdd[c].scsi_id, hdd[c].scsi_lun); - config_set_string(cat, temp, tmp2); - } sprintf(temp, "hdd_%02i_fn", c+1); if (hdd_is_valid(c) && (wcslen(hdd[c].fn) != 0)) config_set_wstring(cat, temp, hdd[c].fn); - else + else config_delete_var(cat, temp); } @@ -1828,13 +1856,11 @@ save_other_removable_devices(void) config_set_string(cat, temp, tmp2); } - sprintf(temp, "cdrom_%02i_scsi_location", c + 1); + sprintf(temp, "cdrom_%02i_scsi_id", c + 1); if (cdrom_drives[c].bus_type != CDROM_BUS_SCSI) { config_delete_var(cat, temp); } else { - sprintf(tmp2, "%02u:%02u", cdrom_drives[c].scsi_device_id, - cdrom_drives[c].scsi_device_lun); - config_set_string(cat, temp, tmp2); + config_set_int(cat, temp, cdrom_drives[c].scsi_device_id); } sprintf(temp, "cdrom_%02i_image_path", c + 1); @@ -1865,13 +1891,11 @@ save_other_removable_devices(void) config_set_string(cat, temp, tmp2); } - sprintf(temp, "zip_%02i_scsi_location", c + 1); + sprintf(temp, "zip_%02i_scsi_id", c + 1); if (zip_drives[c].bus_type != ZIP_BUS_SCSI) { config_delete_var(cat, temp); } else { - sprintf(tmp2, "%02u:%02u", zip_drives[c].scsi_device_id, - zip_drives[c].scsi_device_lun); - config_set_string(cat, temp, tmp2); + config_set_int(cat, temp, zip_drives[c].scsi_device_id); } sprintf(temp, "zip_%02i_image_path", c + 1); diff --git a/src/cpu/cpu_table.c b/src/cpu/cpu_table.c index 92fdd93f4..a715caa43 100644 --- a/src/cpu/cpu_table.c +++ b/src/cpu/cpu_table.c @@ -60,6 +60,7 @@ CPU cpus_8088[] = { {"8088/12", CPU_8088, 3, 12000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, {"8088/16", CPU_8088, 4, 16000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, #endif + {"286/6", CPU_286, 0, 6000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1}, {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0} }; diff --git a/src/disk/hdc_ide.c b/src/disk/hdc_ide.c index a59fb2f06..8ed9d188e 100644 --- a/src/disk/hdc_ide.c +++ b/src/disk/hdc_ide.c @@ -9,7 +9,7 @@ * Implementation of the IDE emulation for hard disks and ATAPI * CD-ROM devices. * - * Version: @(#)hdc_ide.c 1.0.46 2018/05/02 + * Version: @(#)hdc_ide.c 1.0.47 2018/06/02 * * Authors: Sarah Walker, * Miran Grca, @@ -844,7 +844,7 @@ ide_set_signature(ide_t *ide) ide->head=0; if (ide_drive_is_zip(ide)) { - zip_set_signature(zip_id); + zip_set_signature(zip[zip_id]); ide->secount = zip[zip_id]->phase; ide->cylinder = zip[zip_id]->request_length; } else if (ide_drive_is_cdrom(ide)) { @@ -2058,7 +2058,7 @@ ide_callback(void *priv) if (ide_drive_is_zip(ide)) { zip[zip_id]->status = DRDY_STAT | DSC_STAT; zip[zip_id]->error = 1; - zip_reset(zip_id); + zip_reset(zip[zip_id]); } else if (ide_drive_is_cdrom(ide)) { cdrom[cdrom_id]->status = DRDY_STAT | DSC_STAT; cdrom[cdrom_id]->error = 1; @@ -2451,7 +2451,7 @@ ide_callback(void *priv) goto abort_cmd; if (ide_drive_is_zip(ide)) - zip_phase_callback(atapi_zip_drives[ch]); + zip_phase_callback(zip[atapi_zip_drives[ch]]); else cdrom_phase_callback(cdrom[atapi_cdrom_drives[ch]]); return; diff --git a/src/disk/hdd.c b/src/disk/hdd.c index 30b031249..805618a75 100644 --- a/src/disk/hdd.c +++ b/src/disk/hdd.c @@ -8,7 +8,7 @@ * * Common code to handle all sorts of hard disk images. * - * Version: @(#)hdd.c 1.0.8 2018/04/24 + * Version: @(#)hdd.c 1.0.9 2018/05/25 * * Authors: Miran Grca, * Fred N. van Kempen, @@ -48,7 +48,7 @@ hdd_string_to_bus(char *str, int cdrom) if (! strcmp(str, "mfm")) { if (cdrom) { no_cdrom: - ui_msgbox(MBX_ERROR, (wchar_t *)IDS_4114); + ui_msgbox(MBX_ERROR, (wchar_t *)IDS_4099); return(0); } diff --git a/src/disk/hdd.h b/src/disk/hdd.h index cc5f75a38..b9b439a4b 100644 --- a/src/disk/hdd.h +++ b/src/disk/hdd.h @@ -8,7 +8,7 @@ * * Definitions for the hard disk image handler. * - * Version: @(#)hdd.h 1.0.5 2018/04/30 + * Version: @(#)hdd.h 1.0.6 2018/06/09 * * Authors: Miran Grca, * Fred N. van Kempen, @@ -84,7 +84,6 @@ typedef struct { uint8_t xta_channel; uint8_t ide_channel; uint8_t scsi_id; - uint8_t scsi_lun; uint32_t base, spt, @@ -104,6 +103,31 @@ extern hard_disk_t hdd[HDD_NUM]; extern unsigned int hdd_table[128][3]; +typedef struct vhd_footer_t +{ + uint8_t cookie[8]; + uint32_t features; + uint32_t version; + uint64_t offset; + uint32_t timestamp; + uint8_t creator[4]; + uint32_t creator_vers; + uint8_t creator_host_os[4]; + uint64_t orig_size; + uint64_t curr_size; + struct { + uint16_t cyl; + uint8_t heads; + uint8_t spt; + } geom; + uint32_t type; + uint32_t checksum; + uint8_t uuid[16]; + uint8_t saved_state; + uint8_t reserved[427]; +} vhd_footer_t; + + extern int hdd_init(void); extern int hdd_string_to_bus(char *str, int cdrom); extern char *hdd_bus_to_string(int bus, int cdrom); @@ -124,9 +148,16 @@ extern uint8_t hdd_image_get_type(uint8_t id); extern void hdd_image_specify(uint8_t id, uint64_t hpc, uint64_t spt); extern void hdd_image_unload(uint8_t id, int fn_preserve); extern void hdd_image_close(uint8_t id); +extern void hdd_image_calc_chs(uint32_t *c, uint32_t *h, uint32_t *s, uint32_t size); + +extern void vhd_footer_from_bytes(vhd_footer_t *vhd, uint8_t *bytes); +extern void vhd_footer_to_bytes(uint8_t *bytes, vhd_footer_t *vhd); +extern void new_vhd_footer(vhd_footer_t **vhd); +extern void generate_vhd_checksum(vhd_footer_t *vhd); extern int image_is_hdi(const wchar_t *s); extern int image_is_hdx(const wchar_t *s, int check_signature); +extern int image_is_vhd(const wchar_t *s, int check_signature); #endif /*EMU_HDD_H*/ diff --git a/src/disk/hdd_image.c b/src/disk/hdd_image.c index 7f1563626..b895158cb 100644 --- a/src/disk/hdd_image.c +++ b/src/disk/hdd_image.c @@ -8,7 +8,7 @@ * * Handling of hard disk image files. * - * Version: @(#)hdd_image.c 1.0.15 2018/04/29 + * Version: @(#)hdd_image.c 1.0.16 2018/06/09 * * Authors: Miran Grca, * Fred N. van Kempen, @@ -24,11 +24,13 @@ #include #include #include +#include #include #include #define HAVE_STDARG_H #include "../86box.h" #include "../plat.h" +#include "../random.h" #include "hdd.h" @@ -48,6 +50,26 @@ static char empty_sector[512]; static char *empty_sector_1mb; +#define VHD_OFFSET_COOKIE 0 +#define VHD_OFFSET_FEATURES 8 +#define VHD_OFFSET_VERSION 12 +#define VHD_OFFSET_DATA_OFFSET 16 +#define VHD_OFFSET_TIMESTAMP 24 +#define VHD_OFFSET_CREATOR 28 +#define VHD_OFFSET_CREATOR_VERS 32 +#define VHD_OFFSET_CREATOR_HOST 36 +#define VHD_OFFSET_ORIG_SIZE 40 +#define VHD_OFFSET_CURR_SIZE 48 +#define VHD_OFFSET_GEOM_CYL 56 +#define VHD_OFFSET_GEOM_HEAD 58 +#define VHD_OFFSET_GEOM_SPT 59 +#define VHD_OFFSET_TYPE 60 +#define VHD_OFFSET_CHECKSUM 64 +#define VHD_OFFSET_UUID 68 +#define VHD_OFFSET_SAVED_STATE 84 +#define VHD_OFFSET_RESERVED 85 + + #ifdef ENABLE_HDD_IMAGE_LOG int hdd_image_do_log = ENABLE_HDD_IMAGE_LOG; #endif @@ -121,6 +143,303 @@ image_is_hdx(const wchar_t *s, int check_signature) } +int +image_is_vhd(const wchar_t *s, int check_signature) +{ + int len; + FILE *f; + uint64_t filelen; + uint64_t signature; + char *ws = (char *) s; + wchar_t ext[5] = { 0, 0, 0, 0, 0 }; + len = wcslen(s); + if ((len < 4) || (s[0] == L'.')) + return 0; + memcpy(ext, ws + ((len - 4) << 1), 8); + if (wcscasecmp(ext, L".VHD") == 0) { + if (check_signature) { + f = plat_fopen((wchar_t *)s, L"rb"); + if (!f) + return 0; + fseeko64(f, 0, SEEK_END); + filelen = ftello64(f); + fseeko64(f, -512, SEEK_END); + if (filelen < 512) + return 0; + fread(&signature, 1, 8, f); + fclose(f); + if (signature == 0x78697463656E6F63ll) + return 1; + else + return 0; + } else + return 1; + } else + return 0; +} + + +static uint64_t +be_to_u64(uint8_t *bytes, int start) +{ + uint64_t n = ((uint64_t)bytes[start+7] << 0) | + ((uint64_t)bytes[start+6] << 8) | + ((uint64_t)bytes[start+5] << 16) | + ((uint64_t)bytes[start+4] << 24) | + ((uint64_t)bytes[start+3] << 32) | + ((uint64_t)bytes[start+2] << 40) | + ((uint64_t)bytes[start+1] << 48) | + ((uint64_t)bytes[start] << 56); + return n; +} + + +static uint32_t +be_to_u32(uint8_t *bytes, int start) +{ + uint32_t n = ((uint32_t)bytes[start+3] << 0) | + ((uint32_t)bytes[start+2] << 8) | + ((uint32_t)bytes[start+1] << 16) | + ((uint32_t)bytes[start] << 24); + return n; +} + + +static uint16_t +be_to_u16(uint8_t *bytes, int start) +{ + uint16_t n = ((uint16_t)bytes[start+1] << 0) | + ((uint16_t)bytes[start] <<8); + return n; +} + + +static uint64_t +u64_to_be(uint64_t value, int is_be) +{ + uint64_t res = 0; + if (is_be) + res = value; + else { + uint64_t mask = 0xff00000000000000; + res = ((value & (mask >> 0)) >> 56) | + ((value & (mask >> 8)) >> 40) | + ((value & (mask >> 16)) >> 24) | + ((value & (mask >> 24)) >> 8) | + ((value & (mask >> 32)) << 8) | + ((value & (mask >> 40)) << 24) | + ((value & (mask >> 48)) << 40) | + ((value & (mask >> 56)) << 56); + } + return res; +} + + +static uint32_t +u32_to_be(uint32_t value, int is_be) +{ + uint32_t res = 0; + if (is_be) + res = value; + else { + uint32_t mask = 0xff000000; + res = ((value & (mask >> 0)) >> 24) | + ((value & (mask >> 8)) >> 8) | + ((value & (mask >> 16)) << 8) | + ((value & (mask >> 24)) << 24); + } + return res; +} + + +static uint16_t +u16_to_be(uint16_t value, int is_be) +{ + uint16_t res = 0; + if (is_be) + res = value; + else + res = (value >> 8) | (value << 8); + + return res; +} + + +static void +mk_guid(uint8_t *guid) +{ + int n; + + for (n = 0; n < 16; n++) + guid[n] = random_generate(); + + guid[6] &= 0x0F; + guid[6] |= 0x40; /* Type 4 */ + guid[8] &= 0x3F; + guid[8] |= 0x80; /* Variant 1 */ +} + + +static uint32_t +calc_vhd_timestamp() +{ + time_t start_time; + time_t curr_time; + double vhd_time; + start_time = 946684800; /* 1 Jan 2000 00:00 */ + curr_time = time(NULL); + vhd_time = difftime(curr_time, start_time); + + return (uint32_t)vhd_time; +} + + +void +vhd_footer_from_bytes(vhd_footer_t *vhd, uint8_t *bytes) +{ + memcpy(vhd->cookie, bytes + VHD_OFFSET_COOKIE, sizeof(vhd->cookie)); + vhd->features = be_to_u32(bytes, VHD_OFFSET_FEATURES); + vhd->version = be_to_u32(bytes, VHD_OFFSET_VERSION); + vhd->offset = be_to_u64(bytes, VHD_OFFSET_DATA_OFFSET); + vhd->timestamp = be_to_u32(bytes, VHD_OFFSET_TIMESTAMP); + memcpy(vhd->creator, bytes + VHD_OFFSET_CREATOR, sizeof(vhd->creator)); + vhd->creator_vers = be_to_u32(bytes, VHD_OFFSET_CREATOR_VERS); + memcpy(vhd->creator_host_os, bytes + VHD_OFFSET_CREATOR_HOST, sizeof(vhd->creator_host_os)); + vhd->orig_size = be_to_u64(bytes, VHD_OFFSET_ORIG_SIZE); + vhd->curr_size = be_to_u64(bytes, VHD_OFFSET_CURR_SIZE); + vhd->geom.cyl = be_to_u16(bytes, VHD_OFFSET_GEOM_CYL); + vhd->geom.heads = bytes[VHD_OFFSET_GEOM_HEAD]; + vhd->geom.spt = bytes[VHD_OFFSET_GEOM_SPT]; + vhd->type = be_to_u32(bytes, VHD_OFFSET_TYPE); + vhd->checksum = be_to_u32(bytes, VHD_OFFSET_CHECKSUM); + memcpy(vhd->uuid, bytes + VHD_OFFSET_UUID, sizeof(vhd->uuid)); /* TODO: handle UUID's properly */ + vhd->saved_state = bytes[VHD_OFFSET_SAVED_STATE]; + memcpy(vhd->reserved, bytes + VHD_OFFSET_RESERVED, sizeof(vhd->reserved)); +} + + +void +vhd_footer_to_bytes(uint8_t *bytes, vhd_footer_t *vhd) +{ + /* Quick endian check */ + int is_be = 0; + uint8_t e = 1; + uint8_t *ep = &e; + uint16_t u16; + uint32_t u32; + uint64_t u64; + + if (ep[0] == 0) + is_be = 1; + + memcpy(bytes + VHD_OFFSET_COOKIE, vhd->cookie, sizeof(vhd->cookie)); + u32 = u32_to_be(vhd->features, is_be); + memcpy(bytes + VHD_OFFSET_FEATURES, &u32, sizeof(vhd->features)); + u32 = u32_to_be(vhd->version, is_be); + memcpy(bytes + VHD_OFFSET_VERSION, &u32, sizeof(vhd->version)); + u64 = u64_to_be(vhd->offset, is_be); + memcpy(bytes + VHD_OFFSET_DATA_OFFSET, &u64, sizeof(vhd->offset)); + u32 = u32_to_be(vhd->timestamp, is_be); + memcpy(bytes + VHD_OFFSET_TIMESTAMP, &u32, sizeof(vhd->timestamp)); + memcpy(bytes + VHD_OFFSET_CREATOR, vhd->creator, sizeof(vhd->creator)); + u32 = u32_to_be(vhd->creator_vers, is_be); + memcpy(bytes + VHD_OFFSET_CREATOR_VERS, &u32, sizeof(vhd->creator_vers)); + memcpy(bytes + VHD_OFFSET_CREATOR_HOST, vhd->creator_host_os, sizeof(vhd->creator_host_os)); + u64 = u64_to_be(vhd->orig_size, is_be); + memcpy(bytes + VHD_OFFSET_ORIG_SIZE, &u64, sizeof(vhd->orig_size)); + u64 = u64_to_be(vhd->curr_size, is_be); + memcpy(bytes + VHD_OFFSET_CURR_SIZE, &u64, sizeof(vhd->curr_size)); + u16 = u16_to_be(vhd->geom.cyl, is_be); + memcpy(bytes + VHD_OFFSET_GEOM_CYL, &u16, sizeof(vhd->geom.cyl)); + memcpy(bytes + VHD_OFFSET_GEOM_HEAD, &(vhd->geom.heads), sizeof(vhd->geom.heads)); + memcpy(bytes + VHD_OFFSET_GEOM_SPT, &(vhd->geom.spt), sizeof(vhd->geom.spt)); + u32 = u32_to_be(vhd->type, is_be); + memcpy(bytes + VHD_OFFSET_TYPE, &u32, sizeof(vhd->type)); + u32 = u32_to_be(vhd->checksum, is_be); + memcpy(bytes + VHD_OFFSET_CHECKSUM, &u32, sizeof(vhd->checksum)); + memcpy(bytes + VHD_OFFSET_UUID, vhd->uuid, sizeof(vhd->uuid)); + memcpy(bytes + VHD_OFFSET_SAVED_STATE, &(vhd->saved_state), sizeof(vhd->saved_state)); + memcpy(bytes + VHD_OFFSET_RESERVED, vhd->reserved, sizeof(vhd->reserved)); +} + + +void +new_vhd_footer(vhd_footer_t **vhd) +{ + uint8_t cookie[8] = {'c', 'o', 'n', 'e', 'c', 't', 'i', 'x'}; + uint8_t creator[4] = {'8', '6', 'b', 'x'}; + uint8_t cr_host_os[4] = {'W', 'i', '2', 'k'}; + + if (*vhd == NULL) + *vhd = (vhd_footer_t *) malloc(sizeof(vhd_footer_t)); + + memcpy((*vhd)->cookie, cookie, 8); + (*vhd)->features = 0x00000002; + (*vhd)->version = 0x00010000; + (*vhd)->offset = 0xffffffffffffffff; /* fixed disk */ + (*vhd)->timestamp = calc_vhd_timestamp(); + memcpy((*vhd)->creator, creator, 4); + (*vhd)->creator_vers = 0x00010000; + memcpy((*vhd)->creator_host_os, cr_host_os, 4); + (*vhd)->type = 2; /* fixed disk */ + mk_guid((*vhd)->uuid); + (*vhd)->saved_state = 0; + memset((*vhd)->reserved, 0, 427); +} + + +void +generate_vhd_checksum(vhd_footer_t *vhd) +{ + uint32_t chk = 0; + int i; + for (i = 0; i < sizeof(vhd_footer_t); i++) { + /* We don't include the checksum field in the checksum */ + if ((i < VHD_OFFSET_CHECKSUM) || (i >= VHD_OFFSET_UUID)) + chk += ((uint8_t*)vhd)[i]; + } + vhd->checksum = ~chk; +} + + +void +hdd_image_calc_chs(uint32_t *c, uint32_t *h, uint32_t *s, uint32_t size) +{ + /* Calculate the geometry from size (in MB), using the algorithm provided in + "Virtual Hard Disk Image Format Specification, Appendix: CHS Calculation" */ + uint64_t ts = ((uint64_t) size) << 11LL; + uint32_t spt, heads, cyl, cth; + if (ts > 65535 * 16 * 255) + ts = 65535 * 16 * 255; + + if (ts >= 65535 * 16 * 63) { + spt = 255; + heads = 16; + cth = ts / spt; + } else { + spt = 17; + cth = ts / spt; + heads = (cth +1023) / 1024; + if (heads < 4) + heads = 4; + if ((cth >= (heads * 1024)) || (heads > 16)) { + spt = 31; + heads = 16; + cth = ts / spt; + } + if (cth >= (heads * 1024)) { + spt = 63; + heads = 16; + cth = ts / spt; + } + } + cyl = cth / heads; + *c = cyl; + *h = heads; + *s = spt; +} + + static int prepare_new_hard_disk(uint8_t id, uint64_t full_size) { @@ -182,10 +501,12 @@ hdd_image_load(int id) uint64_t signature = 0xD778A82044445459ll; uint64_t full_size = 0; uint64_t spt = 0, hpc = 0, tracks = 0; - int c; + int c, ret; uint64_t s = 0; wchar_t *fn = hdd[id].fn; int is_hdx[2] = { 0, 0 }; + int is_vhd[2] = { 0, 0 }; + vhd_footer_t *vft = NULL; memset(empty_sector, 0, sizeof(empty_sector)); @@ -202,6 +523,9 @@ hdd_image_load(int id) is_hdx[0] = image_is_hdx(fn, 0); is_hdx[1] = image_is_hdx(fn, 1); + is_vhd[0] = image_is_vhd(fn, 0); + is_vhd[1] = image_is_vhd(fn, 1); + hdd_images[id].pos = 0; /* Try to open existing hard disk image */ @@ -268,7 +592,29 @@ hdd_image_load(int id) ((uint64_t) hdd[id].hpc) * ((uint64_t) hdd[id].tracks) << 9LL; - return prepare_new_hard_disk(id, full_size); + ret = prepare_new_hard_disk(id, full_size); + + if (is_vhd[0]) { + /* VHD image. */ + /* Generate new footer. */ + empty_sector_1mb = (char *) malloc(512); + new_vhd_footer(&vft); + vft->orig_size = vft->curr_size = full_size; + vft->geom.cyl = tracks; + vft->geom.heads = hpc; + vft->geom.spt = spt; + generate_vhd_checksum(vft); + memset(empty_sector_1mb, 0, 512); + vhd_footer_to_bytes((uint8_t *) empty_sector_1mb, vft); + fwrite(empty_sector_1mb, 1, 512, hdd_images[id].file); + free(vft); + vft = NULL; + free(empty_sector_1mb); + empty_sector_1mb = NULL; + hdd_images[id].type = 3; + } + + return ret; } else { /* Failed for another reason */ hdd_image_log("Failed for another reason\n"); @@ -322,6 +668,40 @@ hdd_image_load(int id) fread(&(hdd[id].at_spt), 1, 4, hdd_images[id].file); fread(&(hdd[id].at_hpc), 1, 4, hdd_images[id].file); hdd_images[id].type = 2; + } else if (is_vhd[1]) { + empty_sector_1mb = (char *) malloc(512); + memset(empty_sector_1mb, 0, 512); + fseeko64(hdd_images[id].file, -512, SEEK_END); + fread(empty_sector_1mb, 1, 512, hdd_images[id].file); + new_vhd_footer(&vft); + vhd_footer_from_bytes(vft, (uint8_t *) empty_sector_1mb); + if (vft->type != 2) { + /* VHD is not fixed size */ + hdd_image_log("VHD: Image is not fixed size\n"); + free(vft); + vft = NULL; + free(empty_sector_1mb); + empty_sector_1mb = NULL; + fclose(hdd_images[id].file); + hdd_images[id].file = NULL; + memset(hdd[id].fn, 0, sizeof(hdd[id].fn)); + return 0; + } + full_size = vft->orig_size; + hdd[id].tracks = vft->geom.cyl; + hdd[id].hpc = vft->geom.heads; + hdd[id].spt = vft->geom.spt; + free(vft); + vft = NULL; + free(empty_sector_1mb); + empty_sector_1mb = NULL; + hdd_images[id].type = 3; + /* If we're here, this means there is a valid VHD footer in the + image, which means that by definition, all valid sectors + are there. */ + hdd_images[id].last_sector = (uint32_t) (full_size >> 9) - 1; + hdd_images[id].loaded = 1; + return 1; } else { full_size = ((uint64_t) hdd[id].spt) * ((uint64_t) hdd[id].hpc) * diff --git a/src/disk/zip.c b/src/disk/zip.c index c0b015265..e2a4c28d3 100644 --- a/src/disk/zip.c +++ b/src/disk/zip.c @@ -9,7 +9,7 @@ * Implementation of the Iomega ZIP drive with SCSI(-like) * commands, for both ATAPI and SCSI usage. * - * Version: @(#)zip.c 1.0.20 2018/03/26 + * Version: @(#)zip.c 1.0.21 2018/05/28 * * Author: Miran Grca, * @@ -54,22 +54,8 @@ zip_t *zip[ZIP_NUM]; zip_drive_t zip_drives[ZIP_NUM]; uint8_t atapi_zip_drives[8] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; -uint8_t scsi_zip_drives[16][8] = { { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } }; +uint8_t scsi_zip_drives[16] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; /* Table of all SCSI commands and their flags, needed for the new disc change / not ready handler. */ @@ -86,7 +72,7 @@ const uint8_t zip_command_flags[0x100] = IMPLEMENTED | CHECK_READY, /* 0x08 */ 0, IMPLEMENTED | CHECK_READY, /* 0x0A */ - 0, + IMPLEMENTED | CHECK_READY | NONDATA, /* 0x0B */ IMPLEMENTED, /* 0x0C */ IMPLEMENTED | ATAPI_ONLY, /* 0x0D */ 0, 0, 0, 0, @@ -110,7 +96,8 @@ const uint8_t zip_command_flags[0x100] = IMPLEMENTED | CHECK_READY, /* 0x28 */ 0, IMPLEMENTED | CHECK_READY, /* 0x2A */ - 0, 0, 0, + IMPLEMENTED | CHECK_READY | NONDATA, /* 0x2B */ + 0, 0, IMPLEMENTED | CHECK_READY, /* 0x2E */ IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, /* 0x2F */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -462,13 +449,11 @@ static const mode_sense_pages_t zip_250_mode_sense_pages_changeable = { 0x2f, 0x04, 0x5c, 0x0f, 0x3c, 0x0f } } }; -static mode_sense_pages_t zip_mode_sense_pages_saved[ZIP_NUM]; +static void zip_command_complete(zip_t *dev); +static void zip_init(zip_t *dev); -static void zip_command_complete(uint8_t id); - -void zip_init(int id, int cdb_len_setting); -void zip_phase_callback(uint8_t id); +void zip_phase_callback(zip_t *dev); #ifdef ENABLE_ZIP_LOG @@ -504,71 +489,57 @@ find_zip_for_channel(uint8_t channel) } -void -zip_destroy_drives(void) -{ - int i; - - for (i = 0; i < ZIP_NUM; i++) { - if (zip[i]) { - free(zip[i]); - zip[i] = NULL; - } - } -} - - int -zip_load(uint8_t id, wchar_t *fn) +zip_load(zip_t *dev, wchar_t *fn) { - int read_only = zip_drives[id].ui_writeprot; + int read_only = dev->drv->ui_writeprot; int size = 0; - zip_drives[id].f = plat_fopen(fn, zip_drives[id].ui_writeprot ? L"rb" : L"rb+"); - if (!zip_drives[id].ui_writeprot && !zip_drives[id].f) { - zip_drives[id].f = plat_fopen(fn, L"rb"); + dev->drv->f = plat_fopen(fn, dev->drv->ui_writeprot ? L"rb" : L"rb+"); + if (!dev->drv->ui_writeprot && !dev->drv->f) { + dev->drv->f = plat_fopen(fn, L"rb"); read_only = 1; } - if (zip_drives[id].f) { - fseek(zip_drives[id].f, 0, SEEK_END); - size = ftell(zip_drives[id].f); + if (dev->drv->f) { + fseek(dev->drv->f, 0, SEEK_END); + size = ftell(dev->drv->f); if ((size == ((ZIP_250_SECTORS << 9) + 0x1000)) || (size == ((ZIP_SECTORS << 9) + 0x1000))) { /* This is a ZDI image. */ size -= 0x1000; - zip_drives[id].base = 0x1000; + dev->drv->base = 0x1000; } else - zip_drives[id].base = 0; + dev->drv->base = 0; - if (zip_drives[id].is_250) { + if (dev->drv->is_250) { if ((size != (ZIP_250_SECTORS << 9)) && (size != (ZIP_SECTORS << 9))) { zip_log("File is incorrect size for a ZIP image\nMust be exactly %i or %i bytes\n", ZIP_250_SECTORS << 9, ZIP_SECTORS << 9); - fclose(zip_drives[id].f); - zip_drives[id].f = NULL; - zip_drives[id].medium_size = 0; - zip_eject(id); /* Make sure the host OS knows we've rejected (and ejected) the image. */ + fclose(dev->drv->f); + dev->drv->f = NULL; + dev->drv->medium_size = 0; + zip_eject(dev->id); /* Make sure the host OS knows we've rejected (and ejected) the image. */ return 0; } } else { if (size != (ZIP_SECTORS << 9)) { zip_log("File is incorrect size for a ZIP image\nMust be exactly %i bytes\n", ZIP_SECTORS << 9); - fclose(zip_drives[id].f); - zip_drives[id].f = NULL; - zip_drives[id].medium_size = 0; - zip_eject(id); /* Make sure the host OS knows we've rejected (and ejected) the image. */ + fclose(dev->drv->f); + dev->drv->f = NULL; + dev->drv->medium_size = 0; + zip_eject(dev->id); /* Make sure the host OS knows we've rejected (and ejected) the image. */ return 0; } } - zip_drives[id].medium_size = size >> 9; + dev->drv->medium_size = size >> 9; - fseek(zip_drives[id].f, zip_drives[id].base, SEEK_SET); + fseek(dev->drv->f, dev->drv->base, SEEK_SET); - memcpy(zip_drives[id].image_path, fn, sizeof(zip_drives[id].image_path)); + memcpy(dev->drv->image_path, fn, sizeof(dev->drv->image_path)); - zip_drives[id].read_only = read_only; + dev->drv->read_only = read_only; return 1; } @@ -578,15 +549,14 @@ zip_load(uint8_t id, wchar_t *fn) void -zip_disk_reload(uint8_t id) +zip_disk_reload(zip_t *dev) { - zip_t *dev = zip[id]; int ret = 0; - if (wcslen(zip_drives[id].prev_image_path) == 0) + if (wcslen(dev->drv->prev_image_path) == 0) return; else - ret = zip_load(id, zip_drives[id].prev_image_path); + ret = zip_load(dev, dev->drv->prev_image_path); if (ret) dev->unit_attention = 1; @@ -594,16 +564,16 @@ zip_disk_reload(uint8_t id) void -zip_close(uint8_t id) +zip_disk_close(zip_t *dev) { - if (zip_drives[id].f) { - fclose(zip_drives[id].f); - zip_drives[id].f = NULL; + if (dev->drv->f) { + fclose(dev->drv->f); + dev->drv->f = NULL; - memcpy(zip_drives[id].prev_image_path, zip_drives[id].image_path, sizeof(zip_drives[id].prev_image_path)); - memset(zip_drives[id].image_path, 0, sizeof(zip_drives[id].image_path)); + memcpy(dev->drv->prev_image_path, dev->drv->image_path, sizeof(dev->drv->prev_image_path)); + memset(dev->drv->image_path, 0, sizeof(dev->drv->image_path)); - zip_drives[id].medium_size = 0; + dev->drv->medium_size = 0; } } @@ -615,21 +585,18 @@ build_atapi_zip_map() memset(atapi_zip_drives, 0xff, 8); - for (i = 0; i < 8; i++) { + for (i = 0; i < 8; i++) atapi_zip_drives[i] = find_zip_for_channel(i); - if (atapi_zip_drives[i] != 0xff) - zip_init(atapi_zip_drives[i], 12); - } } int -find_zip_for_scsi_id(uint8_t scsi_id, uint8_t scsi_lun) +find_zip_for_scsi_id(uint8_t scsi_id) { uint8_t i = 0; for (i = 0; i < ZIP_NUM; i++) { - if ((zip_drives[i].bus_type == ZIP_BUS_SCSI) && (zip_drives[i].scsi_device_id == scsi_id) && (zip_drives[i].scsi_device_lun == scsi_lun)) + if ((zip_drives[i].bus_type == ZIP_BUS_SCSI) && (zip_drives[i].scsi_device_id == scsi_id)) return i; } return 0xff; @@ -640,114 +607,84 @@ void build_scsi_zip_map() { uint8_t i = 0; - uint8_t j = 0; + + memset(scsi_zip_drives, 0xff, 16); for (i = 0; i < 16; i++) - memset(scsi_zip_drives[i], 0xff, 8); - - for (i = 0; i < 16; i++) { - for (j = 0; j < 8; j++) { - scsi_zip_drives[i][j] = find_zip_for_scsi_id(i, j); - if (scsi_zip_drives[i][j] != 0xff) - zip_init(scsi_zip_drives[i][j], 12); - } - } + scsi_zip_drives[i] = find_zip_for_scsi_id(i); } static void -zip_set_callback(uint8_t id) +zip_set_callback(zip_t *dev) { - zip_t *dev = zip[id]; - - if (zip_drives[id].bus_type != ZIP_BUS_SCSI) - ide_set_callback(zip_drives[id].ide_channel >> 1, dev->callback); -} - - -static void -zip_reset_cdb_len(int id) -{ - zip_t *dev = zip[id]; - - dev->cdb_len = dev->cdb_len_setting ? 16 : 12; + if (dev->drv->bus_type != ZIP_BUS_SCSI) + ide_set_callback(dev->drv->ide_channel >> 1, dev->callback); } void -zip_set_signature(int id) +zip_set_signature(zip_t *dev) { - zip_t *dev = zip[id]; - - if (id >= ZIP_NUM) + if (dev->id >= ZIP_NUM) return; dev->phase = 1; dev->request_length = 0xEB14; } -void -zip_init(int id, int cdb_len_setting) +static void +zip_init(zip_t *dev) { - zip_t *dev = zip[id]; - - if (id >= ZIP_NUM) + if (dev->id >= ZIP_NUM) return; - memset(dev, 0, sizeof(zip_t)); dev->requested_blocks = 1; - if (cdb_len_setting <= 1) - dev->cdb_len_setting = cdb_len_setting; - zip_reset_cdb_len(id); dev->sense[0] = 0xf0; dev->sense[7] = 10; - zip_drives[id].bus_mode = 0; - if (zip_drives[id].bus_type >= ZIP_BUS_ATAPI) - zip_drives[id].bus_mode |= 2; - if (zip_drives[id].bus_type < ZIP_BUS_SCSI) - zip_drives[id].bus_mode |= 1; - zip_log("ZIP %i: Bus type %i, bus mode %i\n", id, zip_drives[id].bus_type, zip_drives[id].bus_mode); - if (zip_drives[id].bus_type < ZIP_BUS_SCSI) - zip_set_signature(id); + dev->drv->bus_mode = 0; + if (dev->drv->bus_type >= ZIP_BUS_ATAPI) + dev->drv->bus_mode |= 2; + if (dev->drv->bus_type < ZIP_BUS_SCSI) + dev->drv->bus_mode |= 1; + zip_log("ZIP %i: Bus type %i, bus mode %i\n", dev->id, dev->drv->bus_type, dev->drv->bus_mode); + if (dev->drv->bus_type < ZIP_BUS_SCSI) + zip_set_signature(dev); dev->status = READY_STAT | DSC_STAT; dev->pos = 0; dev->packet_status = 0xff; zip_sense_key = zip_asc = zip_ascq = dev->unit_attention = 0; - dev->cdb_len_setting = 0; - dev->cdb_len = 12; } static int -zip_supports_pio(int id) +zip_supports_pio(zip_t *dev) { - return (zip_drives[id].bus_mode & 1); + return (dev->drv->bus_mode & 1); } static int -zip_supports_dma(int id) +zip_supports_dma(zip_t *dev) { - return (zip_drives[id].bus_mode & 2); + return (dev->drv->bus_mode & 2); } /* Returns: 0 for none, 1 for PIO, 2 for DMA. */ static int -zip_current_mode(int id) +zip_current_mode(zip_t *dev) { - zip_t *dev = zip[id]; - - if (!zip_supports_pio(id) && !zip_supports_dma(id)) + if (!zip_supports_pio(dev) && !zip_supports_dma(dev)) return 0; - if (zip_supports_pio(id) && !zip_supports_dma(id)) { - zip_log("ZIP %i: Drive does not support DMA, setting to PIO\n", id); + if (zip_supports_pio(dev) && !zip_supports_dma(dev)) { + zip_log("ZIP %i: Drive does not support DMA, setting to PIO\n", dev->id); return 1; } - if (!zip_supports_pio(id) && zip_supports_dma(id)) + if (!zip_supports_pio(dev) && zip_supports_dma(dev)) return 2; - if (zip_supports_pio(id) && zip_supports_dma(id)) { - zip_log("ZIP %i: Drive supports both, setting to %s\n", id, (dev->features & 1) ? "DMA" : "PIO", id); + if (zip_supports_pio(dev) && zip_supports_dma(dev)) { + zip_log("ZIP %i: Drive supports both, setting to %s\n", dev->id, (dev->features & 1) ? "DMA" : "PIO"); return (dev->features & 1) ? 2 : 1; } @@ -757,10 +694,8 @@ zip_current_mode(int id) /* Translates ATAPI status (ERR_STAT flag) to SCSI status. */ int -zip_ZIP_PHASE_to_scsi(uint8_t id) +zip_ZIP_PHASE_to_scsi(zip_t *dev) { - zip_t *dev = zip[id]; - if (dev->status & ERR_STAT) return SCSI_STATUS_CHECK_CONDITION; else @@ -770,10 +705,8 @@ zip_ZIP_PHASE_to_scsi(uint8_t id) /* Translates ATAPI phase (DRQ, I/O, C/D) to SCSI phase (MSG, C/D, I/O). */ int -zip_atapi_phase_to_scsi(uint8_t id) +zip_atapi_phase_to_scsi(zip_t *dev) { - zip_t *dev = zip[id]; - if (dev->status & 8) { switch (dev->phase & 3) { case 0: @@ -797,35 +730,45 @@ zip_atapi_phase_to_scsi(uint8_t id) static void -zip_mode_sense_load(uint8_t id) +zip_mode_sense_load(zip_t *dev) { FILE *f; wchar_t file_name[512]; int i; - memset(&zip_mode_sense_pages_saved[id], 0, sizeof(mode_sense_pages_t)); + memset(&dev->ms_pages_saved, 0, sizeof(mode_sense_pages_t)); for (i = 0; i < 0x3f; i++) { - if (zip_drives[id].is_250) { + if (dev->drv->is_250) { if (zip_250_mode_sense_pages_default.pages[i][1] != 0) { - if (zip_drives[id].bus_type == ZIP_BUS_SCSI) - memcpy(zip_mode_sense_pages_saved[id].pages[i], zip_250_mode_sense_pages_default_scsi.pages[i], zip_250_mode_sense_pages_default_scsi.pages[i][1] + 2); - else - memcpy(zip_mode_sense_pages_saved[id].pages[i], zip_250_mode_sense_pages_default.pages[i], zip_250_mode_sense_pages_default.pages[i][1] + 2); + if (zip_drives[dev->id].bus_type == ZIP_BUS_SCSI) { + memcpy(dev->ms_pages_saved.pages[i], + zip_250_mode_sense_pages_default_scsi.pages[i], + zip_250_mode_sense_pages_default_scsi.pages[i][1] + 2); + } else { + memcpy(dev->ms_pages_saved.pages[i], + zip_250_mode_sense_pages_default.pages[i], + zip_250_mode_sense_pages_default.pages[i][1] + 2); + } } } else { if (zip_mode_sense_pages_default.pages[i][1] != 0) { - if (zip_drives[id].bus_type == ZIP_BUS_SCSI) - memcpy(zip_mode_sense_pages_saved[id].pages[i], zip_mode_sense_pages_default_scsi.pages[i], zip_mode_sense_pages_default_scsi.pages[i][1] + 2); - else - memcpy(zip_mode_sense_pages_saved[id].pages[i], zip_mode_sense_pages_default.pages[i], zip_mode_sense_pages_default.pages[i][1] + 2); + if (dev->drv->bus_type == ZIP_BUS_SCSI) { + memcpy(dev->ms_pages_saved.pages[i], + zip_mode_sense_pages_default_scsi.pages[i], + zip_mode_sense_pages_default_scsi.pages[i][1] + 2); + } else { + memcpy(dev->ms_pages_saved.pages[i], + zip_mode_sense_pages_default.pages[i], + zip_mode_sense_pages_default.pages[i][1] + 2); + } } } } memset(file_name, 0, 512 * sizeof(wchar_t)); - if (zip_drives[id].bus_type == ZIP_BUS_SCSI) - swprintf(file_name, 512, L"scsi_zip_%02i_mode_sense_bin", id); + if (dev->drv->bus_type == ZIP_BUS_SCSI) + swprintf(file_name, 512, L"scsi_zip_%02i_mode_sense_bin", dev->id); else - swprintf(file_name, 512, L"zip_%02i_mode_sense_bin", id); + swprintf(file_name, 512, L"zip_%02i_mode_sense_bin", dev->id); f = plat_fopen(nvr_path(file_name), L"rb"); if (f) fclose(f); @@ -833,16 +776,16 @@ zip_mode_sense_load(uint8_t id) static void -zip_mode_sense_save(uint8_t id) +zip_mode_sense_save(zip_t *dev) { FILE *f; wchar_t file_name[512]; memset(file_name, 0, 512 * sizeof(wchar_t)); - if (zip_drives[id].bus_type == ZIP_BUS_SCSI) - swprintf(file_name, 512, L"scsi_zip_%02i_mode_sense_bin", id); + if (dev->drv->bus_type == ZIP_BUS_SCSI) + swprintf(file_name, 512, L"scsi_zip_%02i_mode_sense_bin", dev->id); else - swprintf(file_name, 512, L"zip_%02i_mode_sense_bin", id); + swprintf(file_name, 512, L"zip_%02i_mode_sense_bin", dev->id); f = plat_fopen(nvr_path(file_name), L"wb"); if (f) fclose(f); @@ -850,12 +793,12 @@ zip_mode_sense_save(uint8_t id) int -zip_read_capacity(uint8_t id, uint8_t *cdb, uint8_t *buffer, uint32_t *len) +zip_read_capacity(zip_t *dev, uint8_t *cdb, uint8_t *buffer, uint32_t *len) { int size = 0; - if (zip_drives[id].is_250) - size = zip_drives[id].medium_size - 1; /* IMPORTANT: What's returned is the last LBA block. */ + if (dev->drv->is_250) + size = dev->drv->medium_size - 1; /* IMPORTANT: What's returned is the last LBA block. */ else size = ZIP_SECTORS - 1; /* IMPORTANT: What's returned is the last LBA block. */ memset(buffer, 0, 8); @@ -872,31 +815,31 @@ zip_read_capacity(uint8_t id, uint8_t *cdb, uint8_t *buffer, uint32_t *len) /*SCSI Mode Sense 6/10*/ static uint8_t -zip_mode_sense_read(uint8_t id, uint8_t page_control, uint8_t page, uint8_t pos) +zip_mode_sense_read(zip_t *dev, uint8_t page_control, uint8_t page, uint8_t pos) { switch (page_control) { case 0: case 3: - if (zip_drives[id].is_250 && (page == 5) && (pos == 9) && (zip_drives[id].medium_size == ZIP_SECTORS)) + if (dev->drv->is_250 && (page == 5) && (pos == 9) && (dev->drv->medium_size == ZIP_SECTORS)) return 0x60; - return zip_mode_sense_pages_saved[id].pages[page][pos]; + return dev->ms_pages_saved.pages[page][pos]; break; case 1: - if (zip_drives[id].is_250) + if (dev->drv->is_250) return zip_250_mode_sense_pages_changeable.pages[page][pos]; else return zip_mode_sense_pages_changeable.pages[page][pos]; break; case 2: - if (zip_drives[id].is_250) { - if ((page == 5) && (pos == 9) && (zip_drives[id].medium_size == ZIP_SECTORS)) + if (dev->drv->is_250) { + if ((page == 5) && (pos == 9) && (dev->drv->medium_size == ZIP_SECTORS)) return 0x60; - if (zip_drives[id].bus_type == ZIP_BUS_SCSI) + if (dev->drv->bus_type == ZIP_BUS_SCSI) return zip_250_mode_sense_pages_default_scsi.pages[page][pos]; else return zip_250_mode_sense_pages_default.pages[page][pos]; } else { - if (zip_drives[id].bus_type == ZIP_BUS_SCSI) + if (dev->drv->bus_type == ZIP_BUS_SCSI) return zip_mode_sense_pages_default_scsi.pages[page][pos]; else return zip_mode_sense_pages_default.pages[page][pos]; @@ -909,14 +852,12 @@ zip_mode_sense_read(uint8_t id, uint8_t page_control, uint8_t page, uint8_t pos) static uint32_t -zip_mode_sense(uint8_t id, uint8_t *buf, uint32_t pos, uint8_t type, uint8_t block_descriptor_len) +zip_mode_sense(zip_t *dev, uint8_t *buf, uint32_t pos, uint8_t type, uint8_t block_descriptor_len) { - zip_t *dev = zip[id]; - uint64_t page_flags; uint8_t page_control = (type >> 6) & 3; - if (zip_drives[id].is_250) + if (dev->drv->is_250) page_flags = zip_250_mode_sense_page_flags; else page_flags = zip_mode_sense_page_flags; @@ -929,11 +870,11 @@ zip_mode_sense(uint8_t id, uint8_t *buf, uint32_t pos, uint8_t type, uint8_t blo type &= 0x3f; if (block_descriptor_len) { - if (zip_drives[id].is_250) { - buf[pos++] = ((zip_drives[id].medium_size >> 24) & 0xff); - buf[pos++] = ((zip_drives[id].medium_size >> 16) & 0xff); - buf[pos++] = ((zip_drives[id].medium_size >> 8) & 0xff); - buf[pos++] = ( zip_drives[id].medium_size & 0xff); + if (dev->drv->is_250) { + buf[pos++] = ((dev->drv->medium_size >> 24) & 0xff); + buf[pos++] = ((dev->drv->medium_size >> 16) & 0xff); + buf[pos++] = ((dev->drv->medium_size >> 8) & 0xff); + buf[pos++] = ( dev->drv->medium_size & 0xff); } else { buf[pos++] = ((ZIP_SECTORS >> 24) & 0xff); buf[pos++] = ((ZIP_SECTORS >> 16) & 0xff); @@ -949,12 +890,12 @@ zip_mode_sense(uint8_t id, uint8_t *buf, uint32_t pos, uint8_t type, uint8_t blo for (i = 0; i < 0x40; i++) { if ((type == GPMODE_ALL_PAGES) || (type == i)) { if (page_flags & (1LL << dev->current_page_code)) { - buf[pos++] = zip_mode_sense_read(id, page_control, i, 0); - msplen = zip_mode_sense_read(id, page_control, i, 1); + buf[pos++] = zip_mode_sense_read(dev, page_control, i, 0); + msplen = zip_mode_sense_read(dev, page_control, i, 1); buf[pos++] = msplen; - zip_log("ZIP %i: MODE SENSE: Page [%02X] length %i\n", id, i, msplen); + zip_log("ZIP %i: MODE SENSE: Page [%02X] length %i\n", dev->id, i, msplen); for (j = 0; j < msplen; j++) - buf[pos++] = zip_mode_sense_read(id, page_control, i, 2 + j); + buf[pos++] = zip_mode_sense_read(dev, page_control, i, 2 + j); } } } @@ -964,9 +905,8 @@ zip_mode_sense(uint8_t id, uint8_t *buf, uint32_t pos, uint8_t type, uint8_t blo static void -zip_update_request_length(uint8_t id, int len, int block_len) +zip_update_request_length(zip_t *dev, int len, int block_len) { - zip_t *dev = zip[id]; uint32_t bt, min_len = 0; dev->max_transfer_len = dev->request_length; @@ -1006,29 +946,27 @@ zip_update_request_length(uint8_t id, int len, int block_len) if ((len <= dev->max_transfer_len) && (len >= min_len)) dev->request_length = dev->max_transfer_len = len; + else if (len > dev->max_transfer_len) + dev->request_length = dev->max_transfer_len; return; } static void -zip_command_bus(uint8_t id) +zip_command_bus(zip_t *dev) { - zip_t *dev = zip[id]; - dev->status = BUSY_STAT; dev->phase = 1; dev->pos = 0; dev->callback = 1LL * ZIP_TIME; - zip_set_callback(id); + zip_set_callback(dev); } static void -zip_command_common(uint8_t id) +zip_command_common(zip_t *dev) { - zip_t *dev = zip[id]; - double bytes_per_second, period; double dusec; @@ -1036,14 +974,14 @@ zip_command_common(uint8_t id) dev->phase = 1; dev->pos = 0; if (dev->packet_status == ZIP_PHASE_COMPLETE) { - zip_phase_callback(id); + zip_phase_callback(dev); dev->callback = 0LL; } else { - if (zip_drives[id].bus_type == ZIP_BUS_SCSI) { + if (dev->drv->bus_type == ZIP_BUS_SCSI) { dev->callback = -1LL; /* Speed depends on SCSI controller */ return; } else { - if (zip_current_mode(id) == 2) + if (zip_current_mode(dev) == 2) bytes_per_second = 66666666.666666666666666; /* 66 MB/s MDMA-2 speed */ else bytes_per_second = 8333333.333333333333333; /* 8.3 MB/s PIO-2 speed */ @@ -1055,58 +993,49 @@ zip_command_common(uint8_t id) dev->callback = ((int64_t) dusec); } - zip_set_callback(id); + zip_set_callback(dev); } static void -zip_command_complete(uint8_t id) +zip_command_complete(zip_t *dev) { - zip_t *dev = zip[id]; - dev->packet_status = ZIP_PHASE_COMPLETE; - zip_command_common(id); + zip_command_common(dev); } static void -zip_command_read(uint8_t id) +zip_command_read(zip_t *dev) { - zip_t *dev = zip[id]; - dev->packet_status = ZIP_PHASE_DATA_IN; - zip_command_common(id); + zip_command_common(dev); dev->total_read = 0; } static void -zip_command_read_dma(uint8_t id) +zip_command_read_dma(zip_t *dev) { - zip_t *dev = zip[id]; - dev->packet_status = ZIP_PHASE_DATA_IN_DMA; - zip_command_common(id); + zip_command_common(dev); dev->total_read = 0; } -static void -zip_command_write(uint8_t id) -{ - zip_t *dev = zip[id]; +static void +zip_command_write(zip_t *dev) +{ dev->packet_status = ZIP_PHASE_DATA_OUT; - zip_command_common(id); + zip_command_common(dev); } static void -zip_command_write_dma(uint8_t id) +zip_command_write_dma(zip_t *dev) { - zip_t *dev = zip[id]; - dev->packet_status = ZIP_PHASE_DATA_OUT_DMA; - zip_command_common(id); + zip_command_common(dev); } @@ -1116,73 +1045,67 @@ zip_command_write_dma(uint8_t id) alloc_len = Allocated transfer length; direction = Transfer direction (0 = read from host, 1 = write to host). */ static void -zip_data_command_finish(uint8_t id, int len, int block_len, int alloc_len, int direction) +zip_data_command_finish(zip_t *dev, int len, int block_len, int alloc_len, int direction) { - zip_t *dev = zip[id]; - - zip_log("ZIP %i: Finishing command (%02X): %i, %i, %i, %i, %i\n", id, dev->current_cdb[0], len, block_len, alloc_len, direction, dev->request_length); - dev->pos=0; + zip_log("ZIP %i: Finishing command (%02X): %i, %i, %i, %i, %i\n", + dev->id, dev->current_cdb[0], len, block_len, alloc_len, direction, dev->request_length); + dev->pos = 0; if (alloc_len >= 0) { if (alloc_len < len) len = alloc_len; } - if ((len == 0) || (zip_current_mode(id) == 0)) { - if (zip_drives[id].bus_type != ZIP_BUS_SCSI) + if ((len == 0) || (zip_current_mode(dev) == 0)) { + if (dev->drv->bus_type != ZIP_BUS_SCSI) dev->packet_len = 0; - zip_command_complete(id); + zip_command_complete(dev); } else { - if (zip_current_mode(id) == 2) { - if (zip_drives[id].bus_type != ZIP_BUS_SCSI) + if (zip_current_mode(dev) == 2) { + if (dev->drv->bus_type != ZIP_BUS_SCSI) dev->packet_len = alloc_len; if (direction == 0) - zip_command_read_dma(id); + zip_command_read_dma(dev); else - zip_command_write_dma(id); + zip_command_write_dma(dev); } else { - zip_update_request_length(id, len, block_len); + zip_update_request_length(dev, len, block_len); if (direction == 0) - zip_command_read(id); + zip_command_read(dev); else - zip_command_write(id); + zip_command_write(dev); } } zip_log("ZIP %i: Status: %i, cylinder %i, packet length: %i, position: %i, phase: %i\n", - id, dev->packet_status, dev->request_length, dev->packet_len, dev->pos, dev->phase); + dev->id, dev->packet_status, dev->request_length, dev->packet_len, dev->pos, dev->phase); } static void -zip_sense_clear(int id, int command) +zip_sense_clear(zip_t *dev, int command) { - zip_t *dev = zip[id]; - dev->previous_command = command; zip_sense_key = zip_asc = zip_ascq = 0; } static void -zip_set_phase(uint8_t id, uint8_t phase) +zip_set_phase(zip_t *dev, uint8_t phase) { - uint8_t scsi_id = zip_drives[id].scsi_device_id; - uint8_t scsi_lun = zip_drives[id].scsi_device_lun; + uint8_t scsi_id = dev->drv->scsi_device_id; - if (zip_drives[id].bus_type != ZIP_BUS_SCSI) + if (dev->drv->bus_type != ZIP_BUS_SCSI) return; - SCSIDevices[scsi_id][scsi_lun].Phase = phase; + SCSIDevices[scsi_id].Phase = phase; } static void -zip_cmd_error(uint8_t id) +zip_cmd_error(zip_t *dev) { - zip_t *dev = zip[id]; - - zip_set_phase(id, SCSI_PHASE_STATUS); + zip_set_phase(dev, SCSI_PHASE_STATUS); dev->error = ((zip_sense_key & 0xf) << 4) | ABRT_ERR; if (dev->unit_attention) dev->error |= MCR_ERR; @@ -1191,17 +1114,15 @@ zip_cmd_error(uint8_t id) dev->pos = 0; dev->packet_status = 0x80; dev->callback = 50LL * ZIP_TIME; - zip_set_callback(id); - zip_log("ZIP %i: [%02X] ERROR: %02X/%02X/%02X\n", id, dev->current_cdb[0], zip_sense_key, zip_asc, zip_ascq); + zip_set_callback(dev); + zip_log("ZIP %i: [%02X] ERROR: %02X/%02X/%02X\n", dev->id, dev->current_cdb[0], zip_sense_key, zip_asc, zip_ascq); } static void -zip_unit_attention(uint8_t id) +zip_unit_attention(zip_t *dev) { - zip_t *dev = zip[id]; - - zip_set_phase(id, SCSI_PHASE_STATUS); + zip_set_phase(dev, SCSI_PHASE_STATUS); dev->error = (SENSE_UNIT_ATTENTION << 4) | ABRT_ERR; if (dev->unit_attention) dev->error |= MCR_ERR; @@ -1210,134 +1131,128 @@ zip_unit_attention(uint8_t id) dev->pos = 0; dev->packet_status = 0x80; dev->callback = 50LL * ZIP_TIME; - zip_set_callback(id); - zip_log("ZIP %i: UNIT ATTENTION\n", id); + zip_set_callback(dev); + zip_log("ZIP %i: UNIT ATTENTION\n", dev->id); } static void -zip_bus_master_error(uint8_t id) +zip_bus_master_error(zip_t *dev) { zip_sense_key = zip_asc = zip_ascq = 0; - zip_cmd_error(id); + zip_cmd_error(dev); } static void -zip_not_ready(uint8_t id) +zip_not_ready(zip_t *dev) { zip_sense_key = SENSE_NOT_READY; zip_asc = ASC_MEDIUM_NOT_PRESENT; zip_ascq = 0; - zip_cmd_error(id); + zip_cmd_error(dev); } static void -zip_write_protected(uint8_t id) +zip_write_protected(zip_t *dev) { zip_sense_key = SENSE_UNIT_ATTENTION; zip_asc = ASC_WRITE_PROTECTED; zip_ascq = 0; - zip_cmd_error(id); + zip_cmd_error(dev); } static void -zip_invalid_lun(uint8_t id) +zip_invalid_lun(zip_t *dev) { zip_sense_key = SENSE_ILLEGAL_REQUEST; zip_asc = ASC_INV_LUN; zip_ascq = 0; - zip_cmd_error(id); + zip_cmd_error(dev); } static void -zip_illegal_opcode(uint8_t id) +zip_illegal_opcode(zip_t *dev) { zip_sense_key = SENSE_ILLEGAL_REQUEST; zip_asc = ASC_ILLEGAL_OPCODE; zip_ascq = 0; - zip_cmd_error(id); + zip_cmd_error(dev); } static void -zip_lba_out_of_range(uint8_t id) +zip_lba_out_of_range(zip_t *dev) { zip_sense_key = SENSE_ILLEGAL_REQUEST; zip_asc = ASC_LBA_OUT_OF_RANGE; zip_ascq = 0; - zip_cmd_error(id); + zip_cmd_error(dev); } static void -zip_invalid_field(uint8_t id) +zip_invalid_field(zip_t *dev) { - zip_t *dev = zip[id]; - zip_sense_key = SENSE_ILLEGAL_REQUEST; zip_asc = ASC_INV_FIELD_IN_CMD_PACKET; zip_ascq = 0; - zip_cmd_error(id); + zip_cmd_error(dev); dev->status = 0x53; } static void -zip_invalid_field_pl(uint8_t id) +zip_invalid_field_pl(zip_t *dev) { - zip_t *dev = zip[id]; - zip_sense_key = SENSE_ILLEGAL_REQUEST; zip_asc = ASC_INV_FIELD_IN_PARAMETER_LIST; zip_ascq = 0; - zip_cmd_error(id); + zip_cmd_error(dev); dev->status = 0x53; } static void -zip_data_phase_error(uint8_t id) +zip_data_phase_error(zip_t *dev) { zip_sense_key = SENSE_ILLEGAL_REQUEST; zip_asc = ASC_DATA_PHASE_ERROR; zip_ascq = 0; - zip_cmd_error(id); + zip_cmd_error(dev); } static int -zip_blocks(uint8_t id, uint32_t *len, int first_batch, int out) +zip_blocks(zip_t *dev, uint32_t *len, int first_batch, int out) { - zip_t *dev = zip[id]; - dev->data_pos = 0; *len = 0; if (!dev->sector_len) { - zip_command_complete(id); + zip_command_complete(dev); return -1; } zip_log("%sing %i blocks starting from %i...\n", out ? "Writ" : "Read", dev->requested_blocks, dev->sector_pos); - if (dev->sector_pos >= zip_drives[id].medium_size) { - zip_log("ZIP %i: Trying to %s beyond the end of disk\n", id, out ? "write" : "read"); - zip_lba_out_of_range(id); + if (dev->sector_pos >= dev->drv->medium_size) { + zip_log("ZIP %i: Trying to %s beyond the end of disk\n", dev->id, out ? "write" : "read"); + zip_lba_out_of_range(dev); return 0; } *len = dev->requested_blocks << 9; - fseek(zip_drives[id].f, zip_drives[id].base + (dev->sector_pos << 9), SEEK_SET); + fseek(dev->drv->f, dev->drv->base + (dev->sector_pos << 9), SEEK_SET); if (out) - fwrite(zipbufferb, 1, *len, zip_drives[id].f); + fwrite(zipbufferb, 1, *len, dev->drv->f); else - fread(zipbufferb, 1, *len, zip_drives[id].f); + fread(zipbufferb, 1, *len, dev->drv->f); zip_log("%s %i bytes of blocks...\n", out ? "Written" : "Read", *len); @@ -1349,17 +1264,15 @@ zip_blocks(uint8_t id, uint32_t *len, int first_batch, int out) void -zip_insert(uint8_t id) +zip_insert(zip_t *dev) { - zip_t *dev = zip[id]; - dev->unit_attention = 1; } /*SCSI Sense Initialization*/ void -zip_sense_code_ok(uint8_t id) +zip_sense_code_ok(zip_t *dev) { zip_sense_key = SENSE_NONE; zip_asc = 0; @@ -1368,40 +1281,39 @@ zip_sense_code_ok(uint8_t id) static int -zip_pre_execution_check(uint8_t id, uint8_t *cdb) +zip_pre_execution_check(zip_t *dev, uint8_t *cdb) { - zip_t *dev = zip[id]; int ready = 0; - if (zip_drives[id].bus_type == ZIP_BUS_SCSI) { - if (((dev->request_length >> 5) & 7) != zip_drives[id].scsi_device_lun) { - zip_log("ZIP %i: Attempting to execute a unknown command targeted at SCSI LUN %i\n", id, ((dev->request_length >> 5) & 7)); - zip_invalid_lun(id); + if (dev->drv->bus_type == ZIP_BUS_SCSI) { + if ((cdb[0] != GPCMD_REQUEST_SENSE) && (cdb[1] & 0xe0)) { + zip_log("ZIP %i: Attempting to execute a unknown command targeted at SCSI LUN %i\n", dev->id, ((dev->request_length >> 5) & 7)); + zip_invalid_lun(dev); return 0; } } if (!(zip_command_flags[cdb[0]] & IMPLEMENTED)) { - zip_log("ZIP %i: Attempting to execute unknown command %02X over %s\n", id, cdb[0], - (zip_drives[id].bus_type == ZIP_BUS_SCSI) ? "SCSI" : "ATAPI"); + zip_log("ZIP %i: Attempting to execute unknown command %02X over %s\n", dev->id, cdb[0], + (dev->drv->bus_type == ZIP_BUS_SCSI) ? "SCSI" : "ATAPI"); - zip_illegal_opcode(id); + zip_illegal_opcode(dev); return 0; } - if ((zip_drives[id].bus_type < ZIP_BUS_SCSI) && (zip_command_flags[cdb[0]] & SCSI_ONLY)) { - zip_log("ZIP %i: Attempting to execute SCSI-only command %02X over ATAPI\n", id, cdb[0]); - zip_illegal_opcode(id); + if ((dev->drv->bus_type < ZIP_BUS_SCSI) && (zip_command_flags[cdb[0]] & SCSI_ONLY)) { + zip_log("ZIP %i: Attempting to execute SCSI-only command %02X over ATAPI\n", dev->id, cdb[0]); + zip_illegal_opcode(dev); return 0; } - if ((zip_drives[id].bus_type == ZIP_BUS_SCSI) && (zip_command_flags[cdb[0]] & ATAPI_ONLY)) { - zip_log("ZIP %i: Attempting to execute ATAPI-only command %02X over SCSI\n", id, cdb[0]); - zip_illegal_opcode(id); + if ((dev->drv->bus_type == ZIP_BUS_SCSI) && (zip_command_flags[cdb[0]] & ATAPI_ONLY)) { + zip_log("ZIP %i: Attempting to execute ATAPI-only command %02X over SCSI\n", dev->id, cdb[0]); + zip_illegal_opcode(dev); return 0; } - ready = (zip_drives[id].f != NULL); + ready = (dev->drv->f != NULL); /* If the drive is not ready, there is no reason to keep the UNIT ATTENTION condition present, as we only use it to mark @@ -1414,15 +1326,15 @@ zip_pre_execution_check(uint8_t id, uint8_t *cdb) if (dev->unit_attention == 1) { /* Only increment the unit attention phase if the command can not pass through it. */ if (!(zip_command_flags[cdb[0]] & ALLOW_UA)) { - /* zip_log("ZIP %i: Unit attention now 2\n", id); */ + /* zip_log("ZIP %i: Unit attention now 2\n", dev->id); */ dev->unit_attention = 2; - zip_log("ZIP %i: UNIT ATTENTION: Command %02X not allowed to pass through\n", id, cdb[0]); - zip_unit_attention(id); + zip_log("ZIP %i: UNIT ATTENTION: Command %02X not allowed to pass through\n", dev->id, cdb[0]); + zip_unit_attention(dev); return 0; } } else if (dev->unit_attention == 2) { if (cdb[0] != GPCMD_REQUEST_SENSE) { - /* zip_log("ZIP %i: Unit attention now 0\n", id); */ + /* zip_log("ZIP %i: Unit attention now 0\n", dev->id); */ dev->unit_attention = 0; } } @@ -1430,7 +1342,7 @@ zip_pre_execution_check(uint8_t id, uint8_t *cdb) /* Unless the command is REQUEST SENSE, clear the sense. This will *NOT* the UNIT ATTENTION condition if it's set. */ if (cdb[0] != GPCMD_REQUEST_SENSE) - zip_sense_clear(id, cdb[0]); + zip_sense_clear(dev, cdb[0]); /* Next it's time for NOT READY. */ if (!ready) @@ -1439,56 +1351,48 @@ zip_pre_execution_check(uint8_t id, uint8_t *cdb) dev->media_status = (dev->unit_attention) ? MEC_NEW_MEDIA : MEC_NO_CHANGE; if ((zip_command_flags[cdb[0]] & CHECK_READY) && !ready) { - zip_log("ZIP %i: Not ready (%02X)\n", id, cdb[0]); - zip_not_ready(id); + zip_log("ZIP %i: Not ready (%02X)\n", dev->id, cdb[0]); + zip_not_ready(dev); return 0; } - zip_log("ZIP %i: Continuing with command %02X\n", id, cdb[0]); + zip_log("ZIP %i: Continuing with command %02X\n", dev->id, cdb[0]); return 1; } static void -zip_seek(uint8_t id, uint32_t pos) +zip_seek(zip_t *dev, uint32_t pos) { - zip_t *dev = zip[id]; - - /* zip_log("ZIP %i: Seek %08X\n", id, pos); */ + /* zip_log("ZIP %i: Seek %08X\n", dev->id, pos); */ dev->sector_pos = pos; } static void -zip_rezero(uint8_t id) +zip_rezero(zip_t *dev) { - zip_t *dev = zip[id]; - dev->sector_pos = dev->sector_len = 0; - zip_seek(id, 0); + zip_seek(dev, 0); } void -zip_reset(uint8_t id) +zip_reset(zip_t *dev) { - zip_t *dev = zip[id]; - - zip_rezero(id); + zip_rezero(dev); dev->status = 0; dev->callback = 0LL; - zip_set_callback(id); + zip_set_callback(dev); dev->packet_status = 0xff; dev->unit_attention = 0; } static void -zip_request_sense(uint8_t id, uint8_t *buffer, uint8_t alloc_length, int desc) +zip_request_sense(zip_t *dev, uint8_t *buffer, uint8_t alloc_length, int desc) { - zip_t *dev = zip[id]; - /*Will return 18 bytes of 0*/ if (alloc_length != 0) { memset(buffer, 0, alloc_length); @@ -1504,12 +1408,12 @@ zip_request_sense(uint8_t id, uint8_t *buffer, uint8_t alloc_length, int desc) buffer[0] = desc ? 0x72 : 0x70; if (dev->unit_attention && (zip_sense_key == 0)) { - buffer[desc ? 1 : 2]=SENSE_UNIT_ATTENTION; - buffer[desc ? 2 : 12]=ASC_MEDIUM_MAY_HAVE_CHANGED; - buffer[desc ? 3 : 13]=0; + buffer[desc ? 1 : 2] = SENSE_UNIT_ATTENTION; + buffer[desc ? 2 : 12] = ASC_MEDIUM_MAY_HAVE_CHANGED; + buffer[desc ? 3 : 13] = 0; } - zip_log("ZIP %i: Reporting sense: %02X %02X %02X\n", id, buffer[2], buffer[12], buffer[13]); + zip_log("ZIP %i: Reporting sense: %02X %02X %02X\n", dev->id, buffer[2], buffer[12], buffer[13]); if (buffer[desc ? 1 : 2] == SENSE_UNIT_ATTENTION) { /* If the last remaining sense is unit attention, clear @@ -1518,17 +1422,16 @@ zip_request_sense(uint8_t id, uint8_t *buffer, uint8_t alloc_length, int desc) } /* Clear the sense stuff as per the spec. */ - zip_sense_clear(id, GPCMD_REQUEST_SENSE); + zip_sense_clear(dev, GPCMD_REQUEST_SENSE); } void -zip_request_sense_for_scsi(uint8_t id, uint8_t *buffer, uint8_t alloc_length) +zip_request_sense_for_scsi(zip_t *dev, uint8_t *buffer, uint8_t alloc_length) { - zip_t *dev = zip[id]; int ready = 0; - ready = (zip_drives[id].f != NULL); + ready = (dev->drv->f != NULL); if (!ready && dev->unit_attention) { /* If the drive is not ready, there is no reason to keep the @@ -1539,42 +1442,38 @@ zip_request_sense_for_scsi(uint8_t id, uint8_t *buffer, uint8_t alloc_length) /* Do *NOT* advance the unit attention phase. */ - zip_request_sense(id, buffer, alloc_length, 0); + zip_request_sense(dev, buffer, alloc_length, 0); } static void -zip_set_buf_len(uint8_t id, int32_t *BufLen, uint32_t *src_len) +zip_set_buf_len(zip_t *dev, int32_t *BufLen, uint32_t *src_len) { - if (zip_drives[id].bus_type == ZIP_BUS_SCSI) { + if (dev->drv->bus_type == ZIP_BUS_SCSI) { if (*BufLen == -1) *BufLen = *src_len; else { *BufLen = MIN(*src_len, *BufLen); *src_len = *BufLen; } - zip_log("ZIP %i: Actual transfer length: %i\n", id, *BufLen); + zip_log("ZIP %i: Actual transfer length: %i\n", dev->id, *BufLen); } } static void -zip_buf_alloc(uint8_t id, uint32_t len) +zip_buf_alloc(zip_t *dev, uint32_t len) { - zip_t *dev = zip[id]; - - zip_log("ZIP %i: Allocated buffer length: %i\n", id, len); + zip_log("ZIP %i: Allocated buffer length: %i\n", dev->id, len); zipbufferb = (uint8_t *) malloc(len); } static void -zip_buf_free(uint8_t id) +zip_buf_free(zip_t *dev) { - zip_t *dev = zip[id]; - if (zipbufferb) { - zip_log("ZIP %i: Freeing buffer...\n", id); + zip_log("ZIP %i: Freeing buffer...\n", dev->id); free(zipbufferb); zipbufferb = NULL; } @@ -1582,7 +1481,7 @@ zip_buf_free(uint8_t id) void -zip_command(uint8_t id, uint8_t *cdb) +zip_command(zip_t *dev, uint8_t *cdb) { int pos = 0, block_desc = 0; int ret; @@ -1593,10 +1492,8 @@ zip_command(uint8_t id, uint8_t *cdb) int32_t blen = 0; int32_t *BufLen; - zip_t *dev = zip[id]; - - if (zip_drives[id].bus_type == ZIP_BUS_SCSI) { - BufLen = &SCSIDevices[zip_drives[id].scsi_device_id][zip_drives[id].scsi_device_lun].BufferLength; + if (dev->drv->bus_type == ZIP_BUS_SCSI) { + BufLen = &SCSIDevices[dev->drv->scsi_device_id].BufferLength; dev->status &= ~ERR_STAT; } else { BufLen = &blen; @@ -1608,54 +1505,54 @@ zip_command(uint8_t id, uint8_t *cdb) dev->data_pos = 0; - memcpy(dev->current_cdb, cdb, dev->cdb_len); + memcpy(dev->current_cdb, cdb, 12); if (cdb[0] != 0) { - zip_log("ZIP %i: Command 0x%02X, Sense Key %02X, Asc %02X, Ascq %02X, Unit attention: %i\n", id, cdb[0], zip_sense_key, zip_asc, zip_ascq, dev->unit_attention); - zip_log("ZIP %i: Request length: %04X\n", id, dev->request_length); + zip_log("ZIP %i: Command 0x%02X, Sense Key %02X, Asc %02X, Ascq %02X, Unit attention: %i\n", + dev->id, cdb[0], zip_sense_key, zip_asc, zip_ascq, dev->unit_attention); + zip_log("ZIP %i: Request length: %04X\n", dev->id, dev->request_length); - zip_log("ZIP %i: CDB: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", id, + zip_log("ZIP %i: CDB: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", dev->id, cdb[0], cdb[1], cdb[2], cdb[3], cdb[4], cdb[5], cdb[6], cdb[7], cdb[8], cdb[9], cdb[10], cdb[11]); } dev->sector_len = 0; - zip_set_phase(id, SCSI_PHASE_STATUS); + zip_set_phase(dev, SCSI_PHASE_STATUS); /* This handles the Not Ready/Unit Attention check if it has to be handled at this point. */ - if (zip_pre_execution_check(id, cdb) == 0) + if (zip_pre_execution_check(dev, cdb) == 0) return; switch (cdb[0]) { case GPCMD_SEND_DIAGNOSTIC: if (!(cdb[1] & (1 << 2))) { - zip_invalid_field(id); + zip_invalid_field(dev); return; } case GPCMD_SCSI_RESERVE: case GPCMD_SCSI_RELEASE: case GPCMD_TEST_UNIT_READY: - zip_set_phase(id, SCSI_PHASE_STATUS); - zip_command_complete(id); + zip_set_phase(dev, SCSI_PHASE_STATUS); + zip_command_complete(dev); break; case GPCMD_FORMAT_UNIT: - if ((zip_drives[id].bus_type == ZIP_BUS_SCSI) && zip_drives[id].read_only) - { - zip_write_protected(id); + if ((dev->drv->bus_type == ZIP_BUS_SCSI) && dev->drv->read_only) { + zip_write_protected(dev); return; } - zip_set_phase(id, SCSI_PHASE_STATUS); - zip_command_complete(id); + zip_set_phase(dev, SCSI_PHASE_STATUS); + zip_command_complete(dev); break; case GPCMD_IOMEGA_SENSE: - zip_set_phase(id, SCSI_PHASE_DATA_IN); + zip_set_phase(dev, SCSI_PHASE_DATA_IN); max_len = cdb[4]; - zip_buf_alloc(id, 256); - zip_set_buf_len(id, BufLen, &max_len); + zip_buf_alloc(dev, 256); + zip_set_buf_len(dev, BufLen, &max_len); memset(zipbufferb, 0, 256); if (cdb[2] == 1) { /* This page is related to disk health status - setting @@ -1670,66 +1567,66 @@ zip_command(uint8_t id, uint8_t *cdb) for (i = 0x00; i < 0x13; i++) zipbufferb[i + 0x02] = 0x00; zipbufferb[0x15] = 0x00; - if (zip_drives[id].read_only) + if (dev->drv->read_only) zipbufferb[0x15] |= 0x02; for (i = 0x00; i < 0x27; i++) zipbufferb[i + 0x16] = 0x00; } else { - zip_invalid_field(id); - zip_buf_free(id); + zip_invalid_field(dev); + zip_buf_free(dev); return; } - zip_data_command_finish(id, 18, 18, cdb[4], 0); + zip_data_command_finish(dev, 18, 18, cdb[4], 0); break; case GPCMD_REZERO_UNIT: dev->sector_pos = dev->sector_len = 0; - zip_seek(id, 0); - zip_set_phase(id, SCSI_PHASE_STATUS); + zip_seek(dev, 0); + zip_set_phase(dev, SCSI_PHASE_STATUS); break; case GPCMD_REQUEST_SENSE: /* If there's a unit attention condition and there's a buffered not ready, a standalone REQUEST SENSE should forget about the not ready, and report unit attention straight away. */ - zip_set_phase(id, SCSI_PHASE_DATA_IN); + zip_set_phase(dev, SCSI_PHASE_DATA_IN); max_len = cdb[4]; - zip_buf_alloc(id, 256); - zip_set_buf_len(id, BufLen, &max_len); + zip_buf_alloc(dev, 256); + zip_set_buf_len(dev, BufLen, &max_len); len = (cdb[1] & 1) ? 8 : 18; - zip_request_sense(id, zipbufferb, max_len, cdb[1] & 1); - zip_data_command_finish(id, len, len, cdb[4], 0); + zip_request_sense(dev, zipbufferb, max_len, cdb[1] & 1); + zip_data_command_finish(dev, len, len, cdb[4], 0); break; case GPCMD_MECHANISM_STATUS: - zip_set_phase(id, SCSI_PHASE_DATA_IN); + zip_set_phase(dev, SCSI_PHASE_DATA_IN); len = (cdb[7] << 16) | (cdb[8] << 8) | cdb[9]; - zip_buf_alloc(id, 8); + zip_buf_alloc(dev, 8); - zip_set_buf_len(id, BufLen, &len); + zip_set_buf_len(dev, BufLen, &len); memset(zipbufferb, 0, 8); zipbufferb[5] = 1; - zip_data_command_finish(id, 8, 8, len, 0); + zip_data_command_finish(dev, 8, 8, len, 0); break; case GPCMD_READ_6: case GPCMD_READ_10: case GPCMD_READ_12: - zip_set_phase(id, SCSI_PHASE_DATA_IN); + zip_set_phase(dev, SCSI_PHASE_DATA_IN); alloc_length = 512; switch(cdb[0]) { case GPCMD_READ_6: dev->sector_len = cdb[4]; dev->sector_pos = ((((uint32_t) cdb[1]) & 0x1f) << 16) | (((uint32_t) cdb[2]) << 8) | ((uint32_t) cdb[3]); - zip_log("ZIP %i: Length: %i, LBA: %i\n", id, dev->sector_len, dev->sector_pos); + zip_log("ZIP %i: Length: %i, LBA: %i\n", dev->id, dev->sector_len, dev->sector_pos); break; case GPCMD_READ_10: dev->sector_len = (cdb[7] << 8) | cdb[8]; dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - zip_log("ZIP %i: Length: %i, LBA: %i\n", id, dev->sector_len, dev->sector_pos); + zip_log("ZIP %i: Length: %i, LBA: %i\n", dev->id, dev->sector_len, dev->sector_pos); break; case GPCMD_READ_12: dev->sector_len = (((uint32_t) cdb[6]) << 24) | (((uint32_t) cdb[7]) << 16) | (((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]); @@ -1738,11 +1635,11 @@ zip_command(uint8_t id, uint8_t *cdb) } if (!dev->sector_len) { - zip_set_phase(id, SCSI_PHASE_STATUS); - /* zip_log("ZIP %i: All done - callback set\n", id); */ + zip_set_phase(dev, SCSI_PHASE_STATUS); + /* zip_log("ZIP %i: All done - callback set\n", dev->id); */ dev->packet_status = ZIP_PHASE_COMPLETE; dev->callback = 20LL * ZIP_TIME; - zip_set_callback(id); + zip_set_callback(dev); break; } @@ -1752,34 +1649,34 @@ zip_command(uint8_t id, uint8_t *cdb) transferred to the host should be different. */ dev->packet_len = max_len * alloc_length; - zip_buf_alloc(id, dev->packet_len); + zip_buf_alloc(dev, dev->packet_len); - ret = zip_blocks(id, &alloc_length, 1, 0); + ret = zip_blocks(dev, &alloc_length, 1, 0); if (ret <= 0) { - zip_buf_free(id); + zip_buf_free(dev); return; } dev->requested_blocks = max_len; dev->packet_len = alloc_length; - zip_set_buf_len(id, BufLen, &dev->packet_len); + zip_set_buf_len(dev, BufLen, &dev->packet_len); - zip_data_command_finish(id, alloc_length, 512, alloc_length, 0); + zip_data_command_finish(dev, alloc_length, 512, alloc_length, 0); dev->all_blocks_total = dev->block_total; if (dev->packet_status != ZIP_PHASE_COMPLETE) - ui_sb_update_icon(SB_ZIP | id, 1); + ui_sb_update_icon(SB_ZIP | dev->id, 1); else - ui_sb_update_icon(SB_ZIP | id, 0); + ui_sb_update_icon(SB_ZIP | dev->id, 0); return; case GPCMD_VERIFY_6: case GPCMD_VERIFY_10: case GPCMD_VERIFY_12: if (!(cdb[1] & 2)) { - zip_set_phase(id, SCSI_PHASE_STATUS); - zip_command_complete(id); + zip_set_phase(dev, SCSI_PHASE_STATUS); + zip_command_complete(dev); break; } case GPCMD_WRITE_6: @@ -1787,11 +1684,11 @@ zip_command(uint8_t id, uint8_t *cdb) case GPCMD_WRITE_AND_VERIFY_10: case GPCMD_WRITE_12: case GPCMD_WRITE_AND_VERIFY_12: - zip_set_phase(id, SCSI_PHASE_DATA_OUT); + zip_set_phase(dev, SCSI_PHASE_DATA_OUT); alloc_length = 512; - if ((zip_drives[id].bus_type == ZIP_BUS_SCSI) && zip_drives[id].read_only) { - zip_write_protected(id); + if ((dev->drv->bus_type == ZIP_BUS_SCSI) && dev->drv->read_only) { + zip_write_protected(dev); return; } @@ -1806,7 +1703,7 @@ zip_command(uint8_t id, uint8_t *cdb) case GPCMD_WRITE_AND_VERIFY_10: dev->sector_len = (cdb[7] << 8) | cdb[8]; dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - zip_log("ZIP %i: Length: %i, LBA: %i\n", id, dev->sector_len, dev->sector_pos); + zip_log("ZIP %i: Length: %i, LBA: %i\n", dev->id, dev->sector_len, dev->sector_pos); break; case GPCMD_VERIFY_12: case GPCMD_WRITE_12: @@ -1816,26 +1713,26 @@ zip_command(uint8_t id, uint8_t *cdb) break; } - if (zip_drives[id].is_250) { - if ((dev->sector_pos >= zip_drives[id].medium_size) || - ((dev->sector_pos + dev->sector_len - 1) >= zip_drives[id].medium_size)) { - zip_lba_out_of_range(id); + if (dev->drv->is_250) { + if ((dev->sector_pos >= dev->drv->medium_size) || + ((dev->sector_pos + dev->sector_len - 1) >= dev->drv->medium_size)) { + zip_lba_out_of_range(dev); return; } } else { if ((dev->sector_pos >= ZIP_SECTORS) || ((dev->sector_pos + dev->sector_len - 1) >= ZIP_SECTORS)) { - zip_lba_out_of_range(id); + zip_lba_out_of_range(dev); return; } } if (!dev->sector_len) { - zip_set_phase(id, SCSI_PHASE_STATUS); - /* zip_log("ZIP %i: All done - callback set\n", id); */ + zip_set_phase(dev, SCSI_PHASE_STATUS); + /* zip_log("ZIP %i: All done - callback set\n", dev->id); */ dev->packet_status = ZIP_PHASE_COMPLETE; dev->callback = 20LL * ZIP_TIME; - zip_set_callback(id); + zip_set_callback(dev); break; } @@ -1845,59 +1742,59 @@ zip_command(uint8_t id, uint8_t *cdb) transferred to the host should be different. */ dev->packet_len = max_len * alloc_length; - zip_buf_alloc(id, dev->packet_len); + zip_buf_alloc(dev, dev->packet_len); dev->requested_blocks = max_len; dev->packet_len = max_len << 9; - zip_set_buf_len(id, BufLen, &dev->packet_len); + zip_set_buf_len(dev, BufLen, &dev->packet_len); - zip_data_command_finish(id, dev->packet_len, 512, dev->packet_len, 1); + zip_data_command_finish(dev, dev->packet_len, 512, dev->packet_len, 1); dev->all_blocks_total = dev->block_total; if (dev->packet_status != ZIP_PHASE_COMPLETE) - ui_sb_update_icon(SB_ZIP | id, 1); + ui_sb_update_icon(SB_ZIP | dev->id, 1); else - ui_sb_update_icon(SB_ZIP | id, 0); + ui_sb_update_icon(SB_ZIP | dev->id, 0); return; case GPCMD_WRITE_SAME_10: - zip_set_phase(id, SCSI_PHASE_DATA_OUT); + zip_set_phase(dev, SCSI_PHASE_DATA_OUT); alloc_length = 512; if ((cdb[1] & 6) == 6) { - zip_invalid_field(id); + zip_invalid_field(dev); return; } - if ((zip_drives[id].bus_type == ZIP_BUS_SCSI) && zip_drives[id].read_only) { - zip_write_protected(id); + if ((dev->drv->bus_type == ZIP_BUS_SCSI) && dev->drv->read_only) { + zip_write_protected(dev); return; } dev->sector_len = (cdb[7] << 8) | cdb[8]; dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - if (zip_drives[id].is_250) { - if ((dev->sector_pos >= zip_drives[id].medium_size) || - ((dev->sector_pos + dev->sector_len - 1) >= zip_drives[id].medium_size)) { - zip_lba_out_of_range(id); + if (dev->drv->is_250) { + if ((dev->sector_pos >= dev->drv->medium_size) || + ((dev->sector_pos + dev->sector_len - 1) >= dev->drv->medium_size)) { + zip_lba_out_of_range(dev); return; } } else { if ((dev->sector_pos >= ZIP_SECTORS) || ((dev->sector_pos + dev->sector_len - 1) >= ZIP_SECTORS)) { - zip_lba_out_of_range(id); + zip_lba_out_of_range(dev); return; } } if (!dev->sector_len) { - zip_set_phase(id, SCSI_PHASE_STATUS); - /* zip_log("ZIP %i: All done - callback set\n", id); */ + zip_set_phase(dev, SCSI_PHASE_STATUS); + /* zip_log("ZIP %i: All done - callback set\n", dev->id); */ dev->packet_status = ZIP_PHASE_COMPLETE; dev->callback = 20LL * ZIP_TIME; - zip_set_callback(id); + zip_set_callback(dev); break; } @@ -1907,45 +1804,45 @@ zip_command(uint8_t id, uint8_t *cdb) transferred to the host should be different. */ dev->packet_len = max_len * alloc_length; - zip_buf_alloc(id, dev->packet_len); + zip_buf_alloc(dev, dev->packet_len); dev->requested_blocks = max_len; dev->packet_len = alloc_length; - zip_set_buf_len(id, BufLen, &dev->packet_len); + zip_set_buf_len(dev, BufLen, &dev->packet_len); - zip_data_command_finish(id, dev->packet_len, 512, dev->packet_len, 1); + zip_data_command_finish(dev, dev->packet_len, 512, dev->packet_len, 1); dev->all_blocks_total = dev->block_total; if (dev->packet_status != ZIP_PHASE_COMPLETE) - ui_sb_update_icon(SB_ZIP | id, 1); + ui_sb_update_icon(SB_ZIP | dev->id, 1); else - ui_sb_update_icon(SB_ZIP | id, 0); + ui_sb_update_icon(SB_ZIP | dev->id, 0); return; case GPCMD_MODE_SENSE_6: case GPCMD_MODE_SENSE_10: - zip_set_phase(id, SCSI_PHASE_DATA_IN); + zip_set_phase(dev, SCSI_PHASE_DATA_IN); - if (zip_drives[id].bus_type == ZIP_BUS_SCSI) + if (dev->drv->bus_type == ZIP_BUS_SCSI) block_desc = ((cdb[1] >> 3) & 1) ? 0 : 1; else block_desc = 0; if (cdb[0] == GPCMD_MODE_SENSE_6) { len = cdb[4]; - zip_buf_alloc(id, 256); + zip_buf_alloc(dev, 256); } else { len = (cdb[8] | (cdb[7] << 8)); - zip_buf_alloc(id, 65536); + zip_buf_alloc(dev, 65536); } dev->current_page_code = cdb[2] & 0x3F; zip_log("Mode sense page: %02X\n", dev->current_page_code); if (!(zip_mode_sense_page_flags & (1LL << dev->current_page_code))) { - zip_invalid_field(id); - zip_buf_free(id); + zip_invalid_field(dev); + zip_buf_free(dev); return; } @@ -1953,14 +1850,14 @@ zip_command(uint8_t id, uint8_t *cdb) alloc_length = len; if (cdb[0] == GPCMD_MODE_SENSE_6) { - len = zip_mode_sense(id, zipbufferb, 4, cdb[2], block_desc); + len = zip_mode_sense(dev, zipbufferb, 4, cdb[2], block_desc); len = MIN(len, alloc_length); zipbufferb[0] = len - 1; zipbufferb[1] = 0; if (block_desc) zipbufferb[3] = 8; } else { - len = zip_mode_sense(id, zipbufferb, 8, cdb[2], block_desc); + len = zip_mode_sense(dev, zipbufferb, 8, cdb[2], block_desc); len = MIN(len, alloc_length); zipbufferb[0]=(len - 2) >> 8; zipbufferb[1]=(len - 2) & 255; @@ -1971,63 +1868,63 @@ zip_command(uint8_t id, uint8_t *cdb) } } - zip_set_buf_len(id, BufLen, &len); + zip_set_buf_len(dev, BufLen, &len); - zip_log("ZIP %i: Reading mode page: %02X...\n", id, cdb[2]); + zip_log("ZIP %i: Reading mode page: %02X...\n", dev->id, cdb[2]); - zip_data_command_finish(id, len, len, alloc_length, 0); + zip_data_command_finish(dev, len, len, alloc_length, 0); return; case GPCMD_MODE_SELECT_6: case GPCMD_MODE_SELECT_10: - zip_set_phase(id, SCSI_PHASE_DATA_OUT); + zip_set_phase(dev, SCSI_PHASE_DATA_OUT); if (cdb[0] == GPCMD_MODE_SELECT_6) { len = cdb[4]; - zip_buf_alloc(id, 256); + zip_buf_alloc(dev, 256); } else { len = (cdb[7] << 8) | cdb[8]; - zip_buf_alloc(id, 65536); + zip_buf_alloc(dev, 65536); } - zip_set_buf_len(id, BufLen, &len); + zip_set_buf_len(dev, BufLen, &len); dev->total_length = len; dev->do_page_save = cdb[1] & 1; dev->current_page_pos = 0; - zip_data_command_finish(id, len, len, len, 1); + zip_data_command_finish(dev, len, len, len, 1); return; case GPCMD_START_STOP_UNIT: - zip_set_phase(id, SCSI_PHASE_STATUS); + zip_set_phase(dev, SCSI_PHASE_STATUS); switch(cdb[4] & 3) { case 0: /* Stop the disc. */ - zip_eject(id); /* The Iomega Windows 9x drivers require this. */ + zip_eject(dev->id); /* The Iomega Windows 9x drivers require this. */ break; case 1: /* Start the disc and read the TOC. */ break; case 2: /* Eject the disc if possible. */ - /* zip_eject(id); */ + /* zip_eject(dev->id); */ break; case 3: /* Load the disc (close tray). */ - zip_reload(id); + zip_reload(dev->id); break; } - zip_command_complete(id); + zip_command_complete(dev); break; case GPCMD_INQUIRY: - zip_set_phase(id, SCSI_PHASE_DATA_IN); + zip_set_phase(dev, SCSI_PHASE_DATA_IN); max_len = cdb[3]; max_len <<= 8; max_len |= cdb[4]; - zip_buf_alloc(id, 65536); + zip_buf_alloc(dev, 65536); if (cdb[1] & 1) { preamble_len = 4; @@ -2046,8 +1943,8 @@ zip_command(uint8_t id, uint8_t *cdb) break; case 0x83: if (idx + 24 > max_len) { - zip_data_phase_error(id); - zip_buf_free(id); + zip_data_phase_error(dev); + zip_buf_free(dev); return; } @@ -2066,7 +1963,7 @@ zip_command(uint8_t id, uint8_t *cdb) zipbufferb[idx++] = 68; ide_padstr8(zipbufferb + idx, 8, "IOMEGA "); /* Vendor */ idx += 8; - if (zip_drives[id].is_250) + if (dev->drv->is_250) ide_padstr8(zipbufferb + idx, 40, "ZIP 250 "); /* Product */ else ide_padstr8(zipbufferb + idx, 40, "ZIP 100 "); /* Product */ @@ -2076,8 +1973,8 @@ zip_command(uint8_t id, uint8_t *cdb) break; default: zip_log("INQUIRY: Invalid page: %02X\n", cdb[2]); - zip_invalid_field(id); - zip_buf_free(id); + zip_invalid_field(dev); + zip_buf_free(dev); return; } } else { @@ -2090,21 +1987,21 @@ zip_command(uint8_t id, uint8_t *cdb) else zipbufferb[0] = 0x00; /*Hard disk*/ zipbufferb[1] = 0x80; /*Removable*/ - if (zip_drives[id].is_250) { - zipbufferb[2] = (zip_drives[id].bus_type == ZIP_BUS_SCSI) ? 0x02 : 0x00; /*SCSI-2 compliant*/ - zipbufferb[3] = (zip_drives[id].bus_type == ZIP_BUS_SCSI) ? 0x02 : 0x21; + if (dev->drv->is_250) { + zipbufferb[2] = (dev->drv->bus_type == ZIP_BUS_SCSI) ? 0x02 : 0x00; /*SCSI-2 compliant*/ + zipbufferb[3] = (dev->drv->bus_type == ZIP_BUS_SCSI) ? 0x02 : 0x21; } else { - zipbufferb[2] = (zip_drives[id].bus_type == ZIP_BUS_SCSI) ? 0x02 : 0x00; /*SCSI-2 compliant*/ - zipbufferb[3] = (zip_drives[id].bus_type == ZIP_BUS_SCSI) ? 0x02 : 0x21; + zipbufferb[2] = (dev->drv->bus_type == ZIP_BUS_SCSI) ? 0x02 : 0x00; /*SCSI-2 compliant*/ + zipbufferb[3] = (dev->drv->bus_type == ZIP_BUS_SCSI) ? 0x02 : 0x21; } zipbufferb[4] = 31; - if (zip_drives[id].bus_type == ZIP_BUS_SCSI) { + if (dev->drv->bus_type == ZIP_BUS_SCSI) { zipbufferb[6] = 1; /* 16-bit transfers supported */ zipbufferb[7] = 0x20; /* Wide bus supported */ } ide_padstr8(zipbufferb + 8, 8, "IOMEGA "); /* Vendor */ - if (zip_drives[id].is_250) { + if (dev->drv->is_250) { ide_padstr8(zipbufferb + 16, 16, "ZIP 250 "); /* Product */ ide_padstr8(zipbufferb + 32, 4, "42.S"); /* Revision */ if (max_len >= 44) @@ -2131,57 +2028,57 @@ atapi_out: len=idx; len = MIN(len, max_len); - zip_set_buf_len(id, BufLen, &len); + zip_set_buf_len(dev, BufLen, &len); - zip_data_command_finish(id, len, len, max_len, 0); + zip_data_command_finish(dev, len, len, max_len, 0); break; case GPCMD_PREVENT_REMOVAL: - zip_set_phase(id, SCSI_PHASE_STATUS); - zip_command_complete(id); + zip_set_phase(dev, SCSI_PHASE_STATUS); + zip_command_complete(dev); break; case GPCMD_SEEK_6: case GPCMD_SEEK_10: - zip_set_phase(id, SCSI_PHASE_STATUS); + zip_set_phase(dev, SCSI_PHASE_STATUS); switch(cdb[0]) { case GPCMD_SEEK_6: pos = (cdb[2] << 8) | cdb[3]; break; case GPCMD_SEEK_10: - pos = (cdb[2] << 24) | (cdb[3]<<16) | (cdb[4]<<8) | cdb[5]; + pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; break; } - zip_seek(id, pos); - zip_command_complete(id); + zip_seek(dev, pos); + zip_command_complete(dev); break; case GPCMD_READ_CDROM_CAPACITY: - zip_set_phase(id, SCSI_PHASE_DATA_IN); + zip_set_phase(dev, SCSI_PHASE_DATA_IN); - zip_buf_alloc(id, 8); + zip_buf_alloc(dev, 8); - if (zip_read_capacity(id, dev->current_cdb, zipbufferb, &len) == 0) { - zip_buf_free(id); + if (zip_read_capacity(dev, dev->current_cdb, zipbufferb, &len) == 0) { + zip_buf_free(dev); return; } - zip_set_buf_len(id, BufLen, &len); + zip_set_buf_len(dev, BufLen, &len); - zip_data_command_finish(id, len, len, len, 0); + zip_data_command_finish(dev, len, len, len, 0); break; case GPCMD_IOMEGA_EJECT: - zip_set_phase(id, SCSI_PHASE_STATUS); - zip_eject(id); - zip_command_complete(id); + zip_set_phase(dev, SCSI_PHASE_STATUS); + zip_eject(dev->id); + zip_command_complete(dev); break; case GPCMD_READ_FORMAT_CAPACITIES: len = (cdb[7] << 8) | cdb[8]; - zip_buf_alloc(id, len); + zip_buf_alloc(dev, len); memset(zipbufferb, 0, len); pos = 0; @@ -2190,18 +2087,18 @@ atapi_out: zipbufferb[pos++] = 0; zipbufferb[pos++] = 0; zipbufferb[pos++] = 0; - if (zip_drives[id].f != NULL) + if (dev->drv->f != NULL) zipbufferb[pos++] = 16; else zipbufferb[pos++] = 8; /* Current/Maximum capacity header */ - if (zip_drives[id].is_250) { - if (zip_drives[id].f != NULL) { - zipbufferb[pos++] = (zip_drives[id].medium_size >> 24) & 0xff; - zipbufferb[pos++] = (zip_drives[id].medium_size >> 16) & 0xff; - zipbufferb[pos++] = (zip_drives[id].medium_size >> 8) & 0xff; - zipbufferb[pos++] = zip_drives[id].medium_size & 0xff; + if (dev->drv->is_250) { + if (dev->drv->f != NULL) { + zipbufferb[pos++] = (dev->drv->medium_size >> 24) & 0xff; + zipbufferb[pos++] = (dev->drv->medium_size >> 16) & 0xff; + zipbufferb[pos++] = (dev->drv->medium_size >> 8) & 0xff; + zipbufferb[pos++] = dev->drv->medium_size & 0xff; zipbufferb[pos++] = 2; /* Current medium capacity */ } else { zipbufferb[pos++] = (ZIP_250_SECTORS >> 24) & 0xff; @@ -2215,7 +2112,7 @@ atapi_out: zipbufferb[pos++] = (ZIP_SECTORS >> 16) & 0xff; zipbufferb[pos++] = (ZIP_SECTORS >> 8) & 0xff; zipbufferb[pos++] = ZIP_SECTORS & 0xff; - if (zip_drives[id].f != NULL) + if (dev->drv->f != NULL) zipbufferb[pos++] = 2; else zipbufferb[pos++] = 3; @@ -2225,41 +2122,39 @@ atapi_out: zipbufferb[pos++] = 512 >> 8; zipbufferb[pos++] = 512 & 0xff; - if (zip_drives[id].f != NULL) { + if (dev->drv->f != NULL) { /* Formattable capacity descriptor */ - zipbufferb[pos++] = (zip_drives[id].medium_size >> 24) & 0xff; - zipbufferb[pos++] = (zip_drives[id].medium_size >> 16) & 0xff; - zipbufferb[pos++] = (zip_drives[id].medium_size >> 8) & 0xff; - zipbufferb[pos++] = zip_drives[id].medium_size & 0xff; + zipbufferb[pos++] = (dev->drv->medium_size >> 24) & 0xff; + zipbufferb[pos++] = (dev->drv->medium_size >> 16) & 0xff; + zipbufferb[pos++] = (dev->drv->medium_size >> 8) & 0xff; + zipbufferb[pos++] = dev->drv->medium_size & 0xff; zipbufferb[pos++] = 0; zipbufferb[pos++] = 512 >> 16; zipbufferb[pos++] = 512 >> 8; zipbufferb[pos++] = 512 & 0xff; } - zip_set_buf_len(id, BufLen, &len); + zip_set_buf_len(dev, BufLen, &len); - zip_data_command_finish(id, len, len, len, 0); + zip_data_command_finish(dev, len, len, len, 0); break; default: - zip_illegal_opcode(id); + zip_illegal_opcode(dev); break; } - /* zip_log("ZIP %i: Phase: %02X, request length: %i\n", dev->phase, dev->request_length); */ + /* zip_log("ZIP %i: Phase: %02X, request length: %i\n", dev->id, dev->phase, dev->request_length); */ - if (zip_atapi_phase_to_scsi(id) == SCSI_PHASE_STATUS) - zip_buf_free(id); + if (zip_atapi_phase_to_scsi(dev) == SCSI_PHASE_STATUS) + zip_buf_free(dev); } /* The command second phase function, needed for Mode Select. */ static uint8_t -zip_phase_data_out(uint8_t id) +zip_phase_data_out(zip_t *dev) { - zip_t *dev = zip[id]; - uint16_t block_desc_len; uint16_t pos; @@ -2284,12 +2179,12 @@ zip_phase_data_out(uint8_t id) case GPCMD_WRITE_12: case GPCMD_WRITE_AND_VERIFY_12: if (dev->requested_blocks > 0) - zip_blocks(id, &len, 1, 1); + zip_blocks(dev, &len, 1, 1); break; case GPCMD_WRITE_SAME_10: if (!dev->current_cdb[7] && !dev->current_cdb[8]) { - if (zip_drives[id].is_250) - last_to_write = (zip_drives[id].medium_size - 1); + if (dev->drv->is_250) + last_to_write = (dev->drv->medium_size - 1); else last_to_write = (ZIP_SECTORS - 1); } else @@ -2315,8 +2210,8 @@ zip_phase_data_out(uint8_t id) zipbufferb[6] = (s >> 8) & 0xff; zipbufferb[7] = s & 0xff; } - fseek(zip_drives[id].f, zip_drives[id].base + (i << 9), SEEK_SET); - fwrite(zipbufferb, 1, 512, zip_drives[id].f); + fseek(dev->drv->f, dev->drv->base + (i << 9), SEEK_SET); + fwrite(zipbufferb, 1, 512, dev->drv->f); } break; case GPCMD_MODE_SELECT_6: @@ -2326,7 +2221,7 @@ zip_phase_data_out(uint8_t id) else hdr_len = 4; - if (zip_drives[id].bus_type == ZIP_BUS_SCSI) { + if (dev->drv->bus_type == ZIP_BUS_SCSI) { if (dev->current_cdb[0] == GPCMD_MODE_SELECT_6) { block_desc_len = zipbufferb[2]; block_desc_len <<= 8; @@ -2353,10 +2248,10 @@ zip_phase_data_out(uint8_t id) for (i = 0; i < page_len; i++) { ch = zip_mode_sense_pages_changeable.pages[page][i + 2]; val = zipbufferb[pos + i]; - old_val = zip_mode_sense_pages_saved[id].pages[page][i + 2]; + old_val = dev->ms_pages_saved.pages[page][i + 2]; if (val != old_val) { if (ch) - zip_mode_sense_pages_saved[id].pages[page][i + 2] = val; + dev->ms_pages_saved.pages[page][i + 2] = val; else error |= 1; } @@ -2365,19 +2260,19 @@ zip_phase_data_out(uint8_t id) pos += page_len; - if (zip_drives[id].bus_type == ZIP_BUS_SCSI) + if (dev->drv->bus_type == ZIP_BUS_SCSI) val = zip_mode_sense_pages_default_scsi.pages[page][0] & 0x80; else val = zip_mode_sense_pages_default.pages[page][0] & 0x80; if (dev->do_page_save && val) - zip_mode_sense_save(id); + zip_mode_sense_save(dev); if (pos >= dev->total_length) break; } if (error) { - zip_invalid_field_pl(id); + zip_invalid_field_pl(dev); return 0; } break; @@ -2389,47 +2284,49 @@ zip_phase_data_out(uint8_t id) /* This is the general ATAPI PIO request function. */ static void -zip_pio_request(uint8_t id, uint8_t out) +zip_pio_request(zip_t *dev, uint8_t out) { - zip_t *dev = zip[id]; - - int old_pos = 0; int ret = 0; - if (zip_drives[id].bus_type < ZIP_BUS_SCSI) { - zip_log("ZIP %i: Lowering IDE IRQ\n", id); - ide_irq_lower(ide_drives[zip_drives[id].ide_channel]); + if (dev->drv->bus_type < ZIP_BUS_SCSI) { + zip_log("ZIP %i: Lowering IDE IRQ\n", dev->id); + ide_irq_lower(ide_drives[dev->drv->ide_channel]); } dev->status = BUSY_STAT; if (dev->pos >= dev->packet_len) { - zip_log("ZIP %i: %i bytes %s, command done\n", id, dev->pos, out ? "written" : "read"); + zip_log("ZIP %i: %i bytes %s, command done\n", dev->id, dev->pos, out ? "written" : "read"); dev->pos = dev->request_pos = 0; if (out) { - ret = zip_phase_data_out(id); + ret = zip_phase_data_out(dev); /* If ret = 0 (phase 1 error), then we do not do anything else other than free the buffer, as the phase and callback have already been set by the error function. */ if (ret) - zip_command_complete(id); + zip_command_complete(dev); } else - zip_command_complete(id); - zip_buf_free(id); + zip_command_complete(dev); + zip_buf_free(dev); } else { - zip_log("ZIP %i: %i bytes %s, %i bytes are still left\n", id, dev->pos, out ? "written" : "read", dev->packet_len - dev->pos); + zip_log("ZIP %i: %i bytes %s, %i bytes are still left\n", dev->id, dev->pos, + out ? "written" : "read", dev->packet_len - dev->pos); /* If less than (packet length) bytes are remaining, update packet length accordingly. */ if ((dev->packet_len - dev->pos) < (dev->max_transfer_len)) dev->max_transfer_len = dev->packet_len - dev->pos; - zip_log("ZIP %i: Packet length %i, request length %i\n", id, dev->packet_len, dev->max_transfer_len); + zip_log("ZIP %i: Packet length %i, request length %i\n", dev->id, dev->packet_len, + dev->max_transfer_len); - old_pos = dev->pos; dev->packet_status = out ? ZIP_PHASE_DATA_OUT : ZIP_PHASE_DATA_IN; - zip_command_common(id); - dev->pos = old_pos; + + dev->status = BUSY_STAT; + dev->phase = 1; + zip_phase_callback(dev); + dev->callback = 0LL; + zip_set_callback(dev); dev->request_pos = 0; } @@ -2456,7 +2353,7 @@ zip_read_from_ide_dma(uint8_t channel) if (ret == 2) /* DMA not enabled, wait for it to be enabled. */ return 2; else if (ret == 1) { /* DMA error. */ - zip_bus_master_error(id); + zip_bus_master_error(dev); return 0; } else return 1; @@ -2466,12 +2363,12 @@ zip_read_from_ide_dma(uint8_t channel) static int -zip_read_from_scsi_dma(uint8_t scsi_id, uint8_t scsi_lun) +zip_read_from_scsi_dma(uint8_t scsi_id) { zip_t *dev; - uint8_t id = scsi_zip_drives[scsi_id][scsi_lun]; - int32_t *BufLen = &SCSIDevices[scsi_id][scsi_lun].BufferLength; + uint8_t id = scsi_zip_drives[scsi_id]; + int32_t *BufLen = &SCSIDevices[scsi_id].BufferLength; if (id > ZIP_NUM) return 0; @@ -2479,46 +2376,39 @@ zip_read_from_scsi_dma(uint8_t scsi_id, uint8_t scsi_lun) dev = zip[id]; zip_log("Reading from SCSI DMA: SCSI ID %02X, init length %i\n", scsi_id, *BufLen); - memcpy(zipbufferb, SCSIDevices[scsi_id][scsi_lun].CmdBuffer, *BufLen); + memcpy(zipbufferb, SCSIDevices[scsi_id].CmdBuffer, *BufLen); return 1; } static void -zip_irq_raise(uint8_t id) +zip_irq_raise(zip_t *dev) { - if (zip_drives[id].bus_type < ZIP_BUS_SCSI) - ide_irq_raise(ide_drives[zip_drives[id].ide_channel]); + if (dev->drv->bus_type < ZIP_BUS_SCSI) + ide_irq_raise(ide_drives[dev->drv->ide_channel]); } static int -zip_read_from_dma(uint8_t id) +zip_read_from_dma(zip_t *dev) { - zip_t *dev = zip[id]; - - int32_t *BufLen = &SCSIDevices[zip_drives[id].scsi_device_id][zip_drives[id].scsi_device_lun].BufferLength; + int32_t *BufLen = &SCSIDevices[dev->drv->scsi_device_id].BufferLength; int ret = 0; - int in_data_length = 0; - - if (zip_drives[id].bus_type == ZIP_BUS_SCSI) - ret = zip_read_from_scsi_dma(zip_drives[id].scsi_device_id, zip_drives[id].scsi_device_lun); + if (dev->drv->bus_type == ZIP_BUS_SCSI) + ret = zip_read_from_scsi_dma(dev->drv->scsi_device_id); else - ret = zip_read_from_ide_dma(zip_drives[id].ide_channel); + ret = zip_read_from_ide_dma(dev->drv->ide_channel); if (ret != 1) return ret; - if (zip_drives[id].bus_type == ZIP_BUS_SCSI) { - in_data_length = *BufLen; - zip_log("ZIP %i: SCSI Input data length: %i\n", id, in_data_length); - } else { - in_data_length = dev->max_transfer_len; - zip_log("ZIP %i: ATAPI Input data length: %i\n", id, in_data_length); - } + if (dev->drv->bus_type == ZIP_BUS_SCSI) + zip_log("ZIP %i: SCSI Input data length: %i\n", dev->id, *BufLen); + else + zip_log("ZIP %i: ATAPI Input data length: %i\n", dev->id, dev->packet_len); - ret = zip_phase_data_out(id); + ret = zip_phase_data_out(dev); if (ret) return 1; @@ -2549,7 +2439,7 @@ zip_write_to_ide_dma(uint8_t channel) if (ret == 2) /* DMA not enabled, wait for it to be enabled. */ return 2; else if (ret == 1) { /* DMA error. */ - zip_bus_master_error(id); + zip_bus_master_error(dev); return 0; } else return 1; @@ -2559,12 +2449,12 @@ zip_write_to_ide_dma(uint8_t channel) static int -zip_write_to_scsi_dma(uint8_t scsi_id, uint8_t scsi_lun) +zip_write_to_scsi_dma(uint8_t scsi_id) { zip_t *dev; - uint8_t id = scsi_zip_drives[scsi_id][scsi_lun]; - int32_t *BufLen = &SCSIDevices[scsi_id][scsi_lun].BufferLength; + uint8_t id = scsi_zip_drives[scsi_id]; + int32_t *BufLen = &SCSIDevices[scsi_id].BufferLength; if (id > ZIP_NUM) return 0; @@ -2572,115 +2462,117 @@ zip_write_to_scsi_dma(uint8_t scsi_id, uint8_t scsi_lun) dev = zip[id]; zip_log("Writing to SCSI DMA: SCSI ID %02X, init length %i\n", scsi_id, *BufLen); - memcpy(SCSIDevices[scsi_id][scsi_lun].CmdBuffer, zipbufferb, *BufLen); - zip_log("ZIP %i: Data from CD buffer: %02X %02X %02X %02X %02X %02X %02X %02X\n", id, zipbufferb[0], zipbufferb[1], zipbufferb[2], zipbufferb[3], zipbufferb[4], zipbufferb[5], zipbufferb[6], zipbufferb[7]); - zip_log("ZIP %i: Data from SCSI DMA : %02X %02X %02X %02X %02X %02X %02X %02X\n", id, SCSIDevices[scsi_id][scsi_lun].CmdBuffer[0], SCSIDevices[scsi_id][scsi_lun].CmdBuffer[1], SCSIDevices[scsi_id][scsi_lun].CmdBuffer[2], SCSIDevices[scsi_id][scsi_lun].CmdBuffer[3], SCSIDevices[scsi_id][scsi_lun].CmdBuffer[4], SCSIDevices[scsi_id][scsi_lun].CmdBuffer[5], SCSIDevices[scsi_id][scsi_lun].CmdBuffer[6], SCSIDevices[scsi_id][scsi_lun].CmdBuffer[7]); + memcpy(SCSIDevices[scsi_id].CmdBuffer, zipbufferb, *BufLen); + zip_log("ZIP %i: Data from CD buffer: %02X %02X %02X %02X %02X %02X %02X %02X\n", id, + zipbufferb[0], zipbufferb[1], zipbufferb[2], zipbufferb[3], zipbufferb[4], zipbufferb[5], + zipbufferb[6], zipbufferb[7]); + zip_log("ZIP %i: Data from SCSI DMA : %02X %02X %02X %02X %02X %02X %02X %02X\n", id, + SCSIDevices[scsi_id].CmdBuffer[0], SCSIDevices[scsi_id].CmdBuffer[1], + SCSIDevices[scsi_id].CmdBuffer[2], SCSIDevices[scsi_id].CmdBuffer[3], + SCSIDevices[scsi_id].CmdBuffer[4], SCSIDevices[scsi_id].CmdBuffer[5], + SCSIDevices[scsi_id].CmdBuffer[6], SCSIDevices[scsi_id].CmdBuffer[7]); return 1; } static int -zip_write_to_dma(uint8_t id) +zip_write_to_dma(zip_t *dev) { - zip_t *dev = zip[id]; - - int32_t *BufLen = &SCSIDevices[zip_drives[id].scsi_device_id][zip_drives[id].scsi_device_lun].BufferLength; + int32_t *BufLen = &SCSIDevices[dev->drv->scsi_device_id].BufferLength; int ret = 0; - if (zip_drives[id].bus_type == ZIP_BUS_SCSI) { - zip_log("Write to SCSI DMA: (%02X:%02X)\n", zip_drives[id].scsi_device_id, zip_drives[id].scsi_device_lun); - ret = zip_write_to_scsi_dma(zip_drives[id].scsi_device_id, zip_drives[id].scsi_device_lun); + if (dev->drv->bus_type == ZIP_BUS_SCSI) { + zip_log("Write to SCSI DMA: (ID %02X)\n", dev->drv->scsi_device_id); + ret = zip_write_to_scsi_dma(dev->drv->scsi_device_id); } else - ret = zip_write_to_ide_dma(zip_drives[id].ide_channel); + ret = zip_write_to_ide_dma(dev->drv->ide_channel); - if (zip_drives[id].bus_type == ZIP_BUS_SCSI) - zip_log("ZIP %i: SCSI Output data length: %i\n", id, *BufLen); + if (dev->drv->bus_type == ZIP_BUS_SCSI) + zip_log("ZIP %i: SCSI Output data length: %i\n", dev->id, *BufLen); else - zip_log("ZIP %i: ATAPI Output data length: %i\n", id, dev->packet_len); + zip_log("ZIP %i: ATAPI Output data length: %i\n", dev->id, dev->packet_len); return ret; } -/* If the result is 1, issue an IRQ, otherwise not. */ void -zip_phase_callback(uint8_t id) +zip_phase_callback(zip_t *dev) { - zip_t *dev = zip[id]; int ret; switch(dev->packet_status) { case ZIP_PHASE_IDLE: - zip_log("ZIP %i: ZIP_PHASE_IDLE\n", id); - dev->pos=0; + zip_log("ZIP %i: ZIP_PHASE_IDLE\n", dev->id); + dev->pos = 0; dev->phase = 1; dev->status = READY_STAT | DRQ_STAT | (dev->status & ERR_STAT); return; case ZIP_PHASE_COMMAND: - zip_log("ZIP %i: ZIP_PHASE_COMMAND\n", id); - dev->status = BUSY_STAT | (dev->status &ERR_STAT); - memcpy(dev->atapi_cdb, zipbufferb, dev->cdb_len); - zip_command(id, dev->atapi_cdb); + zip_log("ZIP %i: ZIP_PHASE_COMMAND\n", dev->id); + dev->status = BUSY_STAT | (dev->status & ERR_STAT); + memcpy(dev->atapi_cdb, zipbufferb, 12); + zip_command(dev, dev->atapi_cdb); return; case ZIP_PHASE_COMPLETE: - zip_log("ZIP %i: ZIP_PHASE_COMPLETE\n", id); + zip_log("ZIP %i: ZIP_PHASE_COMPLETE\n", dev->id); dev->status = READY_STAT; dev->phase = 3; dev->packet_status = 0xFF; - ui_sb_update_icon(SB_ZIP | id, 0); - zip_irq_raise(id); + ui_sb_update_icon(SB_ZIP | dev->id, 0); + zip_irq_raise(dev); return; case ZIP_PHASE_DATA_OUT: - zip_log("ZIP %i: ZIP_PHASE_DATA_OUT\n", id); + zip_log("ZIP %i: ZIP_PHASE_DATA_OUT\n", dev->id); dev->status = READY_STAT | DRQ_STAT | (dev->status & ERR_STAT); dev->phase = 0; - zip_irq_raise(id); + zip_irq_raise(dev); return; case ZIP_PHASE_DATA_OUT_DMA: - zip_log("ZIP %i: ZIP_PHASE_DATA_OUT_DMA\n", id); - ret = zip_read_from_dma(id); + zip_log("ZIP %i: ZIP_PHASE_DATA_OUT_DMA\n", dev->id); + ret = zip_read_from_dma(dev); - if ((ret == 1) || (zip_drives[id].bus_type == ZIP_BUS_SCSI)) { + if ((ret == 1) || (dev->drv->bus_type == ZIP_BUS_SCSI)) { zip_log("ZIP %i: DMA data out phase done\n"); - zip_buf_free(id); - zip_command_complete(id); + zip_buf_free(dev); + zip_command_complete(dev); } else if (ret == 2) { zip_log("ZIP %i: DMA out not enabled, wait\n"); - zip_command_bus(id); + zip_command_bus(dev); } else { zip_log("ZIP %i: DMA data out phase failure\n"); - zip_buf_free(id); + zip_buf_free(dev); } return; case ZIP_PHASE_DATA_IN: - zip_log("ZIP %i: ZIP_PHASE_DATA_IN\n", id); + zip_log("ZIP %i: ZIP_PHASE_DATA_IN\n", dev->id); dev->status = READY_STAT | DRQ_STAT | (dev->status & ERR_STAT); dev->phase = 2; - zip_irq_raise(id); + zip_irq_raise(dev); return; case ZIP_PHASE_DATA_IN_DMA: - zip_log("ZIP %i: ZIP_PHASE_DATA_IN_DMA\n", id); - ret = zip_write_to_dma(id); + zip_log("ZIP %i: ZIP_PHASE_DATA_IN_DMA\n", dev->id); + ret = zip_write_to_dma(dev); - if ((ret == 1) || (zip_drives[id].bus_type == ZIP_BUS_SCSI)) { - zip_log("ZIP %i: DMA data in phase done\n"); - zip_buf_free(id); - zip_command_complete(id); + if ((ret == 1) || (dev->drv->bus_type == ZIP_BUS_SCSI)) { + zip_log("ZIP %i: DMA data in phase done\n", dev->id); + zip_buf_free(dev); + zip_command_complete(dev); } else if (ret == 2) { - zip_log("ZIP %i: DMA in not enabled, wait\n"); - zip_command_bus(id); + zip_log("ZIP %i: DMA in not enabled, wait\n", dev->id); + zip_command_bus(dev); } else { - zip_log("ZIP %i: DMA data in phase failure\n"); - zip_buf_free(id); + zip_log("ZIP %i: DMA data in phase failure\n", dev->id); + zip_buf_free(dev); } return; case ZIP_PHASE_ERROR: - zip_log("ZIP %i: ZIP_PHASE_ERROR\n", id); + zip_log("ZIP %i: ZIP_PHASE_ERROR\n", dev->id); dev->status = READY_STAT | ERR_STAT; dev->phase = 3; dev->packet_status = 0xFF; - zip_irq_raise(id); - ui_sb_update_icon(SB_ZIP | id, 0); + zip_irq_raise(dev); + ui_sb_update_icon(SB_ZIP | dev->id, 0); return; } } @@ -2733,15 +2625,17 @@ zip_read(uint8_t channel, int length) } if (dev->packet_status == ZIP_PHASE_DATA_IN) { + zip_log("ZIP %i: Returning: %04X (buffer position: %05i, request position: %05i)\n", + id, temp, (dev->pos - 2) & 0xffff, (dev->request_pos - 2) & 0xffff); if ((dev->request_pos >= dev->max_transfer_len) || (dev->pos >= dev->packet_len)) { /* Time for a DRQ. */ zip_log("ZIP %i: Issuing read callback\n", id); - zip_pio_request(id, 0); + zip_pio_request(dev, 0); } - zip_log("ZIP %i: Returning: %02X (buffer position: %i, request position: %i)\n", id, temp, dev->pos, dev->request_pos); return temp; } else { - zip_log("ZIP %i: Returning zero (buffer position: %i, request position: %i)\n", id, dev->pos, dev->request_pos); + zip_log("ZIP %i: Returning: 0000 (buffer position: %05i, request position: %05i)\n", + id, (dev->pos - 2) & 0xffff, (dev->request_pos - 2) & 0xffff); return 0; } } @@ -2764,7 +2658,7 @@ zip_write(uint8_t channel, uint32_t val, int length) if (dev->packet_status == ZIP_PHASE_IDLE) { if (!zipbufferb) - zip_buf_alloc(id, dev->cdb_len); + zip_buf_alloc(dev, 12); } zipbufferw = (uint16_t *) zipbufferb; @@ -2796,16 +2690,16 @@ zip_write(uint8_t channel, uint32_t val, int length) if (dev->packet_status == ZIP_PHASE_DATA_OUT) { if ((dev->request_pos >= dev->max_transfer_len) || (dev->pos >= dev->packet_len)) { /* Time for a DRQ. */ - zip_pio_request(id, 1); + zip_pio_request(dev, 1); } return; } else if (dev->packet_status == ZIP_PHASE_IDLE) { - if (dev->pos >= dev->cdb_len) { - dev->pos=0; + if (dev->pos >= 12) { + dev->pos = 0; dev->status = BUSY_STAT; dev->packet_status = ZIP_PHASE_COMMAND; timer_process(); - zip_phase_callback(id); + zip_phase_callback(dev); timer_update_outstanding(); } return; @@ -2828,23 +2722,45 @@ zip_hard_reset(void) { int c; - zip_destroy_drives(); - - for (c=0; cid = c; + zip[c]->drv = &zip_drives[c]; + + zip_init(zip[c]); if (wcslen(zip_drives[c].image_path)) - zip_load(c, zip_drives[c].image_path); + zip_load(zip[c], zip_drives[c].image_path); - zip_mode_sense_load(c); + zip_mode_sense_load(zip[c]); } } build_atapi_zip_map(); } + + +void +zip_close(void) +{ + zip_t *dev; + int c; + + for (c = 0; c < ZIP_NUM; c++) { + dev = zip[c]; + + if (dev) { + zip_disk_close(dev); + + free(zip[c]); + zip[c] = NULL; + } + } +} diff --git a/src/disk/zip.h b/src/disk/zip.h index 5caba5d1d..67be6797b 100644 --- a/src/disk/zip.h +++ b/src/disk/zip.h @@ -48,9 +48,32 @@ enum { typedef struct { - uint8_t previous_command, error, - features, status, - phase, *buffer, + unsigned int bus_type; /* 0 = ATAPI, 1 = SCSI */ + uint8_t ide_channel, + bus_mode; /* Bit 0 = PIO suported; + Bit 1 = DMA supportd. */ + + unsigned int scsi_device_id, is_250; + + wchar_t image_path[1024], + prev_image_path[1024]; + + int read_only, ui_writeprot; + + uint32_t medium_size, base; + + FILE *f; +} zip_drive_t; + +typedef struct { + mode_sense_pages_t ms_pages_saved; + + zip_drive_t *drv; + + uint8_t previous_command, + error, features, + status, phase, + id, *buffer, atapi_cdb[16], current_cdb[16], sense[256]; @@ -77,35 +100,16 @@ typedef struct { uint64_t current_page_code; } zip_t; -typedef struct { - unsigned int bus_type; /* 0 = ATAPI, 1 = SCSI */ - uint8_t ide_channel, - bus_mode; /* Bit 0 = PIO suported; - Bit 1 = DMA supportd. */ - - unsigned int scsi_device_id, scsi_device_lun, - is_250; - - wchar_t image_path[1024], - prev_image_path[1024]; - - int read_only, ui_writeprot; - - uint32_t medium_size, base; - - FILE *f; -} zip_drive_t; - extern zip_t *zip[ZIP_NUM]; extern zip_drive_t zip_drives[ZIP_NUM]; extern uint8_t atapi_zip_drives[8]; -extern uint8_t scsi_zip_drives[16][8]; +extern uint8_t scsi_zip_drives[16]; -#define zip_sense_error zip[id]->sense[0] -#define zip_sense_key zip[id]->sense[2] -#define zip_asc zip[id]->sense[12] -#define zip_ascq zip[id]->sense[13] +#define zip_sense_error dev->sense[0] +#define zip_sense_key dev->sense[2] +#define zip_asc dev->sense[12] +#define zip_ascq dev->sense[13] #ifdef __cplusplus @@ -116,37 +120,32 @@ extern int (*ide_bus_master_read)(int channel, uint8_t *data, int transfer_lengt extern int (*ide_bus_master_write)(int channel, uint8_t *data, int transfer_length, void *priv); extern void (*ide_bus_master_set_irq)(int channel, void *priv); extern void *ide_bus_master_priv[2]; -extern void ioctl_close(uint8_t id); -extern uint32_t zip_mode_sense_get_channel(uint8_t id, int channel); -extern uint32_t zip_mode_sense_get_volume(uint8_t id, int channel); extern void build_atapi_zip_map(void); extern void build_scsi_zip_map(void); -extern int zip_ZIP_PHASE_to_scsi(uint8_t id); -extern int zip_atapi_phase_to_scsi(uint8_t id); -extern void zip_command(uint8_t id, uint8_t *cdb); -extern void zip_phase_callback(uint8_t id); +extern int zip_ZIP_PHASE_to_scsi(zip_t *dev); +extern int zip_atapi_phase_to_scsi(zip_t *dev); +extern void zip_command(zip_t *dev, uint8_t *cdb); +extern void zip_phase_callback(zip_t *dev); extern uint32_t zip_read(uint8_t channel, int length); extern void zip_write(uint8_t channel, uint32_t val, int length); -extern void zip_close(uint8_t id); -extern void zip_disk_reload(uint8_t id); -extern void zip_reset(uint8_t id); -extern void zip_set_signature(int id); -extern void zip_request_sense_for_scsi(uint8_t id, uint8_t *buffer, uint8_t alloc_length); +extern void zip_disk_close(zip_t *dev); +extern void zip_disk_reload(zip_t *dev); +extern void zip_reset(zip_t *dev); +extern void zip_set_signature(zip_t *dev); +extern void zip_request_sense_for_scsi(zip_t *dev, uint8_t *buffer, uint8_t alloc_length); extern void zip_update_cdb(uint8_t *cdb, int lba_pos, int number_of_blocks); -extern void zip_insert(uint8_t id); +extern void zip_insert(zip_t *dev); -extern int find_zip_for_scsi_id(uint8_t scsi_id, uint8_t scsi_lun); -extern int zip_read_capacity(uint8_t id, uint8_t *cdb, uint8_t *buffer, uint32_t *len); +extern int find_zip_for_scsi_id(uint8_t scsi_id); +extern int zip_read_capacity(zip_t *dev, uint8_t *cdb, uint8_t *buffer, uint32_t *len); extern void zip_global_init(void); extern void zip_hard_reset(void); -extern int zip_load(uint8_t id, wchar_t *fn); - -extern void zip_destroy_drives(void); -extern void zip_close(uint8_t id); +extern int zip_load(zip_t *dev, wchar_t *fn); +extern void zip_close(); #ifdef __cplusplus } diff --git a/src/floppy/fdc.c b/src/floppy/fdc.c index 37962cd3a..2b4e38514 100644 --- a/src/floppy/fdc.c +++ b/src/floppy/fdc.c @@ -9,7 +9,7 @@ * Implementation of the NEC uPD-765 and compatible floppy disk * controller. * - * Version: @(#)fdc.c 1.0.8 2018/05/09 + * Version: @(#)fdc.c 1.0.9 2018/06/12 * * Authors: Miran Grca, * Sarah Walker, @@ -1710,10 +1710,8 @@ fdc_error(fdc_t *fdc, int st5, int st6) fdc->fintr = 0; fdc->stat = 0xD0; fdc->st0 = fdc->res[4] = 0x40 | (fdd_get_head(real_drive(fdc, fdc->drive)) ? 4 : 0) | fdc->rw_drive; - if (fdc->head && !fdd_is_double_sided(real_drive(fdc, fdc->drive))) { - pclog("Head 1 on 1-sided drive\n"); + if (fdc->head && !fdd_is_double_sided(real_drive(fdc, fdc->drive))) fdc->st0 |= 0x08; - } fdc->res[5] = st5; fdc->res[6] = st6; fdc_log("FDC Error: %02X %02X %02X\n", fdc->res[4], fdc->res[5], fdc->res[6]); diff --git a/src/floppy/fdd_86f.c b/src/floppy/fdd_86f.c index 8f822a3f7..60df4620e 100644 --- a/src/floppy/fdd_86f.c +++ b/src/floppy/fdd_86f.c @@ -10,7 +10,7 @@ * data in the form of FM/MFM-encoded transitions) which also * forms the core of the emulator's floppy disk emulation. * - * Version: @(#)fdd_86f.c 1.0.9 2018/05/06 + * Version: @(#)fdd_86f.c 1.0.10 2018/06/12 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -1435,9 +1435,9 @@ d86f_read_sector_id(int drive, int side, int match) dev->state = STATE_IDLE; fdc_finishread(d86f_fdc); fdc_headercrcerror(d86f_fdc); - } else if (dev->state == STATE_0A_READ_ID) { + } else if (dev->state == STATE_0A_READ_ID) dev->state--; - } else { + else { dev->error_condition |= 1; /* Mark that there was an ID CRC error. */ dev->state++; } @@ -1549,6 +1549,7 @@ d86f_read_sector_data(int drive, int side) if (dev->data_find.bits_obtained) { if (!(dev->data_find.bits_obtained & 15)) { /* We've got a byte. */ + d86f_log("86F: We've got a byte.\n"); if (dev->data_find.bytes_obtained < sector_len) { data = decodefm(drive, dev->last_word[side]); if (dev->state == STATE_11_SCAN_DATA) { @@ -1559,33 +1560,18 @@ d86f_read_sector_data(int drive, int side) if (dev->data_find.bytes_obtained < d86f_get_data_len(drive)) { if (dev->state != STATE_16_VERIFY_DATA) { read_status = fdc_data(d86f_fdc, data); - if (read_status == -1) { + if (read_status == -1) dev->dma_over++; - } } } } fdd_calccrc(data, &(dev->calc_crc)); - } else if (dev->data_find.bytes_obtained < crc_pos) { + } else if (dev->data_find.bytes_obtained < crc_pos) dev->track_crc.bytes[(dev->data_find.bytes_obtained - sector_len) ^ 1] = decodefm(drive, dev->last_word[side]); - } dev->data_find.bytes_obtained++; if (dev->data_find.bytes_obtained == (crc_pos + fdc_get_gap(d86f_fdc))) { /* We've got the data. */ - if (dev->dma_over > 1) { - dev->data_find.sync_marks = dev->data_find.bits_obtained = dev->data_find.bytes_obtained = 0; - dev->error_condition = 0; - dev->state = STATE_IDLE; - fdc_finishread(d86f_fdc); - fdc_overrun(d86f_fdc); - - d86f_get_bit(drive, side); - - dev->data_find.bits_obtained++; - return; - } - if ((dev->calc_crc.word != dev->track_crc.word) && (dev->state != STATE_02_READ_DATA)) { d86f_log("86F: Data CRC error: %04X != %04X (%08X)\n", dev->track_crc.word, dev->calc_crc.word, dev->last_sector.dword); dev->data_find.sync_marks = dev->data_find.bits_obtained = dev->data_find.bytes_obtained = 0; @@ -1600,15 +1586,14 @@ d86f_read_sector_data(int drive, int side) fdc_track_finishread(d86f_fdc, dev->error_condition); } else { /* CRC is valid. */ + d86f_log("86F: Data CRC OK: %04X != %04X (%08X)\n", dev->track_crc.word, dev->calc_crc.word, dev->last_sector.dword); dev->data_find.sync_marks = dev->data_find.bits_obtained = dev->data_find.bytes_obtained = 0; dev->error_condition = 0; - if (dev->state == STATE_11_SCAN_DATA) { - dev->state = STATE_IDLE; + dev->state = STATE_IDLE; + if (dev->state == STATE_11_SCAN_DATA) fdc_sector_finishcompare(d86f_fdc, (dev->satisfying_bytes == ((128 << ((uint32_t) dev->last_sector.id.n)) - 1)) ? 1 : 0); - } else { - dev->state = STATE_IDLE; + else fdc_sector_finishread(d86f_fdc); - } } } } @@ -1704,17 +1689,6 @@ d86f_write_sector_data(int drive, int side, int mfm, uint16_t am) dev->data_find.bytes_obtained++; if (dev->data_find.bytes_obtained == (crc_pos + fdc_get_gap(d86f_fdc))) { - if (dev->dma_over > 1) { - dev->data_find.sync_marks = dev->data_find.bits_obtained = dev->data_find.bytes_obtained = 0; - dev->error_condition = 0; - dev->state = STATE_IDLE; - fdc_finishread(d86f_fdc); - fdc_overrun(d86f_fdc); - - dev->data_find.bits_obtained++; - return; - } - /* We've written the data. */ dev->data_find.sync_marks = dev->data_find.bits_obtained = dev->data_find.bytes_obtained = 0; dev->error_condition = 0; @@ -2143,15 +2117,6 @@ d86f_turbo_read(int drive, int side) } } - if (dev->dma_over > 1) { - dev->data_find.sync_marks = dev->data_find.bits_obtained = dev->data_find.bytes_obtained = 0; - dev->error_condition = 0; - dev->state = STATE_IDLE; - fdc_finishread(d86f_fdc); - fdc_overrun(d86f_fdc); - return; - } - if (dev->turbo_pos >= (128 << dev->last_sector.id.n)) { /* CRC is valid. */ dev->data_find.sync_marks = dev->data_find.bits_obtained = dev->data_find.bytes_obtained = 0; @@ -2573,7 +2538,8 @@ d86f_poll(int drive) fdc_wrongcylinder(d86f_fdc); else fdc_nosector(d86f_fdc); - } + } else + fdc_nosector(d86f_fdc); } else { fdc_noidam(d86f_fdc); } @@ -3191,7 +3157,8 @@ d86f_readsector(int drive, int sector, int track, int side, int rate, int sector int ret = 0; ret = d86f_common_command(drive, sector, track, side, rate, sector_size); - if (! ret) return; + if (! ret) + return; if (sector == SECTOR_FIRST) dev->state = STATE_02_SPIN_TO_INDEX; diff --git a/src/intel_piix.c b/src/intel_piix.c index c2246abb3..43f8dd17b 100644 --- a/src/intel_piix.c +++ b/src/intel_piix.c @@ -10,7 +10,7 @@ * word 0 - base address * word 1 - bits 1-15 = byte count, bit 31 = end of transfer * - * Version: @(#)intel_piix.c 1.0.16 2018/05/11 + * Version: @(#)intel_piix.c 1.0.17 2018/06/02 * * Authors: Sarah Walker, * Miran Grca, @@ -829,7 +829,7 @@ piix_reset(void *p) } for (i = 0; i < ZIP_NUM; i++) { if (zip_drives[i].bus_type == ZIP_BUS_ATAPI) - zip_reset(i); + zip_reset(zip[i]); } } diff --git a/src/keyboard_at.c b/src/keyboard_at.c index 7bdece8c8..391f725be 100644 --- a/src/keyboard_at.c +++ b/src/keyboard_at.c @@ -8,7 +8,7 @@ * * Intel 8042 (AT keyboard controller) emulation. * - * Version: @(#)keyboard_at.c 1.0.36 2018/05/12 + * Version: @(#)keyboard_at.c 1.0.37 2018/05/25 * * Authors: Sarah Walker, * Miran Grca, @@ -44,6 +44,7 @@ #include "sound/snd_speaker.h" #include "video/video.h" #include "keyboard.h" +#include "mouse.h" #define STAT_PARITY 0x80 @@ -121,6 +122,8 @@ typedef struct { uint8_t (*write60_ven)(void *p, uint8_t val); uint8_t (*write64_ven)(void *p, uint8_t val); + + int64_t timeout; } atkbd_t; @@ -1001,6 +1004,20 @@ kbd_pulse_poll(void *p) } +static void +kbd_timeout_poll(void *p) +{ + atkbd_t *kbd = (atkbd_t *) p; + + kbd->key_wantdata = 0; + kbd->want60 = 0; + if (mouse_p) + mouse_clear_data(mouse_p); + + kbd->timeout = 0LL; +} + + static void kbd_keyboard_set(atkbd_t *kbd, uint8_t enable) { @@ -1074,6 +1091,7 @@ kbd_write64_generic(void *p, uint8_t val) if ((kbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) { kbdlog("ATkbd: write mouse output buffer\n"); kbd->want60 = 1; + kbd->timeout = 25000LL * TIMER_USEC; return 0; } break; @@ -1081,6 +1099,7 @@ kbd_write64_generic(void *p, uint8_t val) if ((kbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) { kbdlog("ATkbd: write to mouse\n"); kbd->want60 = 1; + kbd->timeout = 25000LL * TIMER_USEC; return 0; } break; @@ -1122,6 +1141,7 @@ kbd_write60_ami(void *p, uint8_t val) if (kbd->secr_phase == 1) { kbd->mem_addr = val; kbd->want60 = 1; + kbd->timeout = 25000LL * TIMER_USEC; kbd->secr_phase = 2; } else if (kbd->secr_phase == 2) { kbd->mem[kbd->mem_addr] = val; @@ -1164,6 +1184,7 @@ kbd_write64_ami(void *p, uint8_t val) case 0x5c: case 0x5d: case 0x5e: case 0x5f: kbdlog("AMI - alias write to register %08X\n", kbd->command); kbd->want60 = 1; + kbd->timeout = 25000LL * TIMER_USEC; return 0; case 0xa1: /*AMI - get controller version*/ kbdlog("AMI - get controller version\n"); @@ -1229,6 +1250,7 @@ kbd_write64_ami(void *p, uint8_t val) case 0xaf: /*Set extended controller RAM*/ kbdlog("ATkbd: set extended controller RAM\n"); kbd->want60 = 1; + kbd->timeout = 25000LL * TIMER_USEC; kbd->secr_phase = 1; return 0; case 0xb0: case 0xb1: case 0xb2: case 0xb3: @@ -1245,9 +1267,10 @@ kbd_write64_ami(void *p, uint8_t val) return 0; case 0xb8: case 0xb9: case 0xba: case 0xbb: /*Set keyboard controller line P10-P13 (input port bits 0-3) high*/ - if (!PCI || (val > 0xb9)) + if (!PCI || (val > 0xb9)) { kbd->input_port |= (1 << (val & 0x03)); - kbd_adddata(0x00); + kbd_adddata(0x00); + } return 0; case 0xbc: case 0xbd: /*Set keyboard controller line P22-P23 (output port bits 2-3) high*/ @@ -1274,6 +1297,7 @@ kbd_write64_ami(void *p, uint8_t val) case 0xcb: /*AMI - set keyboard mode*/ kbdlog("AMI - set keyboard mode\n"); kbd->want60 = 1; + kbd->timeout = 25000LL * TIMER_USEC; return 0; case 0xef: /*??? - sent by AMI486*/ kbdlog("??? - sent by AMI486\n"); @@ -1343,6 +1367,7 @@ kbd_write64_quadtel(void *p, uint8_t val) case 0xcf: /*??? - sent by MegaPC BIOS*/ kbdlog("??? - sent by MegaPC BIOS\n"); kbd->want60 = 1; + kbd->timeout = 25000LL * TIMER_USEC; return 0; } @@ -1394,6 +1419,7 @@ kbd_write64_toshiba(void *p, uint8_t val) return 0; case 0xb6: /* T3100e: Set colour / mono byte */ kbd->want60 = 1; + kbd->timeout = 25000LL * TIMER_USEC; return 0; case 0xb7: /* T3100e: Emulate PS/2 keyboard - not implemented */ case 0xb8: /* T3100e: Emulate AT keyboard - not implemented */ @@ -1547,6 +1573,7 @@ kbd_write(uint16_t port, uint8_t val, void *priv) case 0xed: /*Set/reset LEDs*/ kbdlog("ATkbd: set/reset leds\n"); kbd->key_wantdata = 1; + kbd->timeout = 25000LL * TIMER_USEC; kbd_adddata_keyboard(0xfa); break; @@ -1562,6 +1589,7 @@ kbd_write(uint16_t port, uint8_t val, void *priv) case 0xf0: /*Get/set scan code set*/ kbdlog("ATkbd: scan code set\n"); kbd->key_wantdata = 1; + kbd->timeout = 25000LL * TIMER_USEC; kbd_adddata_keyboard(0xfa); break; @@ -1576,6 +1604,7 @@ kbd_write(uint16_t port, uint8_t val, void *priv) case 0xf3: /*Set typematic rate/delay*/ kbdlog("ATkbd: set typematic rate/delay\n"); kbd->key_wantdata = 1; + kbd->timeout = 25000LL * TIMER_USEC; kbd_adddata_keyboard(0xfa); break; @@ -1696,6 +1725,7 @@ kbd_write(uint16_t port, uint8_t val, void *priv) case 0x78: case 0x79: case 0x7a: case 0x7b: case 0x7c: case 0x7d: case 0x7e: case 0x7f: kbd->want60 = 1; + kbd->timeout = 25000LL * TIMER_USEC; break; case 0xaa: /*Self-test*/ @@ -1753,11 +1783,13 @@ kbd_write(uint16_t port, uint8_t val, void *priv) case 0xd1: /*Write output port*/ // kbdlog("ATkbd: write output port\n"); kbd->want60 = 1; + kbd->timeout = 25000LL * TIMER_USEC; break; case 0xd2: /*Write keyboard output buffer*/ kbdlog("ATkbd: write keyboard output buffer\n"); kbd->want60 = 1; + kbd->timeout = 25000LL * TIMER_USEC; break; case 0xdd: /* Disable A20 Address Line */ @@ -1864,6 +1896,7 @@ kbd_reset(void *priv) kbd->last_irq = 0; kbd->secr_phase = 0; kbd->key_wantdata = 0; + kbd->timeout = 0LL; keyboard_mode = 0x02 | kbd->dtrans; @@ -1909,6 +1942,9 @@ kbd_init(const device_t *info) timer_add(kbd_pulse_poll, &kbd->pulse_cb, &kbd->pulse_cb, kbd); + timer_add(kbd_timeout_poll, + &kbd->timeout, &kbd->timeout, kbd); + kbd->write60_ven = NULL; kbd->write64_ven = NULL; diff --git a/src/lang/language.h b/src/lang/language.h index e4c060da8..39e3aff6a 100644 --- a/src/lang/language.h +++ b/src/lang/language.h @@ -10,7 +10,7 @@ * * NOTE: FIXME: Strings 2176 and 2193 are same. * - * Version: @(#)language.h 1.0.7 2018/03/07 + * Version: @(#)language.h 1.0.8 2018/05/25 * * Author: Fred N. van Kempen, * @@ -25,17 +25,17 @@ #define IDS_2049 2049 // "86Box Error" #define IDS_2050 2050 // "86Box Fatal Error" #define IDS_2051 2051 // "This will reset 86Box.." -#define IDS_2052 2052 // "DirectDraw Screenshot Error" -#define IDS_2053 2053 // "Invalid number of sectors.." -#define IDS_2054 2054 // "Invalid number of heads.." -#define IDS_2055 2055 // "Invalid number of cylinders.." +#define IDS_2052 2052 // "Use CTRL+ALT+PAGE DOWN.." +#define IDS_2053 2053 // "Speed" +#define IDS_2054 2054 // "ZIP %i (%03i): %ls" +#define IDS_2055 2055 // "ZIP images (*.IM?)\0*.IM..." #define IDS_2056 2056 // "No usable ROM images found!" #define IDS_2057 2057 // "(empty)" -#define IDS_2058 2058 // "(host drive %c:)" +#define IDS_2058 2058 // "ZIP images (*.IM?)\0*.IM..." #define IDS_2059 2059 // "(Turbo)" #define IDS_2060 2060 // "On" #define IDS_2061 2061 // "Off" -#define IDS_2062 2062 // "86Box was unable to find any.." +#define IDS_2062 2062 // "All floppy images (*.DSK..." #define IDS_2063 2063 // "Configured ROM set not avai.." #define IDS_2064 2064 // "Configured video BIOS not.." #define IDS_2065 2065 // "Machine" @@ -49,114 +49,54 @@ #define IDS_2073 2073 // "Floppy drives" #define IDS_2074 2074 // "Other removable devices" #define IDS_2075 2075 // "CD-ROM images (*.ISO;*.CU.." -#define IDS_2076 2076 // "Host CD/DVD Drive (%c:)" +#define IDS_2076 2076 // "Surface-based images (*.8.." #define IDS_2077 2077 // "Click to capture mouse" #define IDS_2078 2078 // "Press F12-F8 to release mouse" #define IDS_2079 2079 // "Press F12-F8 or middle button.." -#define IDS_2080 2080 // "Drive" -#define IDS_2081 2081 // "Location" +#define IDS_2080 2080 // "E&xport to 86F..." +#define IDS_2081 2081 // "Unable to initialize Flui.." #define IDS_2082 2082 // "Bus" #define IDS_2083 2083 // "File" #define IDS_2084 2084 // "C" #define IDS_2085 2085 // "H" #define IDS_2086 2086 // "S" #define IDS_2087 2087 // "MB" -#define IDS_2088 2088 // "Unable to create bitmap file: %s" -#define IDS_2089 2089 // "Enabled" -#define IDS_2090 2090 // "Mute" -#define IDS_2091 2091 // "Type" -#define IDS_2092 2092 // "Bus" -#define IDS_2093 2093 // "DMA" +#define IDS_2088 2088 // "Check BPB" +#define IDS_2089 2089 // "&Image..." +#define IDS_2090 2090 // "&Reload previous image" +#define IDS_2091 2091 // "E&mpty" +#define IDS_2092 2092 // "&Mute" +#define IDS_2093 2093 // "E&ject" #define IDS_2094 2094 // "KB" #define IDS_2095 2095 // "Neither DirectDraw nor Dire.." -#define IDS_2096 2096 // "Slave" -#define IDS_2097 2097 // "SCSI (ID %s, LUN %s)" -#define IDS_2098 2098 // "Adapter Type" -#define IDS_2099 2099 // "Base Address" -#define IDS_2100 2100 // "IRQ" -#define IDS_2101 2101 // "8-bit DMA" -#define IDS_2102 2102 // "16-bit DMA" -#define IDS_2103 2103 // "BIOS" -#define IDS_2104 2104 // "Network Type" -#define IDS_2105 2105 // "Surround Module" -#define IDS_2106 2106 // "MPU-401 Base Address" -#define IDS_2107 2107 // "Use CTRL+ALT+PAGE DOWN.." -#define IDS_2108 2108 // "On-board RAM" -#define IDS_2109 2109 // "Memory Size" -#define IDS_2110 2110 // "Display Type" -#define IDS_2111 2111 // "RGB" -#define IDS_2112 2112 // "Composite" -#define IDS_2113 2113 // "Composite Type" -#define IDS_2114 2114 // "Old" -#define IDS_2115 2115 // "New" -#define IDS_2116 2116 // "RGB Type" -#define IDS_2117 2117 // "Color" -#define IDS_2118 2118 // "Monochrome (Green)" -#define IDS_2119 2119 // "Monochrome (Amber)" -#define IDS_2120 2120 // "Monochrome (Gray)" -#define IDS_2121 2121 // "Color (no brown)" -#define IDS_2122 2122 // "Monochrome (Default)" -#define IDS_2123 2123 // "Snow Emulation" -#define IDS_2124 2124 // "Bilinear Filtering" -#define IDS_2125 2125 // "Dithering" -#define IDS_2126 2126 // "Framebuffer Memory Size" -#define IDS_2127 2127 // "Texture Memory Size" -#define IDS_2128 2128 // "Screen Filter" -#define IDS_2129 2129 // "Render Threads" -#define IDS_2130 2130 // "Recompiler" -#define IDS_2131 2131 // "System Default" -#define IDS_2132 2132 // "%i Wait state(s)" -#define IDS_2133 2133 // "8-bit" -#define IDS_2134 2134 // "Slow 16-bit" -#define IDS_2135 2135 // "Fast 16-bit" -#define IDS_2136 2136 // "Slow VLB/PCI" -#define IDS_2137 2137 // "Mid VLB/PCI" -#define IDS_2138 2138 // "Fast VLB/PCI" -#define IDS_2139 2139 // "PCap failed to set up.." -#define IDS_2140 2140 // "No PCap devices found" -#define IDS_2141 2141 // "Invalid PCap device" -#define IDS_2142 2142 // "&Notify disk change" -#define IDS_2143 2143 // "Type" -#define IDS_2144 2144 // "Standard 2-button joystick(s)" -#define IDS_2145 2145 // "Standard 4-button joystick" -#define IDS_2146 2146 // "Standard 6-button joystick" -#define IDS_2147 2147 // "Standard 8-button joystick" -#define IDS_2148 2148 // "CH Flightstick Pro" -#define IDS_2149 2149 // "Microsoft SideWinder Pad" -#define IDS_2150 2150 // "Thrustmaster Flight Cont.." -#define IDS_2151 2151 // "Disabled" -#define IDS_2152 2152 // "None" -#define IDS_2153 2153 // "Unable to load Accelerators" -#define IDS_2154 2154 // "Unable to register Raw Input" -#define IDS_2155 2155 // "IRQ %i" -#define IDS_2156 2156 // "%" PRIu64 -#define IDS_2157 2157 // "%" PRIu64 " MB (CHS: %".." -#define IDS_2158 2158 // "Floppy %i (%s): %ls" -#define IDS_2159 2159 // "All floppy images (*.0??;*.." -#define IDS_2160 2160 // "Configuration files (*.CF.." -#define IDS_2161 2161 // "&New image..." -#define IDS_2162 2162 // "&Existing image..." -#define IDS_2163 2163 // "Existing image (&Write-pr..." -#define IDS_2164 2164 // "E&ject" -#define IDS_2165 2165 // "&Mute" -#define IDS_2166 2166 // "E&mpty" -#define IDS_2167 2167 // "&Reload previous image" -#define IDS_2168 2168 // "&Image..." -#define IDS_2169 2169 // "Image (&Write-protected)..." -#define IDS_2170 2170 // "Check BPB" -#define IDS_2171 2171 // "Unable to initialize Flui.." -#define IDS_2172 2172 // "E&xport to 86F..." -#define IDS_2173 2173 // "Surface-based images (*.8.." -#define IDS_2174 2174 // "All floppy images (*.DSK..." -#define IDS_2175 2175 // "ZIP images (*.IM?)\0*.IM..." -#define IDS_2176 2176 // "ZIP images (*.IM?)\0*.IM..." -#define IDS_2177 2177 // "ZIP %i (%03i): %ls" -#define IDS_2178 2178 // "Speed" +#define IDS_2096 2096 // "&New image..." +#define IDS_2097 2097 // "&Existing image..." +#define IDS_2098 2098 // "Existing image (&Write-pr..." +#define IDS_2099 2099 // "Default" +#define IDS_2100 2100 // "%i Wait state(s)" +#define IDS_2101 2101 // "Type" +#define IDS_2102 2102 // "PCap failed to set up.." +#define IDS_2103 2103 // "No PCap devices found" +#define IDS_2104 2104 // "Invalid PCap device" +#define IDS_2105 2105 // "Standard 2-button joystick(s)" +#define IDS_2106 2106 // "Standard 4-button joystick" +#define IDS_2107 2107 // "Standard 6-button joystick" +#define IDS_2108 2108 // "Standard 8-button joystick" +#define IDS_2109 2109 // "CH Flightstick Pro" +#define IDS_2110 2110 // "Microsoft SideWinder Pad" +#define IDS_2111 2111 // "Thrustmaster Flight Cont.." +#define IDS_2112 2112 // "None" +#define IDS_2113 2113 // "Unable to load Accelerators" +#define IDS_2114 2114 // "Unable to register Raw Input" +#define IDS_2115 2115 // "%u" +#define IDS_2116 2116 // "%u MB (CHS: %i, %i, %i)" +#define IDS_2117 2117 // "Floppy %i (%s): %ls" +#define IDS_2118 2118 // "All floppy images (*.0??;*.." #define IDS_4096 4096 // "Hard disk (%s)" #define IDS_4097 4097 // "%01i:%01i" #define IDS_4098 4098 // "%i" -#define IDS_4099 4099 // "Disabled" +#define IDS_4099 4099 // "MFM/RLL or ESDI CD-ROM driv.." #define IDS_4100 4100 // "Custom..." #define IDS_4101 4101 // "Custom (large)..." #define IDS_4102 4102 // "Add New Hard Disk" @@ -171,8 +111,6 @@ #define IDS_4111 4111 // "This image exists and will be.." #define IDS_4112 4112 // "Please enter a valid file name" #define IDS_4113 4113 // "Remember to partition and fo.." -#define IDS_4114 4114 // "MFM/RLL or ESDI CD-ROM driv.." -#define IDS_4115 4115 // "Removable disk %i (SCSI): %ls" #define IDS_4352 4352 // "MFM/RLL" #define IDS_4353 4353 // "XT IDE" @@ -193,17 +131,17 @@ #define IDS_5120 5120 // "CD-ROM %i (%s): %s" #define IDS_5376 5376 // "Disabled" -#define IDS_5377 5377 // "" -#define IDS_5378 5378 // "" -#define IDS_5379 5379 // "" +#define IDS_5377 5377 // +#define IDS_5378 5378 // +#define IDS_5379 5379 // #define IDS_5380 5380 // "ATAPI (PIO-only)" #define IDS_5381 5381 // "ATAPI (PIO and DMA)" #define IDS_5382 5382 // "SCSI" #define IDS_5632 5632 // "Disabled" -#define IDS_5633 5633 // "" -#define IDS_5634 5634 // "" -#define IDS_5635 5635 // "" +#define IDS_5633 5633 // +#define IDS_5634 5634 // +#define IDS_5635 5635 // #define IDS_5636 5636 // "ATAPI (PIO-only) (%01i:%01i)" #define IDS_5637 5637 // "ATAPI (PIO and DMA) (%01i:%01i)" #define IDS_5638 5638 // "SCSI (%02i:%02i)" @@ -232,9 +170,9 @@ #define IDS_LANG_ENUS IDS_7168 -#define STR_NUM_2048 131 +#define STR_NUM_2048 71 #define STR_NUM_3072 11 -#define STR_NUM_4096 20 +#define STR_NUM_4096 18 #define STR_NUM_4352 7 #define STR_NUM_4608 7 #define STR_NUM_5120 1 diff --git a/src/machine/m_at_430fx.c b/src/machine/m_at_430fx.c deleted file mode 100644 index 7032a050b..000000000 --- a/src/machine/m_at_430fx.c +++ /dev/null @@ -1,358 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Implementation of the Intel 430FX PCISet chip. - * - * Version: @(#)m_at_430fx.c 1.0.17 2018/04/26 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ -#include -#include -#include -#include -#include -#include "../86box.h" -#include "../mem.h" -#include "../memregs.h" -#include "../rom.h" -#include "../pci.h" -#include "../device.h" -#include "../keyboard.h" -#include "../piix.h" -#include "../intel_flash.h" -#include "../sio.h" -#include "../video/video.h" -#include "../video/vid_cl54xx.h" -#include "../video/vid_s3.h" -#include "machine.h" - - -typedef struct -{ - uint8_t regs[256]; -} i430fx_t; - - -static void -i430fx_map(uint32_t addr, uint32_t size, int state) -{ - switch (state & 3) { - case 0: - mem_set_mem_state(addr, size, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); - break; - case 1: - mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL); - break; - case 2: - mem_set_mem_state(addr, size, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL); - break; - case 3: - mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - break; - } - flushmmucache_nopc(); -} - - -static void -i430fx_write(int func, int addr, uint8_t val, void *priv) -{ - i430fx_t *dev = (i430fx_t *) priv; - - if (func) - return; - - if ((addr >= 0x10) && (addr < 0x4f)) - return; - - switch (addr) { - case 0x00: case 0x01: case 0x02: case 0x03: - case 0x08: case 0x09: case 0x0a: case 0x0b: - case 0x0c: case 0x0e: - return; - - case 0x04: /*Command register*/ - val &= 0x02; - val |= 0x04; - break; - case 0x05: - val = 0; - break; - - case 0x06: /*Status*/ - val = 0; - break; - case 0x07: - val = 0x02; - break; - - case 0x59: /*PAM0*/ - if ((dev->regs[0x59] ^ val) & 0xf0) { - i430fx_map(0xf0000, 0x10000, val >> 4); - shadowbios = (val & 0x10); - } - break; - case 0x5a: /*PAM1*/ - if ((dev->regs[0x5a] ^ val) & 0x0f) - i430fx_map(0xc0000, 0x04000, val & 0xf); - if ((dev->regs[0x5a] ^ val) & 0xf0) - i430fx_map(0xc4000, 0x04000, val >> 4); - break; - case 0x5b: /*PAM2*/ - if ((dev->regs[0x5b] ^ val) & 0x0f) - i430fx_map(0xc8000, 0x04000, val & 0xf); - if ((dev->regs[0x5b] ^ val) & 0xf0) - i430fx_map(0xcc000, 0x04000, val >> 4); - break; - case 0x5c: /*PAM3*/ - if ((dev->regs[0x5c] ^ val) & 0x0f) - i430fx_map(0xd0000, 0x04000, val & 0xf); - if ((dev->regs[0x5c] ^ val) & 0xf0) - i430fx_map(0xd4000, 0x04000, val >> 4); - break; - case 0x5d: /*PAM4*/ - if ((dev->regs[0x5d] ^ val) & 0x0f) - i430fx_map(0xd8000, 0x04000, val & 0xf); - if ((dev->regs[0x5d] ^ val) & 0xf0) - i430fx_map(0xdc000, 0x04000, val >> 4); - break; - case 0x5e: /*PAM5*/ - if ((dev->regs[0x5e] ^ val) & 0x0f) - i430fx_map(0xe0000, 0x04000, val & 0xf); - if ((dev->regs[0x5e] ^ val) & 0xf0) - i430fx_map(0xe4000, 0x04000, val >> 4); - break; - case 0x5f: /*PAM6*/ - if ((dev->regs[0x5f] ^ val) & 0x0f) - i430fx_map(0xe8000, 0x04000, val & 0xf); - if ((dev->regs[0x5f] ^ val) & 0xf0) - i430fx_map(0xec000, 0x04000, val >> 4); - break; - case 0x72: /*SMRAM*/ - if ((dev->regs[0x72] ^ val) & 0x48) - i430fx_map(0xa0000, 0x20000, ((val & 0x48) == 0x48) ? 3 : 0); - break; - } - - dev->regs[addr] = val; -} - - -static uint8_t -i430fx_read(int func, int addr, void *priv) -{ - i430fx_t *dev = (i430fx_t *) priv; - - if (func) - return 0xff; - - return dev->regs[addr]; -} - - -static void -i430fx_reset(void *priv) -{ - i430fx_write(0, 0x59, 0x00, priv); - i430fx_write(0, 0x72, 0x02, priv); -} - - -static void -i430fx_close(void *p) -{ - i430fx_t *i430fx = (i430fx_t *)p; - - free(i430fx); -} - - -static void -*i430fx_init(const device_t *info) -{ - i430fx_t *i430fx = (i430fx_t *) malloc(sizeof(i430fx_t)); - memset(i430fx, 0, sizeof(i430fx_t)); - - i430fx->regs[0x00] = 0x86; i430fx->regs[0x01] = 0x80; /*Intel*/ - i430fx->regs[0x02] = 0x2d; i430fx->regs[0x03] = 0x12; /*SB82437FX-66*/ - i430fx->regs[0x04] = 0x06; i430fx->regs[0x05] = 0x00; - i430fx->regs[0x06] = 0x00; i430fx->regs[0x07] = 0x82; - i430fx->regs[0x08] = 0x00; /*A0 stepping*/ - i430fx->regs[0x09] = 0x00; i430fx->regs[0x0a] = 0x00; i430fx->regs[0x0b] = 0x06; - i430fx->regs[0x52] = 0x40; /*256kb PLB cache*/ - i430fx->regs[0x57] = 0x01; - i430fx->regs[0x60] = i430fx->regs[0x61] = i430fx->regs[0x62] = i430fx->regs[0x63] = 0x02; - i430fx->regs[0x64] = 0x02; - i430fx->regs[0x72] = 0x02; - - pci_add_card(0, i430fx_read, i430fx_write, i430fx); - - return i430fx; -} - - -const device_t i430fx_device = -{ - "Intel SB82437FX-66", - DEVICE_PCI, - 0, - i430fx_init, - i430fx_close, - i430fx_reset, - NULL, - NULL, - NULL, - NULL -}; - - -void -machine_at_p54tp4xe_init(const machine_t *model) -{ - machine_at_common_init(model); - device_add(&keyboard_ps2_pci_device); - - memregs_init(); - pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); - pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0); - device_add(&i430fx_device); - device_add(&piix_device); - fdc37c665_init(); - - device_add(&intel_flash_bxt_device); -} - - -void -machine_at_endeavor_init(const machine_t *model) -{ - machine_at_common_init(model); - device_add(&keyboard_ps2_ami_pci_device); - - memregs_init(); - pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); - pci_register_slot(0x08, PCI_CARD_ONBOARD, 4, 0, 0, 0); - pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x10, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0); - device_add(&i430fx_device); - device_add(&piix_device); - pc87306_init(); - - device_add(&intel_flash_bxt_ami_device); - - if (gfxcard == GFX_INTERNAL) - device_add(&s3_phoenix_trio64_onboard_pci_device); -} - - -const device_t * -at_endeavor_get_device(void) -{ - return &s3_phoenix_trio64_onboard_pci_device; -} - - -void -machine_at_zappa_init(const machine_t *model) -{ - machine_at_common_init(model); - device_add(&keyboard_ps2_ami_pci_device); - - memregs_init(); - pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); - pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x0E, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x0F, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0); - device_add(&i430fx_device); - device_add(&piix_device); - pc87306_init(); - - device_add(&intel_flash_bxt_ami_device); -} - - -void -machine_at_mb500n_init(const machine_t *model) -{ - machine_at_common_init(model); - device_add(&keyboard_ps2_pci_device); - - pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); - pci_register_slot(0x14, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x13, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x12, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x11, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0); - device_add(&i430fx_device); - device_add(&piix_device); - fdc37c665_init(); - - device_add(&intel_flash_bxt_device); -} - - -void -machine_at_president_init(const machine_t *model) -{ - machine_at_common_init(model); - device_add(&keyboard_ps2_pci_device); - - memregs_init(); - pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); - pci_register_slot(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x09, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0); - device_add(&i430fx_device); - device_add(&piix_device); - w83877f_init(); - - device_add(&intel_flash_bxt_device); -} - - -void -machine_at_thor_init(const machine_t *model) -{ - machine_at_common_init(model); - device_add(&keyboard_ps2_ami_pci_device); - - memregs_init(); - pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); - pci_register_slot(0x08, PCI_CARD_ONBOARD, 4, 0, 0, 0); - pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 2, 1); - pci_register_slot(0x10, PCI_CARD_NORMAL, 4, 3, 2, 1); - pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0); - device_add(&i430fx_device); - device_add(&piix_device); - pc87306_init(); - - device_add(&intel_flash_bxt_ami_device); -} diff --git a/src/machine/m_at_430hx.c b/src/machine/m_at_430hx.c deleted file mode 100644 index 026ab44d3..000000000 --- a/src/machine/m_at_430hx.c +++ /dev/null @@ -1,403 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Implementation of the Intel 430HX PCISet chip. - * - * Version: @(#)m_at_430hx.c 1.0.13 2018/04/26 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ -#include -#include -#include -#include -#include -#include "../86box.h" -#include "../io.h" -#include "../mem.h" -#include "../memregs.h" -#include "../pci.h" -#include "../device.h" -#include "../keyboard.h" -#include "../piix.h" -#include "../intel_flash.h" -#include "../sio.h" -#include "machine.h" - - -typedef struct -{ - uint8_t regs[256]; -} i430hx_t; - - -typedef struct -{ - int index; -} acerm3a_t; - - -static void i430hx_map(uint32_t addr, uint32_t size, int state) -{ - switch (state & 3) { - case 0: - mem_set_mem_state(addr, size, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); - break; - case 1: - mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL); - break; - case 2: - mem_set_mem_state(addr, size, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL); - break; - case 3: - mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - break; - } - flushmmucache_nopc(); -} - - -static void -i430hx_write(int func, int addr, uint8_t val, void *priv) -{ - i430hx_t *dev = (i430hx_t *) priv; - - if (func) - return; - - if ((addr >= 0x10) && (addr < 0x4f)) - return; - - switch (addr) { - case 0x00: case 0x01: case 0x02: case 0x03: - case 0x08: case 0x09: case 0x0a: case 0x0b: - case 0x0c: case 0x0e: - return; - - case 0x04: /*Command register*/ - val &= 0x02; - val |= 0x04; - break; - case 0x05: - val = 0; - break; - - case 0x06: /*Status*/ - val = 0; - break; - case 0x07: - val &= 0x80; - val |= 0x02; - break; - - case 0x59: /*PAM0*/ - if ((dev->regs[0x59] ^ val) & 0xf0) { - i430hx_map(0xf0000, 0x10000, val >> 4); - shadowbios = (val & 0x10); - } - break; - case 0x5a: /*PAM1*/ - if ((dev->regs[0x5a] ^ val) & 0x0f) - i430hx_map(0xc0000, 0x04000, val & 0xf); - if ((dev->regs[0x5a] ^ val) & 0xf0) - i430hx_map(0xc4000, 0x04000, val >> 4); - break; - case 0x5b: /*PAM2*/ - if ((dev->regs[0x5b] ^ val) & 0x0f) - i430hx_map(0xc8000, 0x04000, val & 0xf); - if ((dev->regs[0x5b] ^ val) & 0xf0) - i430hx_map(0xcc000, 0x04000, val >> 4); - break; - case 0x5c: /*PAM3*/ - if ((dev->regs[0x5c] ^ val) & 0x0f) - i430hx_map(0xd0000, 0x04000, val & 0xf); - if ((dev->regs[0x5c] ^ val) & 0xf0) - i430hx_map(0xd4000, 0x04000, val >> 4); - break; - case 0x5d: /*PAM4*/ - if ((dev->regs[0x5d] ^ val) & 0x0f) - i430hx_map(0xd8000, 0x04000, val & 0xf); - if ((dev->regs[0x5d] ^ val) & 0xf0) - i430hx_map(0xdc000, 0x04000, val >> 4); - break; - case 0x5e: /*PAM5*/ - if ((dev->regs[0x5e] ^ val) & 0x0f) - i430hx_map(0xe0000, 0x04000, val & 0xf); - if ((dev->regs[0x5e] ^ val) & 0xf0) - i430hx_map(0xe4000, 0x04000, val >> 4); - break; - case 0x5f: /*PAM6*/ - if ((dev->regs[0x5f] ^ val) & 0x0f) - i430hx_map(0xe8000, 0x04000, val & 0xf); - if ((dev->regs[0x5f] ^ val) & 0xf0) - i430hx_map(0xec000, 0x04000, val >> 4); - break; - case 0x72: /*SMRAM*/ - if ((dev->regs[0x72] ^ val) & 0x48) - i430hx_map(0xa0000, 0x20000, ((val & 0x48) == 0x48) ? 3 : 0); - break; - } - - dev->regs[addr] = val; -} - - -static uint8_t -i430hx_read(int func, int addr, void *priv) -{ - i430hx_t *dev = (i430hx_t *) priv; - - if (func) - return 0xff; - - return dev->regs[addr]; -} - - -static void -i430hx_reset(void *priv) -{ - i430hx_write(0, 0x59, 0x00, priv); - i430hx_write(0, 0x72, 0x02, priv); -} - - -static void -i430hx_close(void *p) -{ - i430hx_t *i430hx = (i430hx_t *)p; - - free(i430hx); -} - - -static void -*i430hx_init(const device_t *info) -{ - i430hx_t *i430hx = (i430hx_t *) malloc(sizeof(i430hx_t)); - memset(i430hx, 0, sizeof(i430hx_t)); - - i430hx->regs[0x00] = 0x86; i430hx->regs[0x01] = 0x80; /*Intel*/ - i430hx->regs[0x02] = 0x50; i430hx->regs[0x03] = 0x12; /*82439HX*/ - i430hx->regs[0x04] = 0x06; i430hx->regs[0x05] = 0x00; - i430hx->regs[0x06] = 0x00; i430hx->regs[0x07] = 0x02; - i430hx->regs[0x08] = 0x00; /*A0 stepping*/ - i430hx->regs[0x09] = 0x00; i430hx->regs[0x0a] = 0x00; i430hx->regs[0x0b] = 0x06; - i430hx->regs[0x51] = 0x20; - i430hx->regs[0x52] = 0xB5; /*512kb cache*/ - i430hx->regs[0x59] = 0x40; - i430hx->regs[0x5A] = i430hx->regs[0x5B] = i430hx->regs[0x5C] = i430hx->regs[0x5D] = 0x44; - i430hx->regs[0x5E] = i430hx->regs[0x5F] = 0x44; - i430hx->regs[0x56] = 0x52; /*DRAM control*/ - i430hx->regs[0x57] = 0x01; - i430hx->regs[0x60] = i430hx->regs[0x61] = i430hx->regs[0x62] = i430hx->regs[0x63] = 0x02; - i430hx->regs[0x64] = i430hx->regs[0x65] = i430hx->regs[0x66] = i430hx->regs[0x67] = 0x02; - i430hx->regs[0x68] = 0x11; - i430hx->regs[0x72] = 0x02; - - pci_add_card(0, i430hx_read, i430hx_write, i430hx); - - return i430hx; -} - - -const device_t i430hx_device = -{ - "Intel 82439HX", - DEVICE_PCI, - 0, - i430hx_init, - i430hx_close, - i430hx_reset, - NULL, - NULL, - NULL, - NULL -}; - - -static void -acerm3a_out(uint16_t port, uint8_t val, void *p) -{ - acerm3a_t *dev = (acerm3a_t *) p; - - if (port == 0xea) - dev->index = val; -} - - -static uint8_t -acerm3a_in(uint16_t port, void *p) -{ - acerm3a_t *dev = (acerm3a_t *) p; - - if (port == 0xeb) { - switch (dev->index) { - case 2: - return 0xfd; - } - } - return 0xff; -} - - -static void -acerm3a_close(void *p) -{ - acerm3a_t *dev = (acerm3a_t *)p; - - free(dev); -} - - -static void -*acerm3a_init(const device_t *info) -{ - acerm3a_t *acerm3a = (acerm3a_t *) malloc(sizeof(acerm3a_t)); - memset(acerm3a, 0, sizeof(acerm3a_t)); - - io_sethandler(0x00ea, 0x0002, acerm3a_in, NULL, NULL, acerm3a_out, NULL, NULL, acerm3a); - - return acerm3a; -} - - -const device_t acerm3a_device = -{ - "Acer M3A Register", - 0, - 0, - acerm3a_init, - acerm3a_close, - NULL, - NULL, - NULL, - NULL, - NULL -}; - - -void -machine_at_acerm3a_init(const machine_t *model) -{ - machine_at_common_init(model); - device_add(&keyboard_ps2_pci_device); - - powermate_memregs_init(); - pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); - pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0); - pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x0D, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x0E, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x1F, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x10, PCI_CARD_ONBOARD, 4, 0, 0, 0); - device_add(&i430hx_device); - device_add(&piix3_device); - fdc37c932fr_init(); - device_add(&acerm3a_device); - - device_add(&intel_flash_bxb_device); -} - - -void -machine_at_acerv35n_init(const machine_t *model) -{ - machine_at_common_init(model); - device_add(&keyboard_ps2_pci_device); - - powermate_memregs_init(); - pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); - pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0); - pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x12, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x13, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x14, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); - device_add(&i430hx_device); - device_add(&piix3_device); - fdc37c932fr_init(); - device_add(&acerm3a_device); - - device_add(&intel_flash_bxb_device); -} - - -void -machine_at_ap53_init(const machine_t *model) -{ - machine_at_common_init(model); - device_add(&keyboard_ps2_ami_pci_device); - - memregs_init(); - powermate_memregs_init(); - pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); - pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x12, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x13, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x14, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0); - pci_register_slot(0x06, PCI_CARD_ONBOARD, 1, 2, 3, 4); - device_add(&i430hx_device); - device_add(&piix3_device); - fdc37c669_init(); - - device_add(&intel_flash_bxt_device); -} - - -void -machine_at_p55t2p4_init(const machine_t *model) -{ - machine_at_common_init(model); - device_add(&keyboard_ps2_pci_device); - - memregs_init(); - pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); - pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0); - device_add(&i430hx_device); - device_add(&piix3_device); - w83877f_init(); - - device_add(&intel_flash_bxt_device); -} - - -void -machine_at_p55t2s_init(const machine_t *model) -{ - machine_at_common_init(model); - device_add(&keyboard_ps2_ami_pci_device); - - memregs_init(); - powermate_memregs_init(); - pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); - pci_register_slot(0x12, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x13, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x14, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x11, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0); - device_add(&i430hx_device); - device_add(&piix3_device); - pc87306_init(); - - device_add(&intel_flash_bxt_device); -} diff --git a/src/machine/m_at_430lx_nx.c b/src/machine/m_at_430lx_nx.c deleted file mode 100644 index 4860fed92..000000000 --- a/src/machine/m_at_430lx_nx.c +++ /dev/null @@ -1,272 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Implementation of the Intel 430LX and 430NX PCISet chips. - * - * Version: @(#)m_at_430lx_nx.c 1.0.12 2018/04/26 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ -#include -#include -#include -#include -#include -#include "../86box.h" -#include "../mem.h" -#include "../memregs.h" -#include "../rom.h" -#include "../pci.h" -#include "../device.h" -#include "../keyboard.h" -#include "../intel.h" -#include "../intel_flash.h" -#include "../intel_sio.h" -#include "../sio.h" -#include "machine.h" - - -typedef struct -{ - uint8_t regs[256]; -} i430lx_nx_t; - - -static void -i430lx_nx_map(uint32_t addr, uint32_t size, int state) -{ - switch (state & 3) { - case 0: - mem_set_mem_state(addr, size, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); - break; - case 1: - mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL); - break; - case 2: - mem_set_mem_state(addr, size, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL); - break; - case 3: - mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - break; - } - flushmmucache_nopc(); -} - - -static void -i430lx_nx_write(int func, int addr, uint8_t val, void *priv) -{ - i430lx_nx_t *dev = (i430lx_nx_t *) priv; - - if (func) - return; - - if ((addr >= 0x10) && (addr < 0x4f)) - return; - - switch (addr) { - case 0x00: case 0x01: case 0x02: case 0x03: - case 0x08: case 0x09: case 0x0a: case 0x0b: - case 0x0c: case 0x0e: - return; - - case 0x04: /*Command register*/ - val &= 0x42; - val |= 0x04; - break; - case 0x05: - val &= 0x01; - break; - - case 0x06: /*Status*/ - val = 0; - break; - case 0x07: - val = 0x02; - break; - - case 0x59: /*PAM0*/ - if ((dev->regs[0x59] ^ val) & 0xf0) { - i430lx_nx_map(0xf0000, 0x10000, val >> 4); - shadowbios = (val & 0x10); - } - break; - case 0x5a: /*PAM1*/ - if ((dev->regs[0x5a] ^ val) & 0x0f) - i430lx_nx_map(0xc0000, 0x04000, val & 0xf); - if ((dev->regs[0x5a] ^ val) & 0xf0) - i430lx_nx_map(0xc4000, 0x04000, val >> 4); - break; - case 0x5b: /*PAM2*/ - if ((dev->regs[0x5b] ^ val) & 0x0f) - i430lx_nx_map(0xc8000, 0x04000, val & 0xf); - if ((dev->regs[0x5b] ^ val) & 0xf0) - i430lx_nx_map(0xcc000, 0x04000, val >> 4); - break; - case 0x5c: /*PAM3*/ - if ((dev->regs[0x5c] ^ val) & 0x0f) - i430lx_nx_map(0xd0000, 0x04000, val & 0xf); - if ((dev->regs[0x5c] ^ val) & 0xf0) - i430lx_nx_map(0xd4000, 0x04000, val >> 4); - break; - case 0x5d: /*PAM4*/ - if ((dev->regs[0x5d] ^ val) & 0x0f) - i430lx_nx_map(0xd8000, 0x04000, val & 0xf); - if ((dev->regs[0x5d] ^ val) & 0xf0) - i430lx_nx_map(0xdc000, 0x04000, val >> 4); - break; - case 0x5e: /*PAM5*/ - if ((dev->regs[0x5e] ^ val) & 0x0f) - i430lx_nx_map(0xe0000, 0x04000, val & 0xf); - if ((dev->regs[0x5e] ^ val) & 0xf0) - i430lx_nx_map(0xe4000, 0x04000, val >> 4); - break; - case 0x5f: /*PAM6*/ - if ((dev->regs[0x5f] ^ val) & 0x0f) - i430lx_nx_map(0xe8000, 0x04000, val & 0xf); - if ((dev->regs[0x5f] ^ val) & 0xf0) - i430lx_nx_map(0xec000, 0x04000, val >> 4); - break; - } - - dev->regs[addr] = val; -} - - -static uint8_t -i430lx_nx_read(int func, int addr, void *priv) -{ - i430lx_nx_t *dev = (i430lx_nx_t *) priv; - - if (func) - return 0xff; - - return dev->regs[addr]; -} - - -static void -i430lx_nx_reset(void *priv) -{ - i430lx_nx_write(0, 0x59, 0x00, priv); -} - - -static void -i430lx_nx_close(void *p) -{ - i430lx_nx_t *i430lx_nx = (i430lx_nx_t *)p; - - free(i430lx_nx); -} - - -static void -*i430lx_nx_init(const device_t *info) -{ - i430lx_nx_t *i430lx_nx = (i430lx_nx_t *) malloc(sizeof(i430lx_nx_t)); - memset(i430lx_nx, 0, sizeof(i430lx_nx_t)); - - i430lx_nx->regs[0x00] = 0x86; i430lx_nx->regs[0x01] = 0x80; /*Intel*/ - i430lx_nx->regs[0x02] = 0xa3; i430lx_nx->regs[0x03] = 0x04; /*82434LX/NX*/ - i430lx_nx->regs[0x04] = 0x06; i430lx_nx->regs[0x05] = 0x00; - i430lx_nx->regs[0x06] = 0x00; i430lx_nx->regs[0x07] = 0x02; - i430lx_nx->regs[0x09] = 0x00; i430lx_nx->regs[0x0a] = 0x00; i430lx_nx->regs[0x0b] = 0x06; - i430lx_nx->regs[0x57] = 0x31; - i430lx_nx->regs[0x60] = i430lx_nx->regs[0x61] = i430lx_nx->regs[0x62] = i430lx_nx->regs[0x63] = 0x02; - i430lx_nx->regs[0x64] = 0x02; - - if (info->local == 1) { - i430lx_nx->regs[0x08] = 0x10; /*A0 stepping*/ - i430lx_nx->regs[0x50] = 0xA0; - i430lx_nx->regs[0x52] = 0x44; /*256kb PLB cache*/ - i430lx_nx->regs[0x66] = i430lx_nx->regs[0x67] = 0x02; - } else { - i430lx_nx->regs[0x08] = 0x03; /*A3 stepping*/ - i430lx_nx->regs[0x50] = 0x80; - i430lx_nx->regs[0x52] = 0x40; /*256kb PLB cache*/ - } - - pci_add_card(0, i430lx_nx_read, i430lx_nx_write, i430lx_nx); - - return i430lx_nx; -} - - -const device_t i430lx_device = -{ - "Intel 82434LX", - DEVICE_PCI, - 0, - i430lx_nx_init, - i430lx_nx_close, - i430lx_nx_reset, - NULL, - NULL, - NULL, - NULL -}; - - -const device_t i430nx_device = -{ - "Intel 82434NX", - DEVICE_PCI, - 1, - i430lx_nx_init, - i430lx_nx_close, - i430lx_nx_reset, - NULL, - NULL, - NULL, - NULL -}; - - -static void -machine_at_premiere_common_init(const machine_t *model) -{ - machine_at_common_init(model); - device_add(&keyboard_ps2_ami_pci_device); - - memregs_init(); - pci_init(PCI_CONFIG_TYPE_2); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); - pci_register_slot(0x01, PCI_CARD_SPECIAL, 0, 0, 0, 0); - pci_register_slot(0x06, PCI_CARD_NORMAL, 3, 2, 1, 4); - pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 1, 3, 4); - pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 3, 2, 4); - pci_register_slot(0x02, PCI_CARD_SPECIAL, 0, 0, 0, 0); - device_add(&sio_device); - fdc37c665_init(); - intel_batman_init(); - - device_add(&intel_flash_bxt_ami_device); -} - - -void -machine_at_batman_init(const machine_t *model) -{ - machine_at_premiere_common_init(model); - - device_add(&i430lx_device); -} - - -void -machine_at_plato_init(const machine_t *model) -{ - machine_at_premiere_common_init(model); - - device_add(&i430nx_device); -} diff --git a/src/machine/m_at_430vx.c b/src/machine/m_at_430vx.c deleted file mode 100644 index 077b54e13..000000000 --- a/src/machine/m_at_430vx.c +++ /dev/null @@ -1,285 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Implementation of the Intel 430VX PCISet chip. - * - * Version: @(#)m_at_430vx.c 1.0.13 2018/04/26 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ -#include -#include -#include -#include -#include -#include "../86box.h" -#include "../device.h" -#include "../keyboard.h" -#include "../io.h" -#include "../pci.h" -#include "../mem.h" -#include "../memregs.h" -#include "../piix.h" -#include "../intel_flash.h" -#include "../sio.h" -#include "machine.h" - - -typedef struct -{ - uint8_t regs[256]; -} i430vx_t; - - -static void -i430vx_map(uint32_t addr, uint32_t size, int state) -{ - switch (state & 3) { - case 0: - mem_set_mem_state(addr, size, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); - break; - case 1: - mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL); - break; - case 2: - mem_set_mem_state(addr, size, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL); - break; - case 3: - mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - break; - } - flushmmucache_nopc(); -} - - -static void -i430vx_write(int func, int addr, uint8_t val, void *priv) -{ - i430vx_t *dev = (i430vx_t *) priv; - - if (func) - return; - - if ((addr >= 0x10) && (addr < 0x4f)) - return; - - switch (addr) { - case 0x00: case 0x01: case 0x02: case 0x03: - case 0x08: case 0x09: case 0x0a: case 0x0b: - case 0x0c: case 0x0e: - return; - - case 0x04: /*Command register*/ - val &= 0x02; - val |= 0x04; - break; - case 0x05: - val = 0; - break; - - case 0x06: /*Status*/ - val = 0; - break; - case 0x07: - val &= 0x80; - val |= 0x02; - break; - - case 0x59: /*PAM0*/ - if ((dev->regs[0x59] ^ val) & 0xf0) { - i430vx_map(0xf0000, 0x10000, val >> 4); - shadowbios = (val & 0x10); - } - break; - case 0x5a: /*PAM1*/ - if ((dev->regs[0x5a] ^ val) & 0x0f) - i430vx_map(0xc0000, 0x04000, val & 0xf); - if ((dev->regs[0x5a] ^ val) & 0xf0) - i430vx_map(0xc4000, 0x04000, val >> 4); - break; - case 0x5b: /*PAM2*/ - if ((dev->regs[0x5b] ^ val) & 0x0f) - i430vx_map(0xc8000, 0x04000, val & 0xf); - if ((dev->regs[0x5b] ^ val) & 0xf0) - i430vx_map(0xcc000, 0x04000, val >> 4); - break; - case 0x5c: /*PAM3*/ - if ((dev->regs[0x5c] ^ val) & 0x0f) - i430vx_map(0xd0000, 0x04000, val & 0xf); - if ((dev->regs[0x5c] ^ val) & 0xf0) - i430vx_map(0xd4000, 0x04000, val >> 4); - break; - case 0x5d: /*PAM4*/ - if ((dev->regs[0x5d] ^ val) & 0x0f) - i430vx_map(0xd8000, 0x04000, val & 0xf); - if ((dev->regs[0x5d] ^ val) & 0xf0) - i430vx_map(0xdc000, 0x04000, val >> 4); - break; - case 0x5e: /*PAM5*/ - if ((dev->regs[0x5e] ^ val) & 0x0f) - i430vx_map(0xe0000, 0x04000, val & 0xf); - if ((dev->regs[0x5e] ^ val) & 0xf0) - i430vx_map(0xe4000, 0x04000, val >> 4); - break; - case 0x5f: /*PAM6*/ - if ((dev->regs[0x5f] ^ val) & 0x0f) - i430vx_map(0xe8000, 0x04000, val & 0xf); - if ((dev->regs[0x5f] ^ val) & 0xf0) - i430vx_map(0xec000, 0x04000, val >> 4); - break; - case 0x72: /*SMRAM*/ - if ((dev->regs[0x72] ^ val) & 0x48) - i430vx_map(0xa0000, 0x20000, ((val & 0x48) == 0x48) ? 3 : 0); - break; - } - - dev->regs[addr] = val; -} - - -static uint8_t i430vx_read(int func, int addr, void *priv) -{ - i430vx_t *dev = (i430vx_t *) priv; - - if (func) - return 0xff; - - return dev->regs[addr]; -} - - -static void -i430vx_reset(void *priv) -{ - i430vx_write(0, 0x59, 0x00, priv); - i430vx_write(0, 0x72, 0x02, priv); -} - - -static void -i430vx_close(void *p) -{ - i430vx_t *i430vx = (i430vx_t *)p; - - free(i430vx); -} - - -static void -*i430vx_init(const device_t *info) -{ - i430vx_t *i430vx = (i430vx_t *) malloc(sizeof(i430vx_t)); - memset(i430vx, 0, sizeof(i430vx_t)); - - i430vx->regs[0x00] = 0x86; i430vx->regs[0x01] = 0x80; /*Intel*/ - i430vx->regs[0x02] = 0x30; i430vx->regs[0x03] = 0x70; /*82437VX*/ - i430vx->regs[0x04] = 0x06; i430vx->regs[0x05] = 0x00; - i430vx->regs[0x06] = 0x00; i430vx->regs[0x07] = 0x02; - i430vx->regs[0x08] = 0x00; /*A0 stepping*/ - i430vx->regs[0x09] = 0x00; i430vx->regs[0x0a] = 0x00; i430vx->regs[0x0b] = 0x06; - i430vx->regs[0x52] = 0x42; /*256kb PLB cache*/ - i430vx->regs[0x53] = 0x14; - i430vx->regs[0x56] = 0x52; /*DRAM control*/ - i430vx->regs[0x57] = 0x01; - i430vx->regs[0x60] = i430vx->regs[0x61] = i430vx->regs[0x62] = i430vx->regs[0x63] = 0x02; - i430vx->regs[0x64] = 0x02; - i430vx->regs[0x67] = 0x11; - i430vx->regs[0x69] = 0x03; - i430vx->regs[0x70] = 0x20; - i430vx->regs[0x72] = 0x02; - i430vx->regs[0x74] = 0x0e; - i430vx->regs[0x78] = 0x23; - - pci_add_card(0, i430vx_read, i430vx_write, i430vx); - - return i430vx; -} - - -const device_t i430vx_device = -{ - "Intel 82437VX", - DEVICE_PCI, - 0, - i430vx_init, - i430vx_close, - i430vx_reset, - NULL, - NULL, - NULL, - NULL -}; - - -void -machine_at_p55tvp4_init(const machine_t *model) -{ - machine_at_common_init(model); - device_add(&keyboard_ps2_pci_device); - - memregs_init(); - pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); - pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0); - device_add(&i430vx_device); - device_add(&piix3_device); - w83877f_init(); - - device_add(&intel_flash_bxt_device); -} - - -void -machine_at_i430vx_init(const machine_t *model) -{ - machine_at_common_init(model); - device_add(&keyboard_ps2_pci_device); - - memregs_init(); - pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); - pci_register_slot(0x11, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x12, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x14, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x13, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0); - device_add(&i430vx_device); - device_add(&piix3_device); - um8669f_init(); - - device_add(&intel_flash_bxt_device); -} - - -void -machine_at_p55va_init(const machine_t *model) -{ - machine_at_common_init(model); - device_add(&keyboard_ps2_pci_device); - - pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); - pci_register_slot(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x09, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0); - device_add(&i430vx_device); - device_add(&piix3_device); - fdc37c932fr_init(); - - device_add(&intel_flash_bxt_device); -} diff --git a/src/machine/m_at_440fx.c b/src/machine/m_at_440fx.c deleted file mode 100644 index 79dd78625..000000000 --- a/src/machine/m_at_440fx.c +++ /dev/null @@ -1,271 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Implementation of the Intel 440FX PCISet chip. - * - * Version: @(#)m_at_440fx.c 1.0.13 2018/04/26 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ -#include -#include -#include -#include -#include -#include "../86box.h" -#include "../io.h" -#include "../pci.h" -#include "../mem.h" -#include "../memregs.h" -#include "../device.h" -#include "../keyboard.h" -#include "../piix.h" -#include "../intel_flash.h" -#include "../sio.h" -#include "machine.h" - - -typedef struct -{ - uint8_t regs[256]; -} i440fx_t; - - -static void -i440fx_map(uint32_t addr, uint32_t size, int state) -{ - switch (state & 3) { - case 0: - mem_set_mem_state(addr, size, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); - break; - case 1: - mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL); - break; - case 2: - mem_set_mem_state(addr, size, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL); - break; - case 3: - mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - break; - } - flushmmucache_nopc(); -} - - -static void -i440fx_write(int func, int addr, uint8_t val, void *priv) -{ - i440fx_t *dev = (i440fx_t *) priv; - - if (func) - return; - - if ((addr >= 0x10) && (addr < 0x4f)) - return; - - switch (addr) { - case 0x00: case 0x01: case 0x02: case 0x03: - case 0x08: case 0x09: case 0x0a: case 0x0b: - case 0x0c: case 0x0e: - return; - - case 0x04: /*Command register*/ - val &= 0x02; - val |= 0x04; - break; - case 0x05: - val = 0; - break; - - case 0x06: /*Status*/ - val = 0; - break; - case 0x07: - val &= 0x80; - val |= 0x02; - break; - - case 0x59: /*PAM0*/ - if ((dev->regs[0x59] ^ val) & 0xf0) { - i440fx_map(0xf0000, 0x10000, val >> 4); - shadowbios = (val & 0x10); - } - break; - case 0x5a: /*PAM1*/ - if ((dev->regs[0x5a] ^ val) & 0x0f) - i440fx_map(0xc0000, 0x04000, val & 0xf); - if ((dev->regs[0x5a] ^ val) & 0xf0) - i440fx_map(0xc4000, 0x04000, val >> 4); - break; - case 0x5b: /*PAM2*/ - if ((dev->regs[0x5b] ^ val) & 0x0f) - i440fx_map(0xc8000, 0x04000, val & 0xf); - if ((dev->regs[0x5b] ^ val) & 0xf0) - i440fx_map(0xcc000, 0x04000, val >> 4); - break; - case 0x5c: /*PAM3*/ - if ((dev->regs[0x5c] ^ val) & 0x0f) - i440fx_map(0xd0000, 0x04000, val & 0xf); - if ((dev->regs[0x5c] ^ val) & 0xf0) - i440fx_map(0xd4000, 0x04000, val >> 4); - break; - case 0x5d: /*PAM4*/ - if ((dev->regs[0x5d] ^ val) & 0x0f) - i440fx_map(0xd8000, 0x04000, val & 0xf); - if ((dev->regs[0x5d] ^ val) & 0xf0) - i440fx_map(0xdc000, 0x04000, val >> 4); - break; - case 0x5e: /*PAM5*/ - if ((dev->regs[0x5e] ^ val) & 0x0f) - i440fx_map(0xe0000, 0x04000, val & 0xf); - if ((dev->regs[0x5e] ^ val) & 0xf0) - i440fx_map(0xe4000, 0x04000, val >> 4); - break; - case 0x5f: /*PAM6*/ - if ((dev->regs[0x5f] ^ val) & 0x0f) - i440fx_map(0xe8000, 0x04000, val & 0xf); - if ((dev->regs[0x5f] ^ val) & 0xf0) - i440fx_map(0xec000, 0x04000, val >> 4); - break; - case 0x72: /*SMRAM*/ - if ((dev->regs[0x72] ^ val) & 0x48) - i440fx_map(0xa0000, 0x20000, ((val & 0x48) == 0x48) ? 3 : 0); - break; - } - - dev->regs[addr] = val; -} - - -static uint8_t -i440fx_read(int func, int addr, void *priv) -{ - i440fx_t *dev = (i440fx_t *) priv; - - if (func) - return 0xff; - - return dev->regs[addr]; -} - - -static void -i440fx_reset(void *priv) -{ - i440fx_write(0, 0x59, 0x00, priv); - i440fx_write(0, 0x72, 0x02, priv); -} - - -static void -i440fx_close(void *p) -{ - i440fx_t *i440fx = (i440fx_t *)p; - - free(i440fx); -} - - -static void -*i440fx_init(const device_t *info) -{ - i440fx_t *i440fx = (i440fx_t *) malloc(sizeof(i440fx_t)); - memset(i440fx, 0, sizeof(i440fx_t)); - - i440fx->regs[0x00] = 0x86; i440fx->regs[0x01] = 0x80; /*Intel*/ - i440fx->regs[0x02] = 0x37; i440fx->regs[0x03] = 0x12; /*82441FX*/ - i440fx->regs[0x04] = 0x03; i440fx->regs[0x05] = 0x01; - i440fx->regs[0x06] = 0x80; i440fx->regs[0x07] = 0x00; - i440fx->regs[0x08] = 0x02; /*A0 stepping*/ - i440fx->regs[0x09] = 0x00; i440fx->regs[0x0a] = 0x00; i440fx->regs[0x0b] = 0x06; - i440fx->regs[0x0d] = 0x00; - i440fx->regs[0x0f] = 0x00; - i440fx->regs[0x2c] = 0xf4; - i440fx->regs[0x2d] = 0x1a; - i440fx->regs[0x2e] = 0x00; - i440fx->regs[0x2f] = 0x11; - i440fx->regs[0x50] = 0x00; - i440fx->regs[0x51] = 0x01; - i440fx->regs[0x52] = i440fx->regs[0x54] = i440fx->regs[0x55] = i440fx->regs[0x56] = 0x00; - i440fx->regs[0x53] = 0x80; - i440fx->regs[0x57] = 0x01; - i440fx->regs[0x58] = 0x10; - i440fx->regs[0x5a] = i440fx->regs[0x5b] = i440fx->regs[0x5c] = i440fx->regs[0x5d] = 0x11; - i440fx->regs[0x5e] = 0x11; - i440fx->regs[0x5f] = 0x31; - i440fx->regs[0x72] = 0x02; - - pci_add_card(0, i440fx_read, i440fx_write, i440fx); - - return i440fx; -} - - -const device_t i440fx_device = -{ - "Intel 82441FX", - DEVICE_PCI, - 0, - i440fx_init, - i440fx_close, - i440fx_reset, - NULL, - NULL, - NULL, - NULL -}; - - -void -machine_at_i440fx_init(const machine_t *model) -{ - machine_at_common_init(model); - device_add(&keyboard_ps2_pci_device); - - memregs_init(); - pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); - pci_register_slot(0x0E, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x0D, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x0C, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x0A, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0); - device_add(&i440fx_device); - device_add(&piix3_device); - fdc37c665_init(); - - device_add(&intel_flash_bxt_device); -} - - -void -machine_at_s1668_init(const machine_t *model) -{ - machine_at_common_init(model); - device_add(&keyboard_ps2_ami_pci_device); - - memregs_init(); - pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); - pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0); - pci_register_slot(0x0E, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x0D, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x0C, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x0A, PCI_CARD_NORMAL, 1, 2, 3, 4); - device_add(&i440fx_device); - device_add(&piix3_device); - fdc37c665_init(); - - device_add(&intel_flash_bxt_device); -} diff --git a/src/machine/m_europc.c b/src/machine/m_europc.c index 8a6f94d43..7e08d3109 100644 --- a/src/machine/m_europc.c +++ b/src/machine/m_europc.c @@ -203,7 +203,7 @@ europc_log(const char *fmt, ...) * FIXME: should we mark NVR as dirty? */ static void -rtc_tick(nvr_t *nvr) +europc_rtc_tick(nvr_t *nvr) { uint8_t *regs; int mon, yr; @@ -757,7 +757,7 @@ machine_europc_init(const machine_t *model) /* Set up any local handlers here. */ europc.nvr.reset = rtc_reset; europc.nvr.start = rtc_start; - europc.nvr.tick = rtc_tick; + europc.nvr.tick = europc_rtc_tick; /* Initialize the actual NVR. */ nvr_init(&europc.nvr); diff --git a/src/machine/machine.c b/src/machine/machine.c index ddfc5d119..9396de0ba 100644 --- a/src/machine/machine.c +++ b/src/machine/machine.c @@ -93,7 +93,7 @@ machine_common_init(const machine_t *model) pit_init(); cpu_set(); - if (AT) + if (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type >= CPU_286) setrtcconst(machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].rspeed); else setrtcconst(14318184.0); diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 864d81a01..c1f89623b 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -11,7 +11,7 @@ * NOTES: OpenAT wip for 286-class machine with open BIOS. * PS2_M80-486 wip, pending receipt of TRM's for machine. * - * Version: @(#)machine_table.c 1.0.29 2018/05/10 + * Version: @(#)machine_table.c 1.0.30 2018/05/26 * * Authors: Sarah Walker, * Miran Grca, @@ -88,7 +88,7 @@ const machine_t machines[] = { { "[386SX ISA] AMI 386SX clone", ROM_AMI386SX, "ami386", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 512,16384, 128, 127, machine_at_headland_init, NULL }, { "[386SX ISA] Amstrad MegaPC", ROM_MEGAPC, "megapc", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_VIDEO | MACHINE_HDC, 1, 16, 1, 127, machine_at_wd76c10_init, NULL }, - { "[386SX ISA] Award 386SX clone", ROM_AWARD386SX_OPTI495, "award386sx", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 127, machine_at_opti495_init, NULL }, + { "[386SX ISA] Award 386SX clone", ROM_AWARD386SX_OPTI495, "award386sx", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 127, machine_at_opti495_init, NULL }, { "[386SX ISA] DTK 386SX clone", ROM_DTK386, "dtk386", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 512,16384, 128, 127, machine_at_neat_init, NULL }, { "[386SX ISA] IBM PS/1 model 2121", ROM_IBMPS1_2121, "ibmps1_2121", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 1, 6, 1, 63, machine_ps1_m2121_init, NULL }, { "[386SX ISA] IBM PS/1 m.2121+ISA", ROM_IBMPS1_2121_ISA, "ibmps1_2121_isa", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 1, 6, 1, 63, machine_ps1_m2121_init, NULL }, @@ -98,7 +98,7 @@ const machine_t machines[] = { { "[386DX ISA] AMI 386DX clone", ROM_AMI386DX_OPTI495, "ami386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 127, machine_at_opti495_ami_init, NULL }, { "[386DX ISA] Amstrad MegaPC 386DX", ROM_MEGAPCDX, "megapcdx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 1, 32, 1, 127, machine_at_wd76c10_init, NULL }, - { "[386DX ISA] Award 386DX clone", ROM_AWARD386DX_OPTI495, "award386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 127, machine_at_opti495_init, NULL }, + { "[386DX ISA] Award 386DX clone", ROM_AWARD386DX_OPTI495, "award386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 127, machine_at_opti495_init, NULL }, { "[386DX ISA] MR 386DX clone", ROM_MR386DX_OPTI495, "mr386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 127, machine_at_opti495_ami_init, NULL }, #if defined(DEV_BRANCH) && defined(USE_PORTABLE3) { "[386DX ISA] Compaq Portable III (386)", ROM_PORTABLEIII386, "portableiii386", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_AT | MACHINE_HDC | MACHINE_VIDEO, 1, 14, 1, 127, machine_at_compaq_init, NULL }, @@ -123,7 +123,6 @@ const machine_t machines[] = { { "[Socket 5 NX] Intel Premiere/PCI II", ROM_PLATO, "plato", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_plato_init, NULL }, { "[Socket 5 FX] ASUS P/I-P54TP4XE", ROM_P54TP4XE, "p54tp4xe", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 8, 128, 8, 127, machine_at_p54tp4xe_init, NULL }, - { "[Socket 5 FX] Intel Advanced/EV", ROM_ENDEAVOR, "endeavor", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 8, 128, 8, 127, machine_at_endeavor_init, at_endeavor_get_device }, { "[Socket 5 FX] Intel Advanced/ZP", ROM_ZAPPA, "zappa", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_zappa_init, NULL }, { "[Socket 5 FX] PC Partner MB500N", ROM_MB500N, "mb500n", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 8, 128, 8, 127, machine_at_mb500n_init, NULL }, { "[Socket 5 FX] President Award 430FX PCI",ROM_PRESIDENT, "president", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 8, 128, 8, 127, machine_at_president_init, NULL }, @@ -132,6 +131,7 @@ const machine_t machines[] = { #if defined(DEV_BRANCH) && defined(USE_MRTHOR) { "[Socket 7 FX] MR Intel Advanced/ATX", ROM_MRTHOR, "mrthor", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_thor_init, NULL }, #endif + { "[Socket 7 FX] Intel Advanced/EV", ROM_ENDEAVOR, "endeavor", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 8, 128, 8, 127, machine_at_endeavor_init, at_endeavor_get_device }, { "[Socket 7 FX] Packard Bell PB640", ROM_PB640, "pb640", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 8, 128, 8, 127, machine_at_pb640_init, NULL }, { "[Socket 7 HX] Acer M3a", ROM_ACERM3A, "acerm3a", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 192, 8, 127, machine_at_acerm3a_init, NULL }, @@ -147,7 +147,6 @@ const machine_t machines[] = { { "[Socket 5 NX] Intel Premiere/PCI II", ROM_PLATO, "plato", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_plato_init, NULL }, { "[Socket 5 FX] ASUS P/I-P54TP4XE", ROM_P54TP4XE, "p54tp4xe", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 8, 128, 8, 127, machine_at_p54tp4xe_init, NULL }, - { "[Socket 5 FX] Intel Advanced/EV", ROM_ENDEAVOR, "endeavor", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 8, 128, 8, 127, machine_at_endeavor_init, at_endeavor_get_device }, { "[Socket 5 FX] Intel Advanced/ZP", ROM_ZAPPA, "zappa", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_zappa_init, NULL }, { "[Socket 5 FX] PC Partner MB500N", ROM_MB500N, "mb500n", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 8, 128, 8, 127, machine_at_mb500n_init, NULL }, { "[Socket 5 FX] President Award 430FX PCI",ROM_PRESIDENT, "president", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 8, 128, 8, 127, machine_at_president_init, NULL }, @@ -156,6 +155,7 @@ const machine_t machines[] = { #if defined(DEV_BRANCH) && defined(USE_MRTHOR) { "[Socket 7 FX] MR Intel Advanced/ATX", ROM_MRTHOR, "mrthor", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_thor_init, NULL }, #endif + { "[Socket 7 FX] Intel Advanced/EV", ROM_ENDEAVOR, "endeavor", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 8, 128, 8, 127, machine_at_endeavor_init, at_endeavor_get_device }, { "[Socket 7 FX] Packard Bell PB640", ROM_PB640, "pb640", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 8, 128, 8, 127, machine_at_pb640_init, NULL }, { "[Socket 7 HX] Acer M3a", ROM_ACERM3A, "acerm3a", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 192, 8, 127, machine_at_acerm3a_init, NULL }, diff --git a/src/mouse.h b/src/mouse.h index 4d402fa0a..341646178 100644 --- a/src/mouse.h +++ b/src/mouse.h @@ -73,6 +73,8 @@ extern int mouse_get_type(int mouse); extern int mouse_get_ndev(void); extern int mouse_get_buttons(void); +extern void mouse_clear_data(void *priv); + #ifdef __cplusplus } #endif diff --git a/src/mouse_bus.c b/src/mouse_bus.c index c64f5c433..e60a7063b 100644 --- a/src/mouse_bus.c +++ b/src/mouse_bus.c @@ -14,45 +14,50 @@ * although alike enough to be handled in the same driver, they * are not the same. * - * This code is based on my Minix driver for the Logitech(-mode) - * interface. Although that driver blindly took IRQ5, the board - * seems to be able to tell the driver what IRQ it is set for. - * When testing on MS-DOS (6.22), the 'mouse.exe' driver did not - * want to start, and only after disassembling it and inspecting - * the code it was discovered that driver actually does use the - * IRQ reporting feature. In a really, really weird way, too: it - * sets up the board, and then reads the CTRL register which is - * supposed to return that IRQ value. Depending on whether or - * not the FREEZE bit is set, it has to return either the two's - * complemented (negated) value, or (if clear) just the value. - * The mouse.com driver reads both values 10,000 times, and - * then makes up its mind. Maybe an effort to 'debounce' the - * reading of the DIP switches? Oh-well. + * NOTES: Ported from Bochs with extensive modifications per testing + * of the real hardware, testing of drivers, and the old code. * - * NOTES: Verified with: - * AMI WinBIOS 486 (5A, no IRQ detect, OK, IRQ5 only) - * Microsoft Mouse.com V2.00 (DOS V6.22, 5A, OK) - * Microsoft Mouse.exe V9.1 (DOS V6.22, A5, OK) - * Logitech LMouse.com V6.02 (DOS V6.22) - * Logitech LMouse.com V6.43 (DOS V6.22) - * Microsoft WfW V3.11 on DOS V6.22 - * GEOS V1.0 (OK, IRQ5 only) - * GEOS V2.0 (OK, IRQ5 only) - * Microsoft Windows 95 OSR2 - * Microsoft Windows 98 SE + * Logitech Bus Mouse verified with: + * Logitech LMouse.com 3.12 + * Logitech LMouse.com 3.30 + * Logitech LMouse.com 3.41 + * Logitech LMouse.com 3.42 + * Logitech LMouse.com 4.00 + * Logitech LMouse.com 5.00 + * Logitech LMouse.com 6.00 + * Logitech LMouse.com 6.02 Beta + * Logitech LMouse.com 6.02 + * Logitech LMouse.com 6.12 + * Logitech LMouse.com 6.20 + * Logitech LMouse.com 6.23 + * Logitech LMouse.com 6.30 + * Logitech LMouse.com 6.31E + * Logitech LMouse.com 6.34 + * Logitech Mouse.exe 6.40 + * Logitech Mouse.exe 6.41 + * Logitech Mouse.exe 6.44 + * Logitech Mouse.exe 6.46 + * Logitech Mouse.exe 6.50 + * Microsoft Mouse.com 2.00 + * Microsoft Mouse.sys 3.00 + * Microsoft Windows 1.00 DR5 + * Microsoft Windows 3.10.026 * Microsoft Windows NT 3.1 - * Microsoft Windows NT 3.51 + * Microsoft Windows 95 * - * The polling frequency for InPort controllers has to - * be changed to programmable. Microsoft uses 30Hz, - * but ATIXL ports are programmable 30-200Hz. + * InPort verified with: + * Logitech LMouse.com 6.12 + * Logitech LMouse.com 6.41 + * Microsoft Windows NT 3.1 + * Microsoft Windows 98 SE * - * Based on an early driver for MINIX 1.5. + * Version: @(#)mouse_bus.c 1.0.0 2018/05/23 * - * Version: @(#)mouse_bus.c 1.0.38 2018/05/23 - * - * Authors: Fred N. van Kempen, + * Authors: Miran Grca, + * Fred N. van Kempen, * + * Copyright 200?-2018 Bochs. + * Copyright 2017,2018 Miran Grca. * Copyright 1989-2018 Fred N. van Kempen. */ #include @@ -70,102 +75,86 @@ #include "timer.h" #include "device.h" #include "mouse.h" +#include "random.h" +#define IRQ_MASK ((1 << 5) >> dev->irq) -#define MOUSE_PORT 0x023c /* default */ -#define MOUSE_IRQ 5 /* default */ -#define MOUSE_BUTTONS 2 /* default */ -#define MOUSE_DEBUG 0 +/* MS Inport Bus Mouse Adapter */ +#define INP_PORT_CONTROL 0x0000 +#define INP_PORT_DATA 0x0001 +#define INP_PORT_SIGNATURE 0x0002 +#define INP_PORT_CONFIG 0x0003 + +#define INP_CTRL_READ_BUTTONS 0x00 +#define INP_CTRL_READ_X 0x01 +#define INP_CTRL_READ_Y 0x02 +#define INP_CTRL_COMMAND 0x07 +#define INP_CTRL_RAISE_IRQ 0x16 +#define INP_CTRL_RESET 0x80 + +#define INP_HOLD_COUNTER (1 << 5) +#define INP_ENABLE_TIMER_IRQ (1 << 4) +#define INP_ENABLE_DATA_IRQ (1 << 3) +#define INP_PERIOD_MASK 0x07 + +/* MS/Logictech Standard Bus Mouse Adapter */ +#define BUSM_PORT_DATA 0x0000 +#define BUSM_PORT_SIGNATURE 0x0001 +#define BUSM_PORT_CONTROL 0x0002 +#define BUSM_PORT_CONFIG 0x0003 + +#define HOLD_COUNTER (1 << 7) +#define READ_X (0 << 6) +#define READ_Y (1 << 6) +#define READ_LOW (0 << 5) +#define READ_HIGH (1 << 5) +#define DISABLE_IRQ (1 << 4) + +#define DEVICE_ACTIVE (1 << 7) + +#define READ_X_LOW (READ_X | READ_LOW) +#define READ_X_HIGH (READ_X | READ_HIGH) +#define READ_Y_LOW (READ_Y | READ_LOW) +#define READ_Y_HIGH (READ_Y | READ_HIGH) + +#define FLAG_INPORT (1 << 0) +#define FLAG_ENABLED (1 << 1) +#define FLAG_HOLD (1 << 2) +#define FLAG_TIMER_INT (1 << 3) +#define FLAG_DATA_INT (1 << 4) + +static const double periods[4] = { 30.0, 50.0, 100.0, 200.0 }; /* Our mouse device. */ typedef struct mouse { - const char *name; /* name of this device */ - int8_t type; /* type of this device */ - uint16_t base; /* I/O port base to use */ - int8_t irq; /* IRQ channel to use */ - uint16_t flags; /* device flags */ + int base, irq, bn, flags, + mouse_delayed_dx, mouse_delayed_dy, + mouse_buttons, + current_x, current_y, + current_b, + control_val, mouse_buttons_last, + config_val, sig_val, + command_val, toggle_counter; - uint8_t r_magic, /* MAGIC register */ - r_ctrl, /* CONTROL register (WR) */ - r_conf, /* CONFIG register */ - r_cmd; /* (MS) current command */ + double period; - uint8_t seq; /* general counter */ - - uint8_t but, /* current mouse status */ - but_last; - uint8_t cur_but; - int8_t x, y; - int x_delay, - y_delay; - uint8_t irq_num; - - int64_t timer; /* mouse event timer */ - - uint8_t (*read)(struct mouse *, uint16_t); - void (*write)(struct mouse *, uint16_t, uint8_t); + int64_t timer_enabled, timer; /* mouse event timer */ } mouse_t; -#define FLAG_NEW 0x100 /* device is the newer variant */ -#define FLAG_INPORT 0x80 /* device is MS InPort */ -#define FLAG_3BTN 0x20 /* enable 3-button mode */ -#define FLAG_SCALED 0x10 /* enable delta scaling */ -#define FLAG_INTR 0x04 /* dev can send interrupts */ -#define FLAG_FROZEN 0x02 /* do not update counters */ -#define FLAG_ENABLED 0x01 /* dev is enabled for use */ - - -/* Definitions for Logitech. */ -#define LTMOUSE_DATA 0 /* DATA register */ -#define LTMOUSE_MAGIC 1 /* signature magic register */ -# define LTMAGIC_BYTE1 0xa5 /* most drivers use this */ -# define LTMAGIC_BYTE2 0x5a /* some drivers use this */ -#define LTMOUSE_CTRL 2 /* CTRL register */ -# define LTCTRL_FREEZE 0x80 /* do not sample when set */ -# define LTCTRL_RD_Y_HI 0x60 -# define LTCTRL_RD_Y_LO 0x40 -# define LTCTRL_RD_X_HI 0x20 -# define LTCTRL_RD_X_LO 0x00 -# define LTCTRL_RD_MASK 0x60 -# define LTCTRL_IDIS 0x10 -# define LTCTRL_IENB 0x00 -#define LTMOUSE_CONFIG 3 /* CONFIG register */ - -/* Definitions for Microsoft. */ -#define MSMOUSE_CTRL 0 /* CTRL register */ -# define MSCTRL_RESET 0x80 /* reset controller */ -# define MSCTRL_FREEZE 0x20 /* HOLD- freeze data */ -# define MSCTRL_IENB_A 0x08 /* ATIXL intr enable */ -# define MSCTRL_IENB_M 0x01 /* MS intr enable */ -# define MSCTRL_COMMAND 0x07 -# define MSCTRL_RD_Y 0x02 -# define MSCTRL_RD_X 0x01 -# define MSCTRL_RD_BUT 0x00 -#define MSMOUSE_DATA 1 /* DATA register */ -# define MSDATA_IRQ 0x16 -# define MSDATA_BASE 0x10 /* MS InPort: 30Hz */ -# define MSDATA_HZ30 0x01 /* ATIXL 30Hz */ -# define MSDATA_HZ50 0x02 /* ATIXL 50Hz */ -# define MSDATA_HZ100 0x03 /* ATIXL 100Hz */ -# define MSDATA_HZ200 0x04 /* ATIXL 200Hz */ -#define MSMOUSE_MAGIC 2 /* MAGIC register */ -# define MAGIC_MSBYTE1 0xde /* indicates MS InPort */ -# define MAGIC_MSBYTE2 0x12 -#define MSMOUSE_CONFIG 3 /* CONFIG register */ #ifdef ENABLE_MOUSE_BUS_LOG -int mouse_bus_do_log = ENABLE_MOUSE_BUS_LOG; +int bm_do_log = ENABLE_MOUSE_BUS_LOG; #endif static void -mouse_bus_log(const char *format, ...) +bm_log(const char *format, ...) { #ifdef ENABLE_MOUSE_BUS_LOG va_list ap; - if (mouse_bus_do_log) { + if (bm_do_log) { va_start(ap, format); pclog_ex(format, ap); va_end(ap); @@ -174,293 +163,140 @@ mouse_bus_log(const char *format, ...) } -/* Reset the controller state. */ -static void -ms_reset(mouse_t *dev) -{ - dev->r_ctrl = 0x00; - dev->r_cmd = 0x00; - - dev->seq = 0; - - dev->x = dev->y = 0; - dev->but = 0x00; - - dev->flags &= 0xf0; - dev->flags |= (FLAG_INTR | FLAG_ENABLED); - - dev->x_delay = dev->y_delay = 0; - - dev->cur_but = 0x00; -} - - -static void -ms_update_data(mouse_t *dev) -{ - int delta_x, delta_y; - - if (dev->x_delay > 127) { - delta_x = 127; - dev->x_delay -= 127; - } else if (dev->x_delay < -128) { - delta_x = -128; - dev->x_delay += 128; - } else { - delta_x = dev->x_delay; - dev->x_delay = 0; - } - - if (dev->y_delay > 127) { - delta_y = 127; - dev->y_delay -= 127; - } else if (dev->y_delay < -128) { - delta_y = -128; - dev->x_delay += 128; - } else { - delta_y = dev->y_delay; - dev->y_delay = 0; - } - - if (!(dev->flags & FLAG_FROZEN)) { - dev->x = (int8_t) delta_x; - dev->y = (int8_t) delta_y; - dev->cur_but = dev->but; - } -} - - -/* Handle a WRITE to an InPort register. */ -static void -ms_write(mouse_t *dev, uint16_t port, uint8_t val) -{ - uint8_t valxor; - - switch (port) { - case MSMOUSE_CTRL: - /* Bit 7 is reset. */ - if (val & MSCTRL_RESET) - ms_reset(dev); - - /* Bits 0-2 are the internal register index. */ - switch (val & 0x07) { - case MSCTRL_COMMAND: - case MSCTRL_RD_BUT: - case MSCTRL_RD_X: - case MSCTRL_RD_Y: - dev->r_cmd = val & 0x07; - break; - } - break; - - case MSMOUSE_DATA: - picintc(1 << dev->irq); - - if (val == MSDATA_IRQ) - picint(1 << dev->irq); - else { - switch (dev->r_cmd) { - case MSCTRL_COMMAND: - valxor = (dev->r_ctrl ^ val); - - if (valxor & MSCTRL_FREEZE) { - if (val & MSCTRL_FREEZE) { - /* Hold the sampling while we do something. */ - dev->flags |= FLAG_FROZEN; - } else { - /* Reset current state. */ - dev->flags &= ~FLAG_FROZEN; - - dev->x = dev->y = 0; - dev->but = 0; - } - } - - if (val & (MSCTRL_IENB_M | MSCTRL_IENB_A)) - dev->flags |= FLAG_INTR; - else - dev->flags &= ~FLAG_INTR; - - dev->r_ctrl = val; - break; - - default: - break; - } - } - break; - - case MSMOUSE_MAGIC: - break; - - case MSMOUSE_CONFIG: - break; - } -} - - -/* Handle a READ from an InPort register. */ +/* Handle a READ operation from one of our registers. */ static uint8_t -ms_read(mouse_t *dev, uint16_t port) +lt_read(uint16_t port, void *priv) { - uint8_t ret = 0x00; + mouse_t *dev = (mouse_t *)priv; + uint8_t value = 0xff; - switch (port) { - case MSMOUSE_CTRL: - ret = dev->r_ctrl; - break; - - case MSMOUSE_DATA: - switch (dev->r_cmd) { - case MSCTRL_RD_BUT: - ret = dev->cur_but; - if (dev->flags & FLAG_NEW) - ret |= 0x40; /* On new InPort, always have bit 6 set. */ + switch (port & 0x03) { + case BUSM_PORT_DATA: + /* Testing and another source confirm that the buttons are + *ALWAYS* present, so I'm going to change this a bit. */ + switch (dev->control_val & 0x60) { + case READ_X_LOW: + value = dev->current_x & 0x0F; break; - - case MSCTRL_RD_X: - ret = dev->x; + case READ_X_HIGH: + value = (dev->current_x >> 4) & 0x0F; break; - - case MSCTRL_RD_Y: - ret = dev->y; + case READ_Y_LOW: + value = dev->current_y & 0x0F; break; - - case MSCTRL_COMMAND: - ret = dev->r_ctrl; + case READ_Y_HIGH: + value = (dev->current_y >> 4) & 0x0F; break; + default: + bm_log("ERROR: Reading data port in unsupported mode 0x%02x\n", dev->control_val); } + value |= ((dev->current_b ^ 7) << 5); break; + case BUSM_PORT_SIGNATURE: + value = dev->sig_val; + break; + case BUSM_PORT_CONTROL: + value = dev->control_val; + dev->control_val |= 0x0F; - case MSMOUSE_MAGIC: - if (dev->seq & 0x01) - ret = MAGIC_MSBYTE2; + /* If the conditions are right, simulate the flakiness of the correct IRQ bit. */ + if (dev->flags & FLAG_TIMER_INT) + dev->control_val = (dev->control_val & ~IRQ_MASK) | (random_generate() & IRQ_MASK); + break; + case BUSM_PORT_CONFIG: + /* Read from config port returns control_val in the upper 4 bits when enabled, + possibly solid interrupt readout in the lower 4 bits, 0xff when not (at power-up). */ + if (dev->flags & FLAG_ENABLED) + return (dev->control_val | 0x0F) & ~IRQ_MASK; else - ret = MAGIC_MSBYTE1; - dev->seq ^= 1; - break; - - case MSMOUSE_CONFIG: - /* Not really present in real hardware. */ + return 0xff; break; } - return(ret); + bm_log("DEBUG: read from address 0x%04x, value = 0x%02x\n", port, value); + + return value; } -/* Reset the controller state. */ -static void -lt_reset(mouse_t *dev) +static uint8_t +ms_read(uint16_t port, void *priv) { - dev->r_magic = 0x00; - dev->r_ctrl = (LTCTRL_IENB); - dev->r_conf = 0x00; + mouse_t *dev = (mouse_t *)priv; + uint8_t value = 0xff; - dev->seq = 0; + switch (port & 0x03) { + case INP_PORT_CONTROL: + value = dev->control_val; + break; + case INP_PORT_DATA: + switch (dev->command_val) { + case INP_CTRL_READ_BUTTONS: + value = dev->current_b | 0x80; + break; + case INP_CTRL_READ_X: + value = dev->current_x; + break; + case INP_CTRL_READ_Y: + value = dev->current_y; + break; + case INP_CTRL_COMMAND: + value = dev->control_val; + break; + default: + bm_log("ERROR: Reading data port in unsupported mode 0x%02x\n", dev->control_val); + } + break; + case INP_PORT_SIGNATURE: + if (dev->toggle_counter) + value = 0x12; + else + value = 0xDE; + dev->toggle_counter ^= 1; + break; + case INP_PORT_CONFIG: + bm_log("ERROR: Unsupported read from port 0x%04x\n", port); + break; + } - dev->x = dev->y = 0; - dev->but = 0x00; + bm_log("DEBUG: read from address 0x%04x, value = 0x%02x\n", port, value); - dev->flags &= 0xf0; - dev->flags |= FLAG_INTR; - - dev->irq_num = 0; + return value; } -/* Called at 30hz */ +/* Handle a WRITE operation to one of our registers. */ static void -bm_timer(void *priv) +lt_write(uint16_t port, uint8_t val, void *priv) { mouse_t *dev = (mouse_t *)priv; - if (dev->flags & FLAG_INPORT) { - dev->timer = ((1000000LL * TIMER_USEC) / 30LL); + bm_log("DEBUG: write to address 0x%04x, value = 0x%02x\n", port, val); - ms_update_data(dev); - - if (dev->flags & FLAG_INTR) - picint(1 << dev->irq); - } else { - picint(1 << dev->irq); - - if (dev->irq_num == 5) { - mouse_bus_log("5th IRQ, enabling mouse...\n"); - lt_reset(dev); - dev->flags |= FLAG_ENABLED; - } - - if (dev->irq_num == 4) { - mouse_bus_log("4th IRQ, going for the 5th...\n"); - dev->irq_num++; - dev->timer = ((1000000LL * TIMER_USEC) / 30LL); - } else { - mouse_bus_log("IRQ before the 4th, disabling timer...\n"); - dev->timer = 0; - } - } -} - - -/* Handle a WRITE to a Logitech register. */ -static void -lt_write(mouse_t *dev, uint16_t port, uint8_t val) -{ - uint8_t b; - - switch (port) { - case LTMOUSE_DATA: /* [00] data register */ + switch (port & 0x03) { + case BUSM_PORT_DATA: + bm_log("ERROR: Unsupported write to port 0x%04x (value = 0x%02x)\n", port, val); break; - - case LTMOUSE_MAGIC: /* [01] magic data register */ - switch(val) { - case LTMAGIC_BYTE1: - case LTMAGIC_BYTE2: - lt_reset(dev); - dev->r_magic = val; - dev->flags |= FLAG_ENABLED; - break; - } + case BUSM_PORT_SIGNATURE: + dev->sig_val = val; break; + case BUSM_PORT_CONTROL: + dev->control_val = val | 0x0F; - case LTMOUSE_CTRL: /* [02] control register */ - if (!(dev->flags & FLAG_ENABLED)) { - dev->irq_num++; - dev->timer = ((1000000LL * TIMER_USEC) / 30LL); - break; - } + if (!(val & DISABLE_IRQ)) + dev->flags |= FLAG_TIMER_INT; + else + dev->flags &= ~FLAG_TIMER_INT; - b = (dev->r_ctrl ^ val); - if (b & LTCTRL_FREEZE) { - if (val & LTCTRL_FREEZE) { - /* Hold the sampling while we do something. */ - dev->flags |= FLAG_FROZEN; - } else { - /* Reset current state. */ - dev->flags &= ~FLAG_FROZEN; - dev->x = dev->y = 0; - if (dev->but) - dev->but |= 0x80; - } - } + if (val & HOLD_COUNTER) + dev->flags |= FLAG_HOLD; + else + dev->flags &= ~FLAG_HOLD; - if (b & LTCTRL_IDIS) { - /* Disable or enable interrupts. */ - if (val & LTCTRL_IDIS) - dev->flags &= ~FLAG_INTR; - else - dev->flags |= FLAG_INTR; - } - - /* Save new register value. */ - dev->r_ctrl = val | 0x0F; - - /* Clear any pending interrupts. */ picintc(1 << dev->irq); - break; - case LTMOUSE_CONFIG: /* [03] config register */ + break; + case BUSM_PORT_CONFIG: /* * The original Logitech design was based on using a * 8255 parallel I/O chip. This chip has to be set up @@ -488,139 +324,106 @@ lt_write(mouse_t *dev, uint16_t port, uint8_t val) * being an output port and lower 4 bits an input port, and * enable the sucker. Courtesy Intel 8255 databook. Lars */ - dev->r_conf = val; - break; - - default: - break; - } -} - - -static int -lt_read_int(mouse_t *dev) -{ - if (!(dev->flags & FLAG_NEW)) - return 1; /* On old LogiBus, read the IRQ bits always. */ - - if (dev->flags & FLAG_INTR) - return 1; /* On new LogiBus, read the IRQ bits if interrupts are enabled. */ - - return 0; /* Otherwise, do not. */ -} - - -/* Handle a READ from a Logitech register. */ -static uint8_t -lt_read(mouse_t *dev, uint16_t port) -{ - uint8_t ret = 0xff; - - /* The GEOS drivers actually check this. */ - if (! (dev->flags & FLAG_ENABLED)) return(ret); - - switch (port) { - case LTMOUSE_DATA: /* [00] data register */ - ret = 0x07; - if (dev->but & 0x01) /* LEFT */ - ret &= ~0x04; - if (dev->but & 0x02) /* RIGHT */ - ret &= ~0x01; - if (dev->flags & FLAG_3BTN) - if (dev->but & 0x04) /* MIDDLE */ - ret &= ~0x02; - ret <<= 5; - - switch(dev->r_ctrl & LTCTRL_RD_MASK) { - case LTCTRL_RD_X_LO: /* X, low bits */ - ret |= (dev->x & 0x0f); - break; - - case LTCTRL_RD_X_HI: /* X, high bits */ - ret |= (dev->x >> 4) & 0x0f; - break; - - case LTCTRL_RD_Y_LO: /* Y, low bits */ - ret |= (dev->y & 0x0f); - break; - - case LTCTRL_RD_Y_HI: /* Y, high bits */ - ret |= (dev->y >> 4) & 0x0f; - break; + dev->config_val = val; + if (val & DEVICE_ACTIVE) { + dev->flags |= (FLAG_ENABLED | FLAG_TIMER_INT); + dev->control_val = 0x0F & ~IRQ_MASK; + dev->timer = ((int64_t) dev->period) * TIMER_USEC; + dev->timer_enabled = 1LL; + } else { + dev->flags &= ~(FLAG_ENABLED | FLAG_TIMER_INT); + dev->timer = 0LL; + dev->timer_enabled = 0LL; } break; - - case LTMOUSE_MAGIC: /* [01] magic data register */ - /* - * Drivers write a magic byte to this register, usually - * this is either 5A (AMI WinBIOS, MS Mouse 2.0) or - * A5 (MS Mouse 9.1, Windows drivers, UNIX/Linux/Minix.) - */ - ret = dev->r_magic; - break; - - case LTMOUSE_CTRL: /* [02] control register */ - ret = dev->r_ctrl; - dev->r_ctrl |= 0x0F; - if ((dev->seq > 0x3FF) && lt_read_int(dev)) { - /* !IDIS, return DIP switch setting. */ - switch(dev->irq) { - case 2: - dev->r_ctrl &= ~0x08; - break; - - case 3: - dev->r_ctrl &= ~0x04; - break; - - case 4: - dev->r_ctrl &= ~0x02; - break; - - case 5: - dev->r_ctrl &= ~0x01; - break; - } - } - dev->seq = (dev->seq + 1) & 0x7ff; - break; - - case LTMOUSE_CONFIG: /* [03] config register */ - ret = dev->r_conf; - break; - - default: - break; } - - return(ret); } /* Handle a WRITE operation to one of our registers. */ static void -bm_write(uint16_t port, uint8_t val, void *priv) +ms_write(uint16_t port, uint8_t val, void *priv) { mouse_t *dev = (mouse_t *)priv; - mouse_bus_log("%s: write(%d,%02x)\n", dev->name, port & 0x03, val); + bm_log("DEBUG: write to address 0x%04x, value = 0x%02x\n", port, val); - dev->write(dev, port & 0x03, val); -} + switch (port & 0x03) { + case INP_PORT_CONTROL: + /* Bit 7 is reset. */ + if (val & INP_CTRL_RESET) + dev->control_val = 0; + /* Bits 0-2 are the internal register index. */ + switch(val & 0x07) { + case INP_CTRL_COMMAND: + case INP_CTRL_READ_BUTTONS: + case INP_CTRL_READ_X: + case INP_CTRL_READ_Y: + dev->command_val = val & 0x07; + break; + default: + bm_log("ERROR: Unsupported command written to port 0x%04x (value = 0x%02x)\n", port, val); + } + break; + case INP_PORT_DATA: + picintc(1 << dev->irq); + switch(dev->command_val) { + case INP_CTRL_COMMAND: + if (val & INP_HOLD_COUNTER) + dev->flags |= FLAG_HOLD; + else + dev->flags &= ~FLAG_HOLD; -/* Handle a READ operation from one of our registers. */ -static uint8_t -bm_read(uint16_t port, void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - uint8_t ret; + if (val & INP_ENABLE_TIMER_IRQ) + dev->flags |= FLAG_TIMER_INT; + else + dev->flags &= ~FLAG_TIMER_INT; - ret = dev->read(dev, port & 0x03); + if (val & INP_ENABLE_DATA_IRQ) + dev->flags |= FLAG_DATA_INT; + else + dev->flags &= ~FLAG_DATA_INT; - mouse_bus_log("%s: read(%d): %02x\n", dev->name, port & 0x03, ret); + switch(val & INP_PERIOD_MASK) { + case 0: + dev->period = 0.0; + dev->timer = 0LL; + dev->timer_enabled = 0LL; + break; - return(ret); + case 1: + case 2: + case 3: + case 4: + dev->period = 1000000.0 / periods[(val & INP_PERIOD_MASK) - 1]; + dev->timer = ((int64_t) dev->period) * TIMER_USEC; + dev->timer_enabled = (val & INP_ENABLE_TIMER_IRQ) ? 1LL : 0LL; + bm_log("DEBUG: Timer is now %sabled at period %i\n", (val & INP_ENABLE_TIMER_IRQ) ? "en" : "dis", (int32_t) dev->period); + break; + + case 6: + if (val & INP_ENABLE_TIMER_IRQ) + picint(1 << dev->irq); + dev->control_val &= INP_PERIOD_MASK; + dev->control_val |= (val & ~INP_PERIOD_MASK); + return; + default: + bm_log("ERROR: Unsupported period written to port 0x%04x (value = 0x%02x)\n", port, val); + } + + dev->control_val = val; + + break; + default: + bm_log("ERROR: Unsupported write to port 0x%04x (value = 0x%02x)\n", port, val); + } + break; + case INP_PORT_SIGNATURE: + case INP_PORT_CONFIG: + bm_log("ERROR: Unsupported write to port 0x%04x (value = 0x%02x)\n", port, val); + break; + } } @@ -628,80 +431,137 @@ bm_read(uint16_t port, void *priv) static int bm_poll(int x, int y, int z, int b, void *priv) { - uint8_t b_last; mouse_t *dev = (mouse_t *)priv; + int xor; - b_last = dev->but; + if (!(dev->flags & FLAG_ENABLED)) + return(1); /* Mouse is disabled, do nothing. */ - /* Return early if nothing to do. */ - if (!x && !y && !z && (dev->but == b)) - return(1); + if (!x && !y && !((b ^ dev->mouse_buttons_last) & 0x07)) { + dev->mouse_buttons_last = b; + return(1); /* State has not changed, do nothing. */ + } - /* If we are not enabled, return. */ - if (! (dev->flags & FLAG_ENABLED)) - mouse_bus_log("bm_poll(): Mouse not enabled\n"); + /* Converts button states from MRL to LMR. */ + dev->mouse_buttons = (uint8_t) (((b & 1) << 2) | ((b & 2) >> 1)); + if (dev->bn == 3) + dev->mouse_buttons |= ((b & 4) >> 1); - if (dev->flags & FLAG_SCALED) { - /* Scale down the motion. */ - if ((x < -1) || (x > 1)) x >>= 1; - if ((y < -1) || (y > 1)) y >>= 1; + if ((dev->flags & FLAG_INPORT) && !dev->timer_enabled) { + /* This is an InPort mouse in data interrupt mode, + so update bits 6-3 here. */ + + /* If the mouse has moved, set bit 6. */ + if (x || y) + dev->mouse_buttons |= 0x40; + + /* Set bits 3-5 according to button state changes. */ + xor = ((dev->current_b ^ dev->mouse_buttons) & 0x07) << 3; + dev->mouse_buttons |= xor; + } + + dev->mouse_buttons_last = b; + + /* Clamp x and y to between -128 and 127 (int8_t range). */ + if (x > 127) x = 127; + if (x < -128) x = -128; + + if (y > 127) y = 127; + if (y < -128) y = -128; + + if (dev->timer_enabled) { + /* Update delayed coordinates. */ + dev->mouse_delayed_dx += x; + dev->mouse_delayed_dy += y; + } else { + /* If the counters are not frozen, update them. */ + if (!(dev->flags & FLAG_HOLD)) { + dev->current_x = (int8_t) x; + dev->current_y = (int8_t) y; + + dev->current_b = dev->mouse_buttons; + } + + /* Send interrupt. */ + if (dev->flags & FLAG_DATA_INT) { + picint(1 << dev->irq); + bm_log("DEBUG: Data Interrupt Fired...\n"); + } + } + return(0); +} + + +/* The timer calls us on every tick if the mouse is in timer mode + (InPort mouse is so configured, MS/Logitech Bus mouse always). */ +static void +bm_update_data(mouse_t *dev) +{ + int delta_x, delta_y; + int xor; + + /* Update the deltas and the delays. */ + if (dev->mouse_delayed_dx > 127) { + delta_x = 127; + dev->mouse_delayed_dx -= 127; + } else if (dev->mouse_delayed_dx < -128) { + delta_x = -128; + dev->mouse_delayed_dx += 128; + } else { + delta_x = dev->mouse_delayed_dx; + dev->mouse_delayed_dx = 0; + } + + if (dev->mouse_delayed_dy > 127) { + delta_y = 127; + dev->mouse_delayed_dy -= 127; + } else if (dev->mouse_delayed_dy < -128) { + delta_y = -128; + dev->mouse_delayed_dy += 128; + } else { + delta_y = dev->mouse_delayed_dy; + dev->mouse_delayed_dy = 0; + } + + /* If the counters are not frozen, update them. */ + if (!(dev->flags & FLAG_HOLD)) { + dev->current_x = (uint8_t) delta_x; + dev->current_y = (uint8_t) delta_y; } if (dev->flags & FLAG_INPORT) { - if (x || y || z) - dev->but = 0x40; /* Mouse has moved. */ - else - dev->but = 0x00; + /* This is an InPort mouse in timer mode, so update current_b always, + and update bits 6-3 (mouse moved and button state changed) here. */ + xor = ((dev->current_b ^ dev->mouse_buttons) & 0x07) << 3; + dev->current_b = (dev->mouse_buttons & 0x87) | xor; + if (delta_x || delta_y) + dev->current_b |= 0x40; + } else if (!(dev->flags & FLAG_HOLD)) { + /* This is a MS/Logitech Bus Mouse, so only update current_b if the + counters are frozen. */ + dev->current_b = dev->mouse_buttons; + } +} - if (x > 127) x = 127; - if (y > 127) y = 127; - if (x < -128) x = -128; - if (y < -128) y = -128; - dev->x_delay += x; - dev->y_delay += y; - dev->but |= (uint8_t) (((b & 1) << 2) | ((b & 2) >> 1)); - if (dev->flags & FLAG_3BTN) - dev->but |= ((b & 4) >> 1); +/* Called at the configured period (InPort mouse) or 45 times per second (MS/Logitech Bus mouse). */ +static void +bm_timer(void *priv) +{ + mouse_t *dev = (mouse_t *)priv; - if ((b_last ^ dev->but) & 0x04) - dev->but |= 0x20; /* Left button state has changed. */ - if (((b_last ^ dev->but) & 0x02) && (dev->flags & FLAG_3BTN)) - dev->but |= 0x10; /* Middle button state has changed. */ - if ((b_last ^ dev->but) & 0x01) - dev->but |= 0x08; /* Right button state has changed. */ + bm_log("DEBUG: Timer Tick (flags=%08X)...\n", dev->flags); - dev->but |= 0x80; /* Packet complete. */ - } else { - /* If we are frozen, do not update the state. */ - if (! (dev->flags & FLAG_FROZEN)) { - /* Add the delta to our state. */ - x += dev->x; - if (x > 127) - x = 127; - if (x < -128) - x = -128; - dev->x = (int8_t)x; + /* The period is configured either via emulator settings (for MS/Logitech Bus mouse) + or via software (for InPort mouse). */ + dev->timer += ((int64_t) dev->period) * TIMER_USEC; - y += dev->y; - if (y > 127) - y = 127; - if (y < -1287) - y = -1287; - dev->y = (int8_t)y; - - dev->x_delay += x; - dev->y_delay += y; - - dev->but = b; - } - - /* Either way, generate an interrupt. */ - if ((dev->flags & FLAG_INTR) && !(dev->flags & FLAG_INPORT)) - picint(1 << dev->irq); + if (dev->flags & FLAG_TIMER_INT) { + picint(1 << dev->irq); + bm_log("DEBUG: Timer Interrupt Fired...\n"); } - return(0); + bm_update_data(dev); } @@ -711,11 +571,8 @@ bm_close(void *priv) { mouse_t *dev = (mouse_t *)priv; - /* Release our I/O range. */ - io_removehandler(dev->base, 4, - bm_read, NULL, NULL, bm_write, NULL, NULL, dev); - - free(dev); + if (dev) + free(dev); } @@ -724,64 +581,64 @@ static void * bm_init(const device_t *info) { mouse_t *dev; - int i, j; dev = (mouse_t *)malloc(sizeof(mouse_t)); memset(dev, 0x00, sizeof(mouse_t)); - dev->name = info->name; - dev->type = info->local; + + if (info->local == MOUSE_TYPE_INPORT) + dev->flags = FLAG_INPORT; + else + dev->flags = 0; + dev->base = device_get_config_hex16("base"); dev->irq = device_get_config_int("irq"); - i = device_get_config_int("buttons"); - if (i > 2) - dev->flags |= FLAG_3BTN; - j = device_get_config_int("model"); - if (j) - dev->flags |= FLAG_NEW; + dev->bn = device_get_config_int("buttons"); + mouse_set_buttons(dev->bn); - switch(dev->type) { - case MOUSE_TYPE_LOGIBUS: - lt_reset(dev); + dev->mouse_delayed_dx = 0; + dev->mouse_delayed_dy = 0; + dev->mouse_buttons = 0; + dev->mouse_buttons_last = 0; + dev->sig_val = 0; /* the signature port value */ + dev->current_x = + dev->current_y = + dev->current_b = 0; + dev->command_val = 0; /* command byte */ + dev->toggle_counter = 0; /* signature byte / IRQ bit toggle */ - /* Initialize I/O handlers. */ - dev->read = lt_read; - dev->write = lt_write; + if (dev->flags & FLAG_INPORT) { + dev->control_val = 0; /* the control port value */ + dev->flags |= FLAG_ENABLED; + dev->period = 0.0; - dev->timer = 0; - timer_add(bm_timer, &dev->timer, &dev->timer, dev); - break; + io_sethandler(dev->base, 4, + ms_read, NULL, NULL, ms_write, NULL, NULL, dev); + } else { + dev->control_val = 0x0f; /* the control port value */ + dev->config_val = 0x0e; /* the config port value */ + dev->period = 1000000.0 / ((double) device_get_config_int("hz")); - case MOUSE_TYPE_INPORT: - dev->flags |= FLAG_INPORT; - ms_reset(dev); - - /* Initialize I/O handlers. */ - dev->read = ms_read; - dev->write = ms_write; - - dev->timer = (33334LL * TIMER_USEC); - timer_add(bm_timer, &dev->timer, TIMER_ALWAYS_ENABLED, dev); - break; + io_sethandler(dev->base, 4, + lt_read, NULL, NULL, lt_write, NULL, NULL, dev); } - /* Request an I/O range. */ - io_sethandler(dev->base, 4, - bm_read, NULL, NULL, bm_write, NULL, NULL, dev); + dev->timer = 0LL; + dev->timer_enabled = 0LL; - mouse_bus_log("%s: I/O=%04x, IRQ=%d, buttons=%d, model=%s\n", - dev->name, dev->base, dev->irq, i, j ? "new" : "old"); + timer_add(bm_timer, &dev->timer, &dev->timer_enabled, dev); - /* Tell them how many buttons we have. */ - mouse_set_buttons((dev->flags & FLAG_3BTN) ? 3 : 2); + if (dev->flags & FLAG_INPORT) + bm_log("MS Inport BusMouse initialized\n"); + else + bm_log("Standard MS/Logitech BusMouse initialized\n"); - /* Return our private data to the I/O layer. */ - return(dev); + return dev; } -static const device_config_t bm_config[] = { +static const device_config_t lt_config[] = { { - "base", "Address", CONFIG_HEX16, "", MOUSE_PORT, + "base", "Address", CONFIG_HEX16, "", 0x23c, { { "0x230", 0x230 @@ -801,7 +658,7 @@ static const device_config_t bm_config[] = { } }, { - "irq", "IRQ", CONFIG_SELECTION, "", MOUSE_IRQ, { + "irq", "IRQ", CONFIG_SELECTION, "", 5, { { "IRQ 2", 2 }, @@ -820,7 +677,23 @@ static const device_config_t bm_config[] = { } }, { - "buttons", "Buttons", CONFIG_SELECTION, "", MOUSE_BUTTONS, { + "hz", "Hz", CONFIG_SELECTION, "", 45, { + { + "30 Hz (JMP2 = 1)", 30 + }, + { + "45 Hz (JMP2 not populated)", 45 + }, + { + "60 Hz (JMP 2 = 2)", 60 + }, + { + "" + } + } + }, + { + "buttons", "Buttons", CONFIG_SELECTION, "", 2, { { "Two", 2 }, @@ -833,12 +706,58 @@ static const device_config_t bm_config[] = { } }, { - "model", "Model", CONFIG_SELECTION, "", 0, { + "", "", -1 + } +}; + + +static const device_config_t ms_config[] = { + { + "base", "Address", CONFIG_HEX16, "", 0x23c, + { { - "Old", 0 + "0x230", 0x230 }, { - "New", 1 + "0x234", 0x234 + }, + { + "0x238", 0x238 + }, + { + "0x23C", 0x23c + }, + { + "" + } + } + }, + { + "irq", "IRQ", CONFIG_SELECTION, "", 5, { + { + "IRQ 2", 2 + }, + { + "IRQ 3", 3 + }, + { + "IRQ 4", 4 + }, + { + "IRQ 5", 5 + }, + { + "" + } + } + }, + { + "buttons", "Buttons", CONFIG_SELECTION, "", 2, { + { + "Two", 2 + }, + { + "Three", 3 }, { "" @@ -857,7 +776,7 @@ const device_t mouse_logibus_device = { MOUSE_TYPE_LOGIBUS, bm_init, bm_close, NULL, bm_poll, NULL, NULL, - bm_config + lt_config }; const device_t mouse_msinport_device = { @@ -866,5 +785,5 @@ const device_t mouse_msinport_device = { MOUSE_TYPE_INPORT, bm_init, bm_close, NULL, bm_poll, NULL, NULL, - bm_config + ms_config }; diff --git a/src/mouse_ps2.c b/src/mouse_ps2.c index a20e49d3e..16ec68b5e 100644 --- a/src/mouse_ps2.c +++ b/src/mouse_ps2.c @@ -79,6 +79,15 @@ mouse_ps2_log(const char *format, ...) } +void +mouse_clear_data(void *priv) +{ + mouse_t *dev = (mouse_t *)priv; + + dev->flags &= ~FLAG_CTRLDAT; +} + + static void ps2_write(uint8_t val, void *priv) { diff --git a/src/network/net_3c503.c b/src/network/net_3c503.c new file mode 100644 index 000000000..65bea5af7 --- /dev/null +++ b/src/network/net_3c503.c @@ -0,0 +1,1679 @@ +/* + * 86Box An emulator of (mostly) x86-based PC systems and devices, + * using the ISA, EISA, VLB, MCA, and PCI system buses, + * roughly spanning the era between 1981 and 1995. + * + * This file is part of the 86Box Project. + * + * Implementation of the following network controllers: + * - 3Com Etherlink II 3c503 (ISA 8-bit). + * + * Version: @(#)net_3c503.c 1.0.0 2018/06/08 + * + * Based on @(#)3c503.cpp Carl (MAME) + * + * Authors: TheCollector1995, + * Miran Grca, + * Fred N. van Kempen, + * Carl, + * + * Copyright 2018 TheCollector1995. + * Copyright 2018 Miran Grca. + * Copyright 2017,2018 Fred N. van Kempen. + * Portions Copyright (C) 2018 MAME Project + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the: + * + * Free Software Foundation, Inc. + * 59 Temple Place - Suite 330 + * Boston, MA 02111-1307 + * USA. + */ +#include +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include "../86box.h" +#include "../config.h" +#include "../machine/machine.h" +#include "../io.h" +#include "../dma.h" +#include "../pic.h" +#include "../mem.h" +#include "../random.h" +#include "../device.h" +#include "../ui.h" +#include "network.h" +#include "net_dp8390.h" +#include "net_3c503.h" +#include "bswap.h" + +typedef struct { + dp8390_t dp8390; + mem_mapping_t ram_mapping; + uint32_t base_address; + int base_irq; + uint32_t bios_addr; + uint8_t maclocal[6]; /* configured MAC (local) address */ + uint8_t prom[32]; + + struct { + uint8_t pstr; + uint8_t pspr; + uint8_t dqtr; + uint8_t bcfr; + uint8_t pcfr; + uint8_t gacfr; + uint8_t ctrl; + uint8_t streg; + uint8_t idcfr; + uint16_t da; + uint32_t vptr; + uint8_t rfmsb; + uint8_t rflsb; + } regs; + + int dma_channel; +} threec503_t; + +static void threec503_rx(void *, uint8_t *, int); +static void threec503_tx(threec503_t *, uint32_t); + + +#ifdef ENABLE_3COM503_LOG +int threec503_do_log = ENABLE_3COM503_LOG; +#endif + + +static void +threec503_log(const char *fmt, ...) +{ +#ifdef ENABLE_3COM503_LOG + va_list ap; + + if (threec503_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +#endif +} + + +static void +threec503_interrupt(threec503_t *dev, int set) +{ + switch (dev->base_irq) { + case 2: + dev->regs.idcfr = 0x10; + break; + + case 3: + dev->regs.idcfr = 0x20; + break; + + case 4: + dev->regs.idcfr = 0x40; + break; + + case 5: + dev->regs.idcfr = 0x80; + break; + } + + if (set) + picint(1 << dev->base_irq); + else + picintc(1 << dev->base_irq); +} + + +static void +threec503_ram_write(uint32_t addr, uint8_t val, void *priv) +{ + threec503_t *dev = (threec503_t *)priv; + + if ((addr & 0x3fff) >= 0x2000) + return; + + dev->dp8390.mem[addr & 0x1fff] = val; +} + + +static uint8_t +threec503_ram_read(uint32_t addr, void *priv) +{ + threec503_t *dev = (threec503_t *)priv; + + if ((addr & 0x3fff) >= 0x2000) + return 0xff; + + return dev->dp8390.mem[addr & 0x1fff]; +} + + +static void +threec503_set_drq(threec503_t *dev) +{ + switch (dev->dma_channel) { + case 1: + dev->regs.idcfr = 1; + break; + + case 2: + dev->regs.idcfr = 2; + break; + + case 3: + dev->regs.idcfr = 4; + break; + } +} + + +/* reset - restore state to power-up, cancelling all i/o */ +static void +threec503_reset(void *priv) +{ + threec503_t *dev = (threec503_t *)priv; + int i; + + threec503_log("3Com503: reset\n"); + + /* Initialize the MAC address area by doubling the physical address */ + dev->prom[0] = dev->dp8390.physaddr[0]; + dev->prom[1] = dev->dp8390.physaddr[1]; + dev->prom[2] = dev->dp8390.physaddr[2]; + dev->prom[3] = dev->dp8390.physaddr[3]; + dev->prom[4] = dev->dp8390.physaddr[4]; + dev->prom[5] = dev->dp8390.physaddr[5]; + + /* ne1k signature */ + for (i=6; i<16; i++) + dev->prom[i] = 0x57; + + /* Zero out registers and memory */ + memset(&dev->dp8390.CR, 0x00, sizeof(dev->dp8390.CR) ); + memset(&dev->dp8390.ISR, 0x00, sizeof(dev->dp8390.ISR)); + memset(&dev->dp8390.IMR, 0x00, sizeof(dev->dp8390.IMR)); + memset(&dev->dp8390.DCR, 0x00, sizeof(dev->dp8390.DCR)); + memset(&dev->dp8390.TCR, 0x00, sizeof(dev->dp8390.TCR)); + memset(&dev->dp8390.TSR, 0x00, sizeof(dev->dp8390.TSR)); + memset(&dev->dp8390.RSR, 0x00, sizeof(dev->dp8390.RSR)); + dev->dp8390.tx_timer_active = 0; + dev->dp8390.local_dma = 0; + dev->dp8390.page_start = 0; + dev->dp8390.page_stop = 0; + dev->dp8390.bound_ptr = 0; + dev->dp8390.tx_page_start = 0; + dev->dp8390.num_coll = 0; + dev->dp8390.tx_bytes = 0; + dev->dp8390.fifo = 0; + dev->dp8390.remote_dma = 0; + dev->dp8390.remote_start = 0; + dev->dp8390.remote_bytes = 0; + dev->dp8390.tallycnt_0 = 0; + dev->dp8390.tallycnt_1 = 0; + dev->dp8390.tallycnt_2 = 0; + + dev->dp8390.curr_page = 0; + + dev->dp8390.rempkt_ptr = 0; + dev->dp8390.localpkt_ptr = 0; + dev->dp8390.address_cnt = 0; + + memset(&dev->dp8390.mem, 0x00, sizeof(dev->dp8390.mem)); + + /* Set power-up conditions */ + dev->dp8390.CR.stop = 1; + dev->dp8390.CR.rdma_cmd = 4; + dev->dp8390.ISR.reset = 1; + dev->dp8390.DCR.longaddr = 1; + + memset(&dev->regs, 0, sizeof(dev->regs)); + + dev->regs.ctrl = 0x0a; + + threec503_interrupt(dev, 0); +} + + +/* + * Access the 32K private RAM. + * + * The NE2000 memory is accessed through the data port of the + * ASIC (offset 0) after setting up a remote-DMA transfer. + * Both byte and word accesses are allowed. + * The first 16 bytes contains the MAC address at even locations, + * and there is 16K of buffer memory starting at 16K. + */ +static uint32_t +threec503_chipmem_read(threec503_t *dev, uint32_t addr, unsigned int len) +{ + uint32_t retval = 0; + + if (addr <= 15) { + retval = dev->prom[addr % 16]; + if (len == 2) + retval |= (dev->prom[(addr + 1) % 16] << 8); + return(retval); + } + + if ((addr >= DP8390_WORD_MEMSTART) && (addr < DP8390_WORD_MEMEND)) { + retval = dev->dp8390.mem[addr - DP8390_WORD_MEMSTART]; + if (len == 2) + retval |= (dev->dp8390.mem[addr - DP8390_WORD_MEMSTART + 1] << 8); + return(retval); + } + + threec503_log("3Com503: out-of-bounds chipmem read, %04X\n", addr); + return(0xff); +} + + +static void +threec503_chipmem_write(threec503_t *dev, uint32_t addr, uint32_t val, unsigned len) +{ + if ((addr >= DP8390_WORD_MEMSTART) && (addr < DP8390_WORD_MEMEND)) { + dev->dp8390.mem[addr-DP8390_WORD_MEMSTART] = val & 0xff; + if (len == 2) + dev->dp8390.mem[addr-DP8390_WORD_MEMSTART+1] = val >> 8; + } else + threec503_log("3Com503: out-of-bounds chipmem write, %04X\n", addr); +} + + +/* Handle reads/writes to the 'zeroth' page of the DS8390 register file. */ +static uint32_t +threec503_page0_read(threec503_t *dev, uint32_t off, unsigned int len) +{ + uint8_t retval = 0; + + if (len > 1) { + /* encountered with win98 hardware probe */ + threec503_log("3Com503: bad length! Page0 read from register 0x%02x, len=%u\n", + off, len); + return(retval); + } + + switch(off) { + case 0x01: /* CLDA0 */ + retval = (dev->dp8390.local_dma & 0xff); + break; + + case 0x02: /* CLDA1 */ + retval = (dev->dp8390.local_dma >> 8); + break; + + case 0x03: /* BNRY */ + retval = dev->dp8390.bound_ptr; + break; + + case 0x04: /* TSR */ + retval = ((dev->dp8390.TSR.ow_coll << 7) | + (dev->dp8390.TSR.cd_hbeat << 6) | + (dev->dp8390.TSR.fifo_ur << 5) | + (dev->dp8390.TSR.no_carrier << 4) | + (dev->dp8390.TSR.aborted << 3) | + (dev->dp8390.TSR.collided << 2) | + (dev->dp8390.TSR.tx_ok)); + break; + + case 0x05: /* NCR */ + retval = dev->dp8390.num_coll; + break; + + case 0x06: /* FIFO */ + /* reading FIFO is only valid in loopback mode */ + threec503_log("3Com503: reading FIFO not supported yet\n"); + retval = dev->dp8390.fifo; + break; + + case 0x07: /* ISR */ + retval = ((dev->dp8390.ISR.reset << 7) | + (dev->dp8390.ISR.rdma_done << 6) | + (dev->dp8390.ISR.cnt_oflow << 5) | + (dev->dp8390.ISR.overwrite << 4) | + (dev->dp8390.ISR.tx_err << 3) | + (dev->dp8390.ISR.rx_err << 2) | + (dev->dp8390.ISR.pkt_tx << 1) | + (dev->dp8390.ISR.pkt_rx)); + break; + + case 0x08: /* CRDA0 */ + retval = (dev->dp8390.remote_dma & 0xff); + break; + + case 0x09: /* CRDA1 */ + retval = (dev->dp8390.remote_dma >> 8); + break; + + case 0x0a: /* reserved / RTL8029ID0 */ + threec503_log("3Com503: reserved Page0 read - 0x0a\n"); + retval = 0xff; + break; + + case 0x0b: /* reserved / RTL8029ID1 */ + threec503_log("3Com503: reserved Page0 read - 0x0b\n"); + retval = 0xff; + break; + + case 0x0c: /* RSR */ + retval = ((dev->dp8390.RSR.deferred << 7) | + (dev->dp8390.RSR.rx_disabled << 6) | + (dev->dp8390.RSR.rx_mbit << 5) | + (dev->dp8390.RSR.rx_missed << 4) | + (dev->dp8390.RSR.fifo_or << 3) | + (dev->dp8390.RSR.bad_falign << 2) | + (dev->dp8390.RSR.bad_crc << 1) | + (dev->dp8390.RSR.rx_ok)); + break; + + case 0x0d: /* CNTR0 */ + retval = dev->dp8390.tallycnt_0; + break; + + case 0x0e: /* CNTR1 */ + retval = dev->dp8390.tallycnt_1; + break; + + case 0x0f: /* CNTR2 */ + retval = dev->dp8390.tallycnt_2; + break; + + default: + threec503_log("3Com503: Page0 register 0x%02x out of range\n", + off); + break; + } + + threec503_log("3Com503: Page0 read from register 0x%02x, value=0x%02x\n", + off, retval); + + return(retval); +} + + +static void +threec503_page0_write(threec503_t *dev, uint32_t off, uint32_t val, unsigned len) +{ + uint8_t val2; + + /* It appears to be a common practice to use outw on page0 regs... */ + + /* break up outw into two outb's */ + if (len == 2) { + threec503_page0_write(dev, off, (val & 0xff), 1); + if (off < 0x0f) + threec503_page0_write(dev, off+1, ((val>>8)&0xff), 1); + return; + } + + threec503_log("3Com503: Page0 write to register 0x%02x, value=0x%02x\n", + off, val); + + switch(off) { + case 0x01: /* PSTART */ + dev->dp8390.page_start = val; + break; + + case 0x02: /* PSTOP */ + dev->dp8390.page_stop = val; + break; + + case 0x03: /* BNRY */ + dev->dp8390.bound_ptr = val; + break; + + case 0x04: /* TPSR */ + dev->dp8390.tx_page_start = val; + break; + + case 0x05: /* TBCR0 */ + /* Clear out low byte and re-insert */ + dev->dp8390.tx_bytes &= 0xff00; + dev->dp8390.tx_bytes |= (val & 0xff); + break; + + case 0x06: /* TBCR1 */ + /* Clear out high byte and re-insert */ + dev->dp8390.tx_bytes &= 0x00ff; + dev->dp8390.tx_bytes |= ((val & 0xff) << 8); + break; + + case 0x07: /* ISR */ + val &= 0x7f; /* clear RST bit - status-only bit */ + /* All other values are cleared iff the ISR bit is 1 */ + dev->dp8390.ISR.pkt_rx &= !((int)((val & 0x01) == 0x01)); + dev->dp8390.ISR.pkt_tx &= !((int)((val & 0x02) == 0x02)); + dev->dp8390.ISR.rx_err &= !((int)((val & 0x04) == 0x04)); + dev->dp8390.ISR.tx_err &= !((int)((val & 0x08) == 0x08)); + dev->dp8390.ISR.overwrite &= !((int)((val & 0x10) == 0x10)); + dev->dp8390.ISR.cnt_oflow &= !((int)((val & 0x20) == 0x20)); + dev->dp8390.ISR.rdma_done &= !((int)((val & 0x40) == 0x40)); + val = ((dev->dp8390.ISR.rdma_done << 6) | + (dev->dp8390.ISR.cnt_oflow << 5) | + (dev->dp8390.ISR.overwrite << 4) | + (dev->dp8390.ISR.tx_err << 3) | + (dev->dp8390.ISR.rx_err << 2) | + (dev->dp8390.ISR.pkt_tx << 1) | + (dev->dp8390.ISR.pkt_rx)); + val &= ((dev->dp8390.IMR.rdma_inte << 6) | + (dev->dp8390.IMR.cofl_inte << 5) | + (dev->dp8390.IMR.overw_inte << 4) | + (dev->dp8390.IMR.txerr_inte << 3) | + (dev->dp8390.IMR.rxerr_inte << 2) | + (dev->dp8390.IMR.tx_inte << 1) | + (dev->dp8390.IMR.rx_inte)); + if (val == 0x00) + threec503_interrupt(dev, 0); + break; + + case 0x08: /* RSAR0 */ + /* Clear out low byte and re-insert */ + dev->dp8390.remote_start &= 0xff00; + dev->dp8390.remote_start |= (val & 0xff); + dev->dp8390.remote_dma = dev->dp8390.remote_start; + break; + + case 0x09: /* RSAR1 */ + /* Clear out high byte and re-insert */ + dev->dp8390.remote_start &= 0x00ff; + dev->dp8390.remote_start |= ((val & 0xff) << 8); + dev->dp8390.remote_dma = dev->dp8390.remote_start; + break; + + case 0x0a: /* RBCR0 */ + /* Clear out low byte and re-insert */ + dev->dp8390.remote_bytes &= 0xff00; + dev->dp8390.remote_bytes |= (val & 0xff); + break; + + case 0x0b: /* RBCR1 */ + /* Clear out high byte and re-insert */ + dev->dp8390.remote_bytes &= 0x00ff; + dev->dp8390.remote_bytes |= ((val & 0xff) << 8); + break; + + case 0x0c: /* RCR */ + /* Check if the reserved bits are set */ + if (val & 0xc0) { + threec503_log("3Com503: RCR write, reserved bits set\n"); + } + + /* Set all other bit-fields */ + dev->dp8390.RCR.errors_ok = ((val & 0x01) == 0x01); + dev->dp8390.RCR.runts_ok = ((val & 0x02) == 0x02); + dev->dp8390.RCR.broadcast = ((val & 0x04) == 0x04); + dev->dp8390.RCR.multicast = ((val & 0x08) == 0x08); + dev->dp8390.RCR.promisc = ((val & 0x10) == 0x10); + dev->dp8390.RCR.monitor = ((val & 0x20) == 0x20); + + /* Monitor bit is a little suspicious... */ + if (val & 0x20) threec503_log("3Com503: RCR write, monitor bit set!\n"); + break; + + case 0x0d: /* TCR */ + /* Check reserved bits */ + if (val & 0xe0) threec503_log("3Com503: TCR write, reserved bits set\n"); + + /* Test loop mode (not supported) */ + if (val & 0x06) { + dev->dp8390.TCR.loop_cntl = (val & 0x6) >> 1; + threec503_log("3Com503: TCR write, loop mode %d not supported\n", + dev->dp8390.TCR.loop_cntl); + } else { + dev->dp8390.TCR.loop_cntl = 0; + } + + /* Inhibit-CRC not supported. */ + if (val & 0x01) threec503_log( + "3Com503: TCR write, inhibit-CRC not supported\n"); + + /* Auto-transmit disable very suspicious */ + if (val & 0x08) threec503_log( + "3Com503: TCR write, auto transmit disable not supported\n"); + + /* Allow collision-offset to be set, although not used */ + dev->dp8390.TCR.coll_prio = ((val & 0x08) == 0x08); + break; + + case 0x0e: /* DCR */ + /* the loopback mode is not suppported yet */ + if (! (val & 0x08)) threec503_log( + "3Com503: DCR write, loopback mode selected\n"); + + /* It is questionable to set longaddr and auto_rx, since + * they are not supported on the NE2000. Print a warning + * and continue. */ + if (val & 0x04) + threec503_log("3Com503: DCR write - LAS set ???\n"); + if (val & 0x10) + threec503_log("3Com503: DCR write - AR set ???\n"); + + /* Set other values. */ + dev->dp8390.DCR.wdsize = ((val & 0x01) == 0x01); + dev->dp8390.DCR.endian = ((val & 0x02) == 0x02); + dev->dp8390.DCR.longaddr = ((val & 0x04) == 0x04); /* illegal ? */ + dev->dp8390.DCR.loop = ((val & 0x08) == 0x08); + dev->dp8390.DCR.auto_rx = ((val & 0x10) == 0x10); /* also illegal ? */ + dev->dp8390.DCR.fifo_size = (val & 0x50) >> 5; + break; + + case 0x0f: /* IMR */ + /* Check for reserved bit */ + if (val & 0x80) + threec503_log("3Com503: IMR write, reserved bit set\n"); + + /* Set other values */ + dev->dp8390.IMR.rx_inte = ((val & 0x01) == 0x01); + dev->dp8390.IMR.tx_inte = ((val & 0x02) == 0x02); + dev->dp8390.IMR.rxerr_inte = ((val & 0x04) == 0x04); + dev->dp8390.IMR.txerr_inte = ((val & 0x08) == 0x08); + dev->dp8390.IMR.overw_inte = ((val & 0x10) == 0x10); + dev->dp8390.IMR.cofl_inte = ((val & 0x20) == 0x20); + dev->dp8390.IMR.rdma_inte = ((val & 0x40) == 0x40); + val2 = ((dev->dp8390.ISR.rdma_done << 6) | + (dev->dp8390.ISR.cnt_oflow << 5) | + (dev->dp8390.ISR.overwrite << 4) | + (dev->dp8390.ISR.tx_err << 3) | + (dev->dp8390.ISR.rx_err << 2) | + (dev->dp8390.ISR.pkt_tx << 1) | + (dev->dp8390.ISR.pkt_rx)); + if (((val & val2) & 0x7f) == 0) + threec503_interrupt(dev, 0); + else + threec503_interrupt(dev, 1); + break; + + default: + threec503_log("3Com503: Page0 write, bad register 0x%02x\n", + off); + break; + } +} + + +/* Handle reads/writes to the first page of the DS8390 register file. */ +static uint32_t +threec503_page1_read(threec503_t *dev, uint32_t off, unsigned int len) +{ + threec503_log("3Com503: Page1 read from register 0x%02x, len=%u\n", + off, len); + + switch(off) { + case 0x01: /* PAR0-5 */ + case 0x02: + case 0x03: + case 0x04: + case 0x05: + case 0x06: + return(dev->dp8390.physaddr[off - 1]); + + case 0x07: /* CURR */ + threec503_log("3Com503: returning current page: 0x%02x\n", + (dev->dp8390.curr_page)); + return(dev->dp8390.curr_page); + + case 0x08: /* MAR0-7 */ + case 0x09: + case 0x0a: + case 0x0b: + case 0x0c: + case 0x0d: + case 0x0e: + case 0x0f: + return(dev->dp8390.mchash[off - 8]); + + default: + threec503_log("3Com503: Page1 read register 0x%02x out of range\n", + off); + return(0); + } +} + + +static void +threec503_page1_write(threec503_t *dev, uint32_t off, uint32_t val, unsigned len) +{ + threec503_log("3Com503: Page1 write to register 0x%02x, len=%u, value=0x%04x\n", + off, len, val); + + switch(off) { + case 0x01: /* PAR0-5 */ + case 0x02: + case 0x03: + case 0x04: + case 0x05: + case 0x06: + dev->dp8390.physaddr[off - 1] = val; + if (off == 6) threec503_log( + "3Com503: physical address set to %02x:%02x:%02x:%02x:%02x:%02x\n", + dev->dp8390.physaddr[0], dev->dp8390.physaddr[1], + dev->dp8390.physaddr[2], dev->dp8390.physaddr[3], + dev->dp8390.physaddr[4], dev->dp8390.physaddr[5]); + break; + + case 0x07: /* CURR */ + dev->dp8390.curr_page = val; + break; + + case 0x08: /* MAR0-7 */ + case 0x09: + case 0x0a: + case 0x0b: + case 0x0c: + case 0x0d: + case 0x0e: + case 0x0f: + dev->dp8390.mchash[off - 8] = val; + break; + + default: + threec503_log("3Com503: Page1 write register 0x%02x out of range\n", + off); + break; + } +} + + +/* Handle reads/writes to the second page of the DS8390 register file. */ +static uint32_t +threec503_page2_read(threec503_t *dev, uint32_t off, unsigned int len) +{ + threec503_log("3Com503: Page2 read from register 0x%02x, len=%u\n", + off, len); + + switch(off) { + case 0x01: /* PSTART */ + return(dev->dp8390.page_start); + + case 0x02: /* PSTOP */ + return(dev->dp8390.page_stop); + + case 0x03: /* Remote Next-packet pointer */ + return(dev->dp8390.rempkt_ptr); + + case 0x04: /* TPSR */ + return(dev->dp8390.tx_page_start); + + case 0x05: /* Local Next-packet pointer */ + return(dev->dp8390.localpkt_ptr); + + case 0x06: /* Address counter (upper) */ + return(dev->dp8390.address_cnt >> 8); + + case 0x07: /* Address counter (lower) */ + return(dev->dp8390.address_cnt & 0xff); + + case 0x08: /* Reserved */ + case 0x09: + case 0x0a: + case 0x0b: + threec503_log("3Com503: reserved Page2 read - register 0x%02x\n", + off); + return(0xff); + + case 0x0c: /* RCR */ + return ((dev->dp8390.RCR.monitor << 5) | + (dev->dp8390.RCR.promisc << 4) | + (dev->dp8390.RCR.multicast << 3) | + (dev->dp8390.RCR.broadcast << 2) | + (dev->dp8390.RCR.runts_ok << 1) | + (dev->dp8390.RCR.errors_ok)); + + case 0x0d: /* TCR */ + return ((dev->dp8390.TCR.coll_prio << 4) | + (dev->dp8390.TCR.ext_stoptx << 3) | + ((dev->dp8390.TCR.loop_cntl & 0x3) << 1) | + (dev->dp8390.TCR.crc_disable)); + + case 0x0e: /* DCR */ + return (((dev->dp8390.DCR.fifo_size & 0x3) << 5) | + (dev->dp8390.DCR.auto_rx << 4) | + (dev->dp8390.DCR.loop << 3) | + (dev->dp8390.DCR.longaddr << 2) | + (dev->dp8390.DCR.endian << 1) | + (dev->dp8390.DCR.wdsize)); + + case 0x0f: /* IMR */ + return ((dev->dp8390.IMR.rdma_inte << 6) | + (dev->dp8390.IMR.cofl_inte << 5) | + (dev->dp8390.IMR.overw_inte << 4) | + (dev->dp8390.IMR.txerr_inte << 3) | + (dev->dp8390.IMR.rxerr_inte << 2) | + (dev->dp8390.IMR.tx_inte << 1) | + (dev->dp8390.IMR.rx_inte)); + + default: + threec503_log("3Com503: Page2 register 0x%02x out of range\n", + off); + break; + } + + return(0); +} + + +static void +threec503_page2_write(threec503_t *dev, uint32_t off, uint32_t val, unsigned len) +{ + /* Maybe all writes here should be BX_PANIC()'d, since they + affect internal operation, but let them through for now + and print a warning. */ + threec503_log("3Com503: Page2 write to register 0x%02x, len=%u, value=0x%04x\n", + off, len, val); + switch(off) { + case 0x01: /* CLDA0 */ + /* Clear out low byte and re-insert */ + dev->dp8390.local_dma &= 0xff00; + dev->dp8390.local_dma |= (val & 0xff); + break; + + case 0x02: /* CLDA1 */ + /* Clear out high byte and re-insert */ + dev->dp8390.local_dma &= 0x00ff; + dev->dp8390.local_dma |= ((val & 0xff) << 8); + break; + + case 0x03: /* Remote Next-pkt pointer */ + dev->dp8390.rempkt_ptr = val; + break; + + case 0x04: + threec503_log("page 2 write to reserved register 0x04\n"); + break; + + case 0x05: /* Local Next-packet pointer */ + dev->dp8390.localpkt_ptr = val; + break; + + case 0x06: /* Address counter (upper) */ + /* Clear out high byte and re-insert */ + dev->dp8390.address_cnt &= 0x00ff; + dev->dp8390.address_cnt |= ((val & 0xff) << 8); + break; + + case 0x07: /* Address counter (lower) */ + /* Clear out low byte and re-insert */ + dev->dp8390.address_cnt &= 0xff00; + dev->dp8390.address_cnt |= (val & 0xff); + break; + + case 0x08: + case 0x09: + case 0x0a: + case 0x0b: + case 0x0c: + case 0x0d: + case 0x0e: + case 0x0f: + threec503_log("3Com503: Page2 write to reserved register 0x%02x\n", + off); + break; + + default: + threec503_log("3Com503: Page2 write, illegal register 0x%02x\n", + off); + break; + } +} + + +/* Routines for handling reads/writes to the Command Register. */ +static uint32_t +threec503_read_cr(threec503_t *dev) +{ + uint32_t retval; + + retval = (((dev->dp8390.CR.pgsel & 0x03) << 6) | + ((dev->dp8390.CR.rdma_cmd & 0x07) << 3) | + (dev->dp8390.CR.tx_packet << 2) | + (dev->dp8390.CR.start << 1) | + (dev->dp8390.CR.stop)); + threec503_log("3Com503: read CR returns 0x%02x\n", retval); + + return(retval); +} + + +static void +threec503_write_cr(threec503_t *dev, uint32_t val) +{ + threec503_log("3Com503: wrote 0x%02x to CR\n", val); + + /* Validate remote-DMA */ + if ((val & 0x38) == 0x00) { + threec503_log("3Com503: CR write - invalid rDMA value 0\n"); + val |= 0x20; /* dma_cmd == 4 is a safe default */ + } + + /* Check for s/w reset */ + if (val & 0x01) { + dev->dp8390.ISR.reset = 1; + dev->dp8390.CR.stop = 1; + } else + dev->dp8390.CR.stop = 0; + + dev->dp8390.CR.rdma_cmd = (val & 0x38) >> 3; + + /* If start command issued, the RST bit in the ISR */ + /* must be cleared */ + if ((val & 0x02) && !dev->dp8390.CR.start) + dev->dp8390.ISR.reset = 0; + + dev->dp8390.CR.start = ((val & 0x02) == 0x02); + dev->dp8390.CR.pgsel = (val & 0xc0) >> 6; + + /* Check for send-packet command */ + if (dev->dp8390.CR.rdma_cmd == 3) { + /* Set up DMA read from receive ring */ + dev->dp8390.remote_start = dev->dp8390.remote_dma = dev->dp8390.bound_ptr * 256; + dev->dp8390.remote_bytes = (uint16_t) threec503_chipmem_read(dev, dev->dp8390.bound_ptr * 256 + 2, 2); + threec503_log("3Com503: sending buffer %x length %d\n", + dev->dp8390.remote_start, dev->dp8390.remote_bytes); + } + + /* Check for start-tx */ + if ((val & 0x04) && dev->dp8390.TCR.loop_cntl) { + if (dev->dp8390.TCR.loop_cntl != 1) { + threec503_log("3Com503: loop mode %d not supported\n", + dev->dp8390.TCR.loop_cntl); + } else { + threec503_rx(dev, + &dev->dp8390.mem[dev->dp8390.tx_page_start*256 - DP8390_WORD_MEMSTART], + dev->dp8390.tx_bytes); + } + } else if (val & 0x04) { + if (dev->dp8390.CR.stop || (!dev->dp8390.CR.start)) { + if (dev->dp8390.tx_bytes == 0) /* njh@bandsman.co.uk */ + return; /* Solaris9 probe */ + threec503_log("3Com503: CR write - tx start, dev in reset\n"); + } + + if (dev->dp8390.tx_bytes == 0) + threec503_log("3Com503: CR write - tx start, tx bytes == 0\n"); + + /* Send the packet to the system driver */ + dev->dp8390.CR.tx_packet = 1; + network_tx(&dev->dp8390.mem[dev->dp8390.tx_page_start*256 - DP8390_WORD_MEMSTART], + dev->dp8390.tx_bytes); + + /* some more debug */ + if (dev->dp8390.tx_timer_active) + threec503_log("3Com503: CR write, tx timer still active\n"); + + threec503_tx(dev, val); + } + + /* Linux probes for an interrupt by setting up a remote-DMA read + * of 0 bytes with remote-DMA completion interrupts enabled. + * Detect this here */ + if (dev->dp8390.CR.rdma_cmd == 0x01 && dev->dp8390.CR.start && dev->dp8390.remote_bytes == 0) { + dev->dp8390.ISR.rdma_done = 1; + if (dev->dp8390.IMR.rdma_inte) { + threec503_interrupt(dev, 1); + threec503_interrupt(dev, 0); + } + } +} + + +static uint8_t +threec503_nic_lo_read(uint16_t addr, void *priv) +{ + threec503_t *dev = (threec503_t *)priv; + uint8_t retval = 0; + int off = addr - dev->base_address; + + switch ((dev->regs.ctrl >> 2) & 3) { + case 0x00: + threec503_log("Read offset=%04x\n", off); + if (off == 0x00) + retval = threec503_read_cr(dev); + else switch(dev->dp8390.CR.pgsel) { + case 0x00: + retval = threec503_page0_read(dev, off, 1); + break; + + case 0x01: + retval = threec503_page1_read(dev, off, 1); + break; + + case 0x02: + retval = threec503_page2_read(dev, off, 1); + break; + + case 0x03: + retval = 0xff; + break; + } + break; + + case 0x01: + retval = dev->prom[off]; + break; + + case 0x02: + retval = dev->prom[off + 0x10]; + break; + + case 0x03: + retval = 0xff; + break; + } + + return(retval); +} + + +static void +threec503_nic_lo_write(uint16_t addr, uint8_t val, void *priv) +{ + threec503_t *dev = (threec503_t *)priv; + int off = addr - dev->base_address; + + switch ((dev->regs.ctrl >> 2) & 3) { + case 0x00: + /* The high 16 bytes of i/o space are for the ne2000 asic - + the low 16 bytes are for the DS8390, with the current + page being selected by the PS0,PS1 registers in the + command register */ + if (off == 0x00) + threec503_write_cr(dev, val); + else switch(dev->dp8390.CR.pgsel) { + case 0x00: + threec503_page0_write(dev, off, val, 1); + break; + + case 0x01: + threec503_page1_write(dev, off, val, 1); + break; + + case 0x02: + threec503_page2_write(dev, off, val, 1); + break; + + case 0x03: + break; + } + break; + + case 0x01: + case 0x02: + case 0x03: + break; + } + + threec503_log("3Com503: write addr %x, value %x\n", addr, val); +} + + +static uint8_t +threec503_nic_hi_read(uint16_t addr, void *priv) +{ + threec503_t *dev = (threec503_t *)priv; + + threec503_log("3Com503: Read GA address=%04x\n", addr); + + switch (addr & 0x0f) { + case 0x00: + return dev->regs.pstr; + + case 0x01: + return dev->regs.pspr; + + case 0x02: + return dev->regs.dqtr; + + case 0x03: + switch (dev->base_address) { + default: + case 0x300: + dev->regs.bcfr = 0x80; + break; + + case 0x310: + dev->regs.bcfr = 0x40; + break; + + case 0x330: + dev->regs.bcfr = 0x20; + break; + + case 0x350: + dev->regs.bcfr = 0x10; + break; + + case 0x250: + dev->regs.bcfr = 0x08; + break; + + case 0x280: + dev->regs.bcfr = 0x04; + break; + + case 0x2a0: + dev->regs.bcfr = 0x02; + break; + + case 0x2e0: + dev->regs.bcfr = 0x01; + break; + } + + return dev->regs.bcfr; + break; + + case 0x04: + switch (dev->bios_addr) { + case 0xdc000: + dev->regs.pcfr = 0x80; + break; + + case 0xd8000: + dev->regs.pcfr = 0x40; + break; + + case 0xcc000: + dev->regs.pcfr = 0x20; + break; + + case 0xc8000: + dev->regs.pcfr = 0x10; + break; + } + + return dev->regs.pcfr; + break; + + case 0x05: + return dev->regs.gacfr; + + case 0x06: + return dev->regs.ctrl; + + case 0x07: + return dev->regs.streg; + + case 0x08: + return dev->regs.idcfr; + + case 0x09: + return (dev->regs.da >> 8); + + case 0x0a: + return (dev->regs.da & 0xff); + + case 0x0b: + return (dev->regs.vptr >> 12) & 0xff; + + case 0x0c: + return (dev->regs.vptr >> 4) & 0xff; + + case 0x0d: + return (dev->regs.vptr & 0x0f) << 4; + + case 0x0e: + case 0x0f: + if (!(dev->regs.ctrl & 0x80)) + return 0xff; + + threec503_set_drq(dev); + + return threec503_chipmem_read(dev, dev->regs.da++, 1); + } + + return 0; +} + + +static void +threec503_nic_hi_write(uint16_t addr, uint8_t val, void *priv) +{ + threec503_t *dev = (threec503_t *)priv; + + threec503_log("3Com503: Write GA address=%04x, val=%04x\n", addr, val); + + switch (addr & 0x0f) { + case 0x00: + dev->regs.pstr = val; + break; + + case 0x01: + dev->regs.pspr = val; + break; + + case 0x02: + dev->regs.dqtr = val; + break; + + case 0x05: + if ((dev->regs.gacfr & 0x0f) != (val & 0x0f)) { + mem_mapping_disable(&dev->ram_mapping); + + switch (val & 0x0f) { + case 0: /*ROM mapping*/ + /* FIXME: Implement this when a BIOS is found/generated. */ + break; + + case 9: /*RAM mapping*/ + mem_mapping_enable(&dev->ram_mapping); + break; + + default: /*No ROM mapping*/ + break; + } + } + + if (!(val & 0x80)) + threec503_interrupt(dev, 1); + else + threec503_interrupt(dev, 0); + + dev->regs.gacfr = val; + break; + + case 0x06: + if (val & 1) { + threec503_reset(dev); + dev->dp8390.ISR.reset = 1; + dev->regs.ctrl = 0x0b; + return; + } + + if ((val & 0x80) != (dev->regs.ctrl & 0x80)) { + if (val & 0x80) + dev->regs.streg |= 0x88; + else + dev->regs.streg &= ~0x88; + dev->regs.streg &= ~0x10; + } + dev->regs.ctrl = val; + break; + + case 0x08: + switch (val & 0xf0) { + case 0x00: + case 0x10: + case 0x20: + case 0x40: + case 0x80: + dev->regs.idcfr = (dev->regs.idcfr & 0x0f) | (val & 0xf0); + break; + + default: + threec503_log("Trying to set multiple IRQs: %02x\n", val); + break; + } + + switch (val & 0x0f) { + case 0x00: + case 0x01: + case 0x02: + case 0x04: + dev->regs.idcfr = (dev->regs.idcfr & 0xf0) | (val & 0x0f); + break; + + case 0x08: + break; + + default: + threec503_log("Trying to set multiple DMA channels: %02x\n", val); + break; + } + break; + + case 0x09: + dev->regs.da = (val << 8) | (dev->regs.da & 0xff); + break; + + case 0x0a: + dev->regs.da = (dev->regs.da & 0xff00) | val; + break; + + case 0x0b: + dev->regs.vptr = (val << 12) | (dev->regs.vptr & 0xfff); + break; + + case 0x0c: + dev->regs.vptr = (val << 4) | (dev->regs.vptr & 0xff00f); + break; + + case 0x0d: + dev->regs.vptr = (val << 4) | (dev->regs.vptr & 0xffff0); + break; + + case 0x0e: + case 0x0f: + if (!(dev->regs.ctrl & 0x80)) + return; + + threec503_set_drq(dev); + + threec503_chipmem_write(dev, dev->regs.da++, val, 1); + break; + } +} + + +static void +threec503_nic_ioremove(threec503_t *dev, uint16_t addr) +{ + io_removehandler(addr, 0x10, + threec503_nic_lo_read, NULL, NULL, + threec503_nic_lo_write, NULL, NULL, dev); + + io_removehandler(addr+0x400, 0x10, + threec503_nic_hi_read, NULL, NULL, + threec503_nic_hi_write, NULL, NULL, dev); +} + + +static void +threec503_nic_ioset(threec503_t *dev, uint16_t addr) +{ + io_sethandler(addr, 0x10, + threec503_nic_lo_read, NULL, NULL, + threec503_nic_lo_write, NULL, NULL, dev); + + io_sethandler(addr+0x400, 0x10, + threec503_nic_hi_read, NULL, NULL, + threec503_nic_hi_write, NULL, NULL, dev); +} + + +static void +threec503_tx(threec503_t *dev, uint32_t val) +{ + dev->dp8390.CR.tx_packet = 0; + dev->dp8390.TSR.tx_ok = 1; + dev->dp8390.ISR.pkt_tx = 1; + + /* Generate an interrupt if not masked */ + if (dev->dp8390.IMR.tx_inte) + threec503_interrupt(dev, 1); + dev->dp8390.tx_timer_active = 0; +} + + +/* + * Called by the platform-specific code when an Ethernet frame + * has been received. The destination address is tested to see + * if it should be accepted, and if the RX ring has enough room, + * it is copied into it and the receive process is updated. + */ +static void +threec503_rx(void *priv, uint8_t *buf, int io_len) +{ + static uint8_t bcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff}; + threec503_t *dev = (threec503_t *)priv; + uint8_t pkthdr[4]; + uint8_t *startptr; + int rx_pages, avail; + int idx, nextpage; + int endbytes; + + /* FIXME: move to upper layer */ + ui_sb_update_icon(SB_NETWORK, 1); + + if (io_len != 60) + threec503_log("3Com503: rx_frame with length %d\n", io_len); + + if ((dev->dp8390.CR.stop != 0) || (dev->dp8390.page_start == 0)) return; + + /* + * Add the pkt header + CRC to the length, and work + * out how many 256-byte pages the frame would occupy. + */ + rx_pages = (io_len + sizeof(pkthdr) + sizeof(uint32_t) + 255)/256; + if (dev->dp8390.curr_page < dev->dp8390.bound_ptr) { + avail = dev->dp8390.bound_ptr - dev->dp8390.curr_page; + } else { + avail = (dev->dp8390.page_stop - dev->dp8390.page_start) - + (dev->dp8390.curr_page - dev->dp8390.bound_ptr); + } + + /* + * Avoid getting into a buffer overflow condition by + * not attempting to do partial receives. The emulation + * to handle this condition seems particularly painful. + */ + if ((avail < rx_pages) +#if NE2K_NEVER_FULL_RING + || (avail == rx_pages) +#endif + ) { + threec503_log("3Com503: no space\n"); + + /* FIXME: move to upper layer */ + ui_sb_update_icon(SB_NETWORK, 0); + return; + } + + if ((io_len < 40/*60*/) && !dev->dp8390.RCR.runts_ok) { + threec503_log("3Com503: rejected small packet, length %d\n", io_len); + + /* FIXME: move to upper layer */ + ui_sb_update_icon(SB_NETWORK, 0); + return; + } + + /* Some computers don't care... */ + if (io_len < 60) + io_len = 60; + + threec503_log("3Com503: RX %x:%x:%x:%x:%x:%x > %x:%x:%x:%x:%x:%x len %d\n", + buf[6], buf[7], buf[8], buf[9], buf[10], buf[11], + buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], + io_len); + + /* Do address filtering if not in promiscuous mode. */ + if (! dev->dp8390.RCR.promisc) { + /* If this is a broadcast frame.. */ + if (! memcmp(buf, bcast_addr, 6)) { + /* Broadcast not enabled, we're done. */ + if (! dev->dp8390.RCR.broadcast) { + threec503_log("3Com503: RX BC disabled\n"); + + /* FIXME: move to upper layer */ + ui_sb_update_icon(SB_NETWORK, 0); + return; + } + } + + /* If this is a multicast frame.. */ + else if (buf[0] & 0x01) { + /* Multicast not enabled, we're done. */ + if (! dev->dp8390.RCR.multicast) { +#if 1 + threec503_log("3Com503: RX MC disabled\n"); +#endif + + /* FIXME: move to upper layer */ + ui_sb_update_icon(SB_NETWORK, 0); + return; + } + + /* Are we listening to this multicast address? */ + idx = mcast_index(buf); + if (! (dev->dp8390.mchash[idx>>3] & (1<<(idx&0x7)))) { + threec503_log("3Com503: RX MC not listed\n"); + + /* FIXME: move to upper layer */ + ui_sb_update_icon(SB_NETWORK, 0); + return; + } + } + + /* Unicast, must be for us.. */ + else if (memcmp(buf, dev->dp8390.physaddr, 6)) return; + } else + threec503_log("3Com503: RX promiscuous receive\n"); + + nextpage = dev->dp8390.curr_page + rx_pages; + if (nextpage >= dev->dp8390.page_stop) + nextpage -= (dev->dp8390.page_stop - dev->dp8390.page_start); + + /* Set up packet header. */ + pkthdr[0] = 0x01; /* RXOK - packet is OK */ + if (buf[0] & 0x01) + pkthdr[0] |= 0x20; /* MULTICAST packet */ + pkthdr[1] = nextpage; /* ptr to next packet */ + pkthdr[2] = (io_len + sizeof(pkthdr))&0xff; /* length-low */ + pkthdr[3] = (io_len + sizeof(pkthdr))>>8; /* length-hi */ + threec503_log("3Com503: RX pkthdr [%02x %02x %02x %02x]\n", + pkthdr[0], pkthdr[1], pkthdr[2], pkthdr[3]); + + /* Copy into buffer, update curpage, and signal interrupt if config'd */ + startptr = &dev->dp8390.mem[(dev->dp8390.curr_page * 256) - DP8390_WORD_MEMSTART]; + memcpy(startptr, pkthdr, sizeof(pkthdr)); + if ((nextpage > dev->dp8390.curr_page) || + ((dev->dp8390.curr_page + rx_pages) == dev->dp8390.page_stop)) { + memcpy(startptr+sizeof(pkthdr), buf, io_len); + } else { + endbytes = (dev->dp8390.page_stop - dev->dp8390.curr_page) * 256; + memcpy(startptr+sizeof(pkthdr), buf, endbytes-sizeof(pkthdr)); + startptr = &dev->dp8390.mem[(dev->dp8390.page_start * 256) - DP8390_WORD_MEMSTART]; + memcpy(startptr, buf+endbytes-sizeof(pkthdr), io_len-endbytes+8); + } + dev->dp8390.curr_page = nextpage; + + dev->dp8390.RSR.rx_ok = 1; + dev->dp8390.RSR.rx_mbit = (buf[0] & 0x01) ? 1 : 0; + dev->dp8390.ISR.pkt_rx = 1; + + if (dev->dp8390.IMR.rx_inte) + threec503_interrupt(dev, 1); + + /* FIXME: move to upper layer */ + ui_sb_update_icon(SB_NETWORK, 0); +} + + +static void * +threec503_nic_init(const device_t *info) +{ + uint32_t mac; + threec503_t *dev; + + dev = malloc(sizeof(threec503_t)); + memset(dev, 0x00, sizeof(threec503_t)); + dev->maclocal[0] = 0x02; /* 02:60:8C (3Com OID) */ + dev->maclocal[1] = 0x60; + dev->maclocal[2] = 0x8C; + + dev->base_address = device_get_config_hex16("base"); + dev->base_irq = device_get_config_int("irq"); + dev->dma_channel = device_get_config_int("dma"); + dev->bios_addr = device_get_config_hex20("bios_addr"); + + /* See if we have a local MAC address configured. */ + mac = device_get_config_mac("mac", -1); + + /* + * Make this device known to the I/O system. + * PnP and PCI devices start with address spaces inactive. + */ + threec503_nic_ioset(dev, dev->base_address); + + /* Set up our BIA. */ + if (mac & 0xff000000) { + /* Generate new local MAC. */ + dev->maclocal[3] = random_generate(); + dev->maclocal[4] = random_generate(); + dev->maclocal[5] = random_generate(); + mac = (((int) dev->maclocal[3]) << 16); + mac |= (((int) dev->maclocal[4]) << 8); + mac |= ((int) dev->maclocal[5]); + device_set_config_mac("mac", mac); + } else { + dev->maclocal[3] = (mac>>16) & 0xff; + dev->maclocal[4] = (mac>>8) & 0xff; + dev->maclocal[5] = (mac & 0xff); + } + memcpy(dev->dp8390.physaddr, dev->maclocal, sizeof(dev->maclocal)); + + threec503_log("I/O=%04x, IRQ=%d, MAC=%02x:%02x:%02x:%02x:%02x:%02x\n", + dev->base_address, dev->base_irq, + dev->dp8390.physaddr[0], dev->dp8390.physaddr[1], dev->dp8390.physaddr[2], + dev->dp8390.physaddr[3], dev->dp8390.physaddr[4], dev->dp8390.physaddr[5]); + + /* Reset the board. */ + threec503_reset(dev); + + /* Attach ourselves to the network module. */ + network_attach(dev, dev->dp8390.physaddr, threec503_rx); + + /* Map this system into the memory map. */ + mem_mapping_add(&dev->ram_mapping, dev->bios_addr, 0x4000, + threec503_ram_read, NULL, NULL, + threec503_ram_write, NULL, NULL, + NULL, MEM_MAPPING_EXTERNAL, dev); + mem_mapping_disable(&dev->ram_mapping); + + return(dev); +} + + +static void +threec503_nic_close(void *priv) +{ + threec503_t *dev = (threec503_t *)priv; + + /* Make sure the platform layer is shut down. */ + network_close(); + + threec503_nic_ioremove(dev, dev->base_address); + + threec503_log("3Com503: closed\n"); + + free(dev); +} + + +static const device_config_t threec503_config[] = +{ + { + "base", "Address", CONFIG_HEX16, "", 0x300, + { + { + "0x250", 0x250 + }, + { + "0x280", 0x280 + }, + { + "0x2a0", 0x2a0 + }, + { + "0x2e0", 0x2e0 + }, + { + "0x300", 0x300 + }, + { + "0x310", 0x310 + }, + { + "0x330", 0x330 + }, + { + "0x350", 0x350 + }, + { + "", 0 + } + }, + { { NULL, { NULL } } }, + { 0, 0, 0 } + }, + { + "irq", "IRQ", CONFIG_SELECTION, "", 3, + { + { + "IRQ 2", 2 + }, + { + "IRQ 3", 3 + }, + { + "IRQ 4", 4 + }, + { + "IRQ 5", 5 + }, + { + "", 0 + } + }, + { { NULL, { NULL } } }, + { 0, 0, 0 } + }, + { + "dma", "DMA", CONFIG_SELECTION, "", 3, + { + { + "DMA 1", 1 + }, + { + "DMA 2", 2 + }, + { + "DMA 3", 3 + }, + { + "", 0 + } + }, + { { NULL, { NULL } } }, + { 0, 0, 0 } + }, + { + "mac", "MAC Address", CONFIG_MAC, "", -1, + { + { + "", 0 + } + }, + { { NULL, { NULL } } }, + { 0, 0, 0 } + }, + { + "bios_addr", "BIOS address", CONFIG_HEX20, "", 0xCC000, + { + { + "DC00", 0xDC000 + }, + { + "D800", 0xD8000 + }, + { + "C800", 0xC8000 + }, + { + "CC00", 0xCC000 + }, + { + "", 0 + } + }, + { { NULL, { NULL } } }, + { 0, 0, 0 } + }, + { + "", "", -1, "", -1, + { + { + "", 0 + } + }, + { { NULL, { NULL } } }, + { 0, 0, 0 } + } +}; + + +const device_t threec503_device = { + "3Com EtherLink II", + DEVICE_ISA, + 0, + threec503_nic_init, threec503_nic_close, NULL, + NULL, NULL, NULL, + threec503_config +}; diff --git a/src/network/net_3c503.h b/src/network/net_3c503.h new file mode 100644 index 000000000..6cc656b9f --- /dev/null +++ b/src/network/net_3c503.h @@ -0,0 +1,7 @@ +#ifndef NET_3C503_H +# define NET_3C503_H + +extern const device_t threec503_device; + + +#endif /*NET_3C503_H*/ diff --git a/src/network/net_dp8390.c b/src/network/net_dp8390.c new file mode 100644 index 000000000..ee24ecd1e --- /dev/null +++ b/src/network/net_dp8390.c @@ -0,0 +1,35 @@ +#include +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H + +/* + * Return the 6-bit index into the multicast + * table. Stolen unashamedly from FreeBSD's if_ed.c + */ +int +mcast_index(const void *dst) +{ +#define POLYNOMIAL 0x04c11db6 + uint32_t crc = 0xffffffffL; + int carry, i, j; + uint8_t b; + uint8_t *ep = (uint8_t *)dst; + + for (i=6; --i>=0;) { + b = *ep++; + for (j = 8; --j >= 0;) { + carry = ((crc & 0x80000000L) ? 1 : 0) ^ (b & 0x01); + crc <<= 1; + b >>= 1; + if (carry) + crc = ((crc ^ POLYNOMIAL) | carry); + } + } + return(crc >> 26); +#undef POLYNOMIAL +} diff --git a/src/network/net_dp8390.h b/src/network/net_dp8390.h new file mode 100644 index 000000000..16b2d0188 --- /dev/null +++ b/src/network/net_dp8390.h @@ -0,0 +1,158 @@ +#ifndef NET_DP8390_H +# define NET_DP8390_H + +/* Never completely fill the ne2k ring so that we never + hit the unclear completely full buffer condition. */ +#define DP8390_NEVER_FULL_RING (1) + +#define DP8390_DWORD_MEMSIZ (32*1024) +#define DP8390_DWORD_MEMSTART (16*1024) +#define DP8390_DWORD_MEMEND (DP8390_DWORD_MEMSTART+DP8390_DWORD_MEMSIZ) + +#define DP8390_WORD_MEMSIZ (16*1024) +#define DP8390_WORD_MEMSTART (8*1024) +#define DP8390_WORD_MEMEND (DP8390_WORD_MEMSTART+DP8390_WORD_MEMSIZ) + +typedef struct { + /* Page 0 */ + + /* Command Register - 00h read/write */ + struct CR_t { + int stop; /* STP - Software Reset command */ + int start; /* START - start the NIC */ + int tx_packet; /* TXP - initiate packet transmission */ + uint8_t rdma_cmd; /* RD0,RD1,RD2 - Remote DMA command */ + uint8_t pgsel; /* PS0,PS1 - Page select */ + } CR; + + /* Interrupt Status Register - 07h read/write */ + struct ISR_t { + int pkt_rx; /* PRX - packet received with no errors */ + int pkt_tx; /* PTX - packet txed with no errors */ + int rx_err; /* RXE - packet rxed with 1 or more errors */ + int tx_err; /* TXE - packet txed " " " " " */ + int overwrite; /* OVW - rx buffer resources exhausted */ + int cnt_oflow; /* CNT - network tally counter MSB's set */ + int rdma_done; /* RDC - remote DMA complete */ + int reset; /* RST - reset status */ + } ISR; + + /* Interrupt Mask Register - 0fh write */ + struct IMR_t { + int rx_inte; /* PRXE - packet rx interrupt enable */ + int tx_inte; /* PTXE - packet tx interrput enable */ + int rxerr_inte; /* RXEE - rx error interrupt enable */ + int txerr_inte; /* TXEE - tx error interrupt enable */ + int overw_inte; /* OVWE - overwrite warn int enable */ + int cofl_inte; /* CNTE - counter o'flow int enable */ + int rdma_inte; /* RDCE - remote DMA complete int enable */ + int reserved; /* D7 - reserved */ + } IMR; + + /* Data Configuration Register - 0eh write */ + struct DCR_t { + int wdsize; /* WTS - 8/16-bit select */ + int endian; /* BOS - byte-order select */ + int longaddr; /* LAS - long-address select */ + int loop; /* LS - loopback select */ + int auto_rx; /* AR - auto-remove rx pkts with remote DMA */ + uint8_t fifo_size; /* FT0,FT1 - fifo threshold */ + } DCR; + + /* Transmit Configuration Register - 0dh write */ + struct TCR_t { + int crc_disable; /* CRC - inhibit tx CRC */ + uint8_t loop_cntl; /* LB0,LB1 - loopback control */ + int ext_stoptx; /* ATD - allow tx disable by external mcast */ + int coll_prio; /* OFST - backoff algorithm select */ + uint8_t reserved; /* D5,D6,D7 - reserved */ + } TCR; + + /* Transmit Status Register - 04h read */ + struct TSR_t { + int tx_ok; /* PTX - tx complete without error */ + int reserved; /* D1 - reserved */ + int collided; /* COL - tx collided >= 1 times */ + int aborted; /* ABT - aborted due to excessive collisions */ + int no_carrier; /* CRS - carrier-sense lost */ + int fifo_ur; /* FU - FIFO underrun */ + int cd_hbeat; /* CDH - no tx cd-heartbeat from transceiver */ + int ow_coll; /* OWC - out-of-window collision */ + } TSR; + + /* Receive Configuration Register - 0ch write */ + struct RCR_t { + int errors_ok; /* SEP - accept pkts with rx errors */ + int runts_ok; /* AR - accept < 64-byte runts */ + int broadcast; /* AB - accept eth broadcast address */ + int multicast; /* AM - check mcast hash array */ + int promisc; /* PRO - accept all packets */ + int monitor; /* MON - check pkts, but don't rx */ + uint8_t reserved; /* D6,D7 - reserved */ + } RCR; + + /* Receive Status Register - 0ch read */ + struct RSR_t { + int rx_ok; /* PRX - rx complete without error */ + int bad_crc; /* CRC - Bad CRC detected */ + int bad_falign; /* FAE - frame alignment error */ + int fifo_or; /* FO - FIFO overrun */ + int rx_missed; /* MPA - missed packet error */ + int rx_mbit; /* PHY - unicast or mcast/bcast address match */ + int rx_disabled; /* DIS - set when in monitor mode */ + int deferred; /* DFR - collision active */ + } RSR; + + uint16_t local_dma; /* 01,02h read ; current local DMA addr */ + uint8_t page_start; /* 01h write ; page start regr */ + uint8_t page_stop; /* 02h write ; page stop regr */ + uint8_t bound_ptr; /* 03h read/write ; boundary pointer */ + uint8_t tx_page_start; /* 04h write ; transmit page start reg */ + uint8_t num_coll; /* 05h read ; number-of-collisions reg */ + uint16_t tx_bytes; /* 05,06h write ; transmit byte-count reg */ + uint8_t fifo; /* 06h read ; FIFO */ + uint16_t remote_dma; /* 08,09h read ; current remote DMA addr */ + uint16_t remote_start; /* 08,09h write ; remote start address reg */ + uint16_t remote_bytes; /* 0a,0bh write ; remote byte-count reg */ + uint8_t tallycnt_0; /* 0dh read ; tally ctr 0 (frame align errs) */ + uint8_t tallycnt_1; /* 0eh read ; tally ctr 1 (CRC errors) */ + uint8_t tallycnt_2; /* 0fh read ; tally ctr 2 (missed pkt errs) */ + + /* Page 1 */ + + /* Command Register 00h (repeated) */ + + uint8_t physaddr[6]; /* 01-06h read/write ; MAC address */ + uint8_t curr_page; /* 07h read/write ; current page register */ + uint8_t mchash[8]; /* 08-0fh read/write ; multicast hash array */ + + /* Page 2 - diagnostic use only */ + + /* Command Register 00h (repeated) */ + + /* Page Start Register 01h read (repeated) + * Page Stop Register 02h read (repeated) + * Current Local DMA Address 01,02h write (repeated) + * Transmit Page start address 04h read (repeated) + * Receive Configuration Register 0ch read (repeated) + * Transmit Configuration Register 0dh read (repeated) + * Data Configuration Register 0eh read (repeated) + * Interrupt Mask Register 0fh read (repeated) + */ + uint8_t rempkt_ptr; /* 03h read/write ; rmt next-pkt ptr */ + uint8_t localpkt_ptr; /* 05h read/write ; lcl next-pkt ptr */ + uint16_t address_cnt; /* 06,07h read/write ; address cter */ + + /* Page 3 - should never be modified. */ + + /* Novell ASIC state */ + uint8_t mem[DP8390_DWORD_MEMSIZ]; /* on-chip packet memory */ + + int tx_timer_index; + int tx_timer_active; + +} dp8390_t; + +extern int mcast_index(const void *dst); + +#endif /*NET_DP8390_H*/ diff --git a/src/network/net_ne2000.c b/src/network/net_ne2000.c index ea446743b..43a7b347f 100644 --- a/src/network/net_ne2000.c +++ b/src/network/net_ne2000.c @@ -63,6 +63,7 @@ #include "../device.h" #include "../ui.h" #include "network.h" +#include "net_dp8390.h" #include "net_ne2000.h" #include "bswap.h" @@ -89,18 +90,6 @@ enum { #define PCI_REGSIZE 256 /* size of PCI space */ -/* Never completely fill the ne2k ring so that we never - hit the unclear completely full buffer condition. */ -#define NE2K_NEVER_FULL_RING (1) - -#define NE2K_MEMSIZ (32*1024) -#define NE2K_MEMSTART (16*1024) -#define NE2K_MEMEND (NE2K_MEMSTART+NE2K_MEMSIZ) - -#define NE1K_MEMSIZ (16*1024) -#define NE1K_MEMSTART (8*1024) -#define NE1K_MEMEND (NE1K_MEMSTART+NE1K_MEMSIZ) - uint8_t pnp_init_key[32] = { 0x6A, 0xB5, 0xDA, 0xED, 0xF6, 0xFB, 0x7D, 0xBE, 0xDF, 0x6F, 0x37, 0x1B, 0x0D, 0x86, 0xC3, 0x61, 0xB0, 0x58, 0x2C, 0x16, 0x8B, 0x45, 0xA2, 0xD1, @@ -108,141 +97,8 @@ uint8_t pnp_init_key[32] = { 0x6A, 0xB5, 0xDA, 0xED, 0xF6, 0xFB, 0x7D, 0xBE, typedef struct { - /* Page 0 */ - - /* Command Register - 00h read/write */ - struct CR_t { - int stop; /* STP - Software Reset command */ - int start; /* START - start the NIC */ - int tx_packet; /* TXP - initiate packet transmission */ - uint8_t rdma_cmd; /* RD0,RD1,RD2 - Remote DMA command */ - uint8_t pgsel; /* PS0,PS1 - Page select */ - } CR; - - /* Interrupt Status Register - 07h read/write */ - struct ISR_t { - int pkt_rx; /* PRX - packet received with no errors */ - int pkt_tx; /* PTX - packet txed with no errors */ - int rx_err; /* RXE - packet rxed with 1 or more errors */ - int tx_err; /* TXE - packet txed " " " " " */ - int overwrite; /* OVW - rx buffer resources exhausted */ - int cnt_oflow; /* CNT - network tally counter MSB's set */ - int rdma_done; /* RDC - remote DMA complete */ - int reset; /* RST - reset status */ - } ISR; - - /* Interrupt Mask Register - 0fh write */ - struct IMR_t { - int rx_inte; /* PRXE - packet rx interrupt enable */ - int tx_inte; /* PTXE - packet tx interrput enable */ - int rxerr_inte; /* RXEE - rx error interrupt enable */ - int txerr_inte; /* TXEE - tx error interrupt enable */ - int overw_inte; /* OVWE - overwrite warn int enable */ - int cofl_inte; /* CNTE - counter o'flow int enable */ - int rdma_inte; /* RDCE - remote DMA complete int enable */ - int reserved; /* D7 - reserved */ - } IMR; - - /* Data Configuration Register - 0eh write */ - struct DCR_t { - int wdsize; /* WTS - 8/16-bit select */ - int endian; /* BOS - byte-order select */ - int longaddr; /* LAS - long-address select */ - int loop; /* LS - loopback select */ - int auto_rx; /* AR - auto-remove rx pkts with remote DMA */ - uint8_t fifo_size; /* FT0,FT1 - fifo threshold */ - } DCR; - - /* Transmit Configuration Register - 0dh write */ - struct TCR_t { - int crc_disable; /* CRC - inhibit tx CRC */ - uint8_t loop_cntl; /* LB0,LB1 - loopback control */ - int ext_stoptx; /* ATD - allow tx disable by external mcast */ - int coll_prio; /* OFST - backoff algorithm select */ - uint8_t reserved; /* D5,D6,D7 - reserved */ - } TCR; - - /* Transmit Status Register - 04h read */ - struct TSR_t { - int tx_ok; /* PTX - tx complete without error */ - int reserved; /* D1 - reserved */ - int collided; /* COL - tx collided >= 1 times */ - int aborted; /* ABT - aborted due to excessive collisions */ - int no_carrier; /* CRS - carrier-sense lost */ - int fifo_ur; /* FU - FIFO underrun */ - int cd_hbeat; /* CDH - no tx cd-heartbeat from transceiver */ - int ow_coll; /* OWC - out-of-window collision */ - } TSR; - - /* Receive Configuration Register - 0ch write */ - struct RCR_t { - int errors_ok; /* SEP - accept pkts with rx errors */ - int runts_ok; /* AR - accept < 64-byte runts */ - int broadcast; /* AB - accept eth broadcast address */ - int multicast; /* AM - check mcast hash array */ - int promisc; /* PRO - accept all packets */ - int monitor; /* MON - check pkts, but don't rx */ - uint8_t reserved; /* D6,D7 - reserved */ - } RCR; - - /* Receive Status Register - 0ch read */ - struct RSR_t { - int rx_ok; /* PRX - rx complete without error */ - int bad_crc; /* CRC - Bad CRC detected */ - int bad_falign; /* FAE - frame alignment error */ - int fifo_or; /* FO - FIFO overrun */ - int rx_missed; /* MPA - missed packet error */ - int rx_mbit; /* PHY - unicast or mcast/bcast address match */ - int rx_disabled; /* DIS - set when in monitor mode */ - int deferred; /* DFR - collision active */ - } RSR; - - uint16_t local_dma; /* 01,02h read ; current local DMA addr */ - uint8_t page_start; /* 01h write ; page start regr */ - uint8_t page_stop; /* 02h write ; page stop regr */ - uint8_t bound_ptr; /* 03h read/write ; boundary pointer */ - uint8_t tx_page_start; /* 04h write ; transmit page start reg */ - uint8_t num_coll; /* 05h read ; number-of-collisions reg */ - uint16_t tx_bytes; /* 05,06h write ; transmit byte-count reg */ - uint8_t fifo; /* 06h read ; FIFO */ - uint16_t remote_dma; /* 08,09h read ; current remote DMA addr */ - uint16_t remote_start; /* 08,09h write ; remote start address reg */ - uint16_t remote_bytes; /* 0a,0bh write ; remote byte-count reg */ - uint8_t tallycnt_0; /* 0dh read ; tally ctr 0 (frame align errs) */ - uint8_t tallycnt_1; /* 0eh read ; tally ctr 1 (CRC errors) */ - uint8_t tallycnt_2; /* 0fh read ; tally ctr 2 (missed pkt errs) */ - - /* Page 1 */ - - /* Command Register 00h (repeated) */ - - uint8_t physaddr[6]; /* 01-06h read/write ; MAC address */ - uint8_t curr_page; /* 07h read/write ; current page register */ - uint8_t mchash[8]; /* 08-0fh read/write ; multicast hash array */ - - /* Page 2 - diagnostic use only */ - - /* Command Register 00h (repeated) */ - - /* Page Start Register 01h read (repeated) - * Page Stop Register 02h read (repeated) - * Current Local DMA Address 01,02h write (repeated) - * Transmit Page start address 04h read (repeated) - * Receive Configuration Register 0ch read (repeated) - * Transmit Configuration Register 0dh read (repeated) - * Data Configuration Register 0eh read (repeated) - * Interrupt Mask Register 0fh read (repeated) - */ - uint8_t rempkt_ptr; /* 03h read/write ; rmt next-pkt ptr */ - uint8_t localpkt_ptr; /* 05h read/write ; lcl next-pkt ptr */ - uint16_t address_cnt; /* 06,07h read/write ; address cter */ - - /* Page 3 - should never be modified. */ - - /* Novell ASIC state */ - uint8_t macaddr[32]; /* ASIC ROM'd MAC address, even bytes */ - uint8_t mem[NE2K_MEMSIZ]; /* on-chip packet memory */ - + dp8390_t dp8390; + uint8_t macaddr[32]; /* ASIC ROM'd MAC address, even bytes */ int board; int is_pci, is_8bit; const char *name; @@ -255,8 +111,6 @@ typedef struct { uint8_t pnp_res_data[256]; bar_t pci_bar[2]; uint8_t pci_regs[PCI_REGSIZE]; - int tx_timer_index; - int tx_timer_active; uint8_t maclocal[6]; /* configured MAC (local) address */ uint8_t eeprom[128]; /* for RTL8029AS */ rom_t bios_rom; @@ -330,30 +184,30 @@ nic_reset(void *priv) if (dev->board >= NE2K_NE2000) { /* Initialize the MAC address area by doubling the physical address */ - dev->macaddr[0] = dev->physaddr[0]; - dev->macaddr[1] = dev->physaddr[0]; - dev->macaddr[2] = dev->physaddr[1]; - dev->macaddr[3] = dev->physaddr[1]; - dev->macaddr[4] = dev->physaddr[2]; - dev->macaddr[5] = dev->physaddr[2]; - dev->macaddr[6] = dev->physaddr[3]; - dev->macaddr[7] = dev->physaddr[3]; - dev->macaddr[8] = dev->physaddr[4]; - dev->macaddr[9] = dev->physaddr[4]; - dev->macaddr[10] = dev->physaddr[5]; - dev->macaddr[11] = dev->physaddr[5]; + dev->macaddr[0] = dev->dp8390.physaddr[0]; + dev->macaddr[1] = dev->dp8390.physaddr[0]; + dev->macaddr[2] = dev->dp8390.physaddr[1]; + dev->macaddr[3] = dev->dp8390.physaddr[1]; + dev->macaddr[4] = dev->dp8390.physaddr[2]; + dev->macaddr[5] = dev->dp8390.physaddr[2]; + dev->macaddr[6] = dev->dp8390.physaddr[3]; + dev->macaddr[7] = dev->dp8390.physaddr[3]; + dev->macaddr[8] = dev->dp8390.physaddr[4]; + dev->macaddr[9] = dev->dp8390.physaddr[4]; + dev->macaddr[10] = dev->dp8390.physaddr[5]; + dev->macaddr[11] = dev->dp8390.physaddr[5]; /* ne2k signature */ for (i=12; i<32; i++) dev->macaddr[i] = 0x57; } else { /* Initialize the MAC address area by doubling the physical address */ - dev->macaddr[0] = dev->physaddr[0]; - dev->macaddr[1] = dev->physaddr[1]; - dev->macaddr[2] = dev->physaddr[2]; - dev->macaddr[3] = dev->physaddr[3]; - dev->macaddr[4] = dev->physaddr[4]; - dev->macaddr[5] = dev->physaddr[5]; + dev->macaddr[0] = dev->dp8390.physaddr[0]; + dev->macaddr[1] = dev->dp8390.physaddr[1]; + dev->macaddr[2] = dev->dp8390.physaddr[2]; + dev->macaddr[3] = dev->dp8390.physaddr[3]; + dev->macaddr[4] = dev->dp8390.physaddr[4]; + dev->macaddr[5] = dev->dp8390.physaddr[5]; /* ne1k signature */ for (i=6; i<16; i++) @@ -361,42 +215,42 @@ nic_reset(void *priv) } /* Zero out registers and memory */ - memset(&dev->CR, 0x00, sizeof(dev->CR) ); - memset(&dev->ISR, 0x00, sizeof(dev->ISR)); - memset(&dev->IMR, 0x00, sizeof(dev->IMR)); - memset(&dev->DCR, 0x00, sizeof(dev->DCR)); - memset(&dev->TCR, 0x00, sizeof(dev->TCR)); - memset(&dev->TSR, 0x00, sizeof(dev->TSR)); - memset(&dev->RSR, 0x00, sizeof(dev->RSR)); - dev->tx_timer_active = 0; - dev->local_dma = 0; - dev->page_start = 0; - dev->page_stop = 0; - dev->bound_ptr = 0; - dev->tx_page_start = 0; - dev->num_coll = 0; - dev->tx_bytes = 0; - dev->fifo = 0; - dev->remote_dma = 0; - dev->remote_start = 0; - dev->remote_bytes = 0; - dev->tallycnt_0 = 0; - dev->tallycnt_1 = 0; - dev->tallycnt_2 = 0; + memset(&dev->dp8390.CR, 0x00, sizeof(dev->dp8390.CR) ); + memset(&dev->dp8390.ISR, 0x00, sizeof(dev->dp8390.ISR)); + memset(&dev->dp8390.IMR, 0x00, sizeof(dev->dp8390.IMR)); + memset(&dev->dp8390.DCR, 0x00, sizeof(dev->dp8390.DCR)); + memset(&dev->dp8390.TCR, 0x00, sizeof(dev->dp8390.TCR)); + memset(&dev->dp8390.TSR, 0x00, sizeof(dev->dp8390.TSR)); + memset(&dev->dp8390.RSR, 0x00, sizeof(dev->dp8390.RSR)); + dev->dp8390.tx_timer_active = 0; + dev->dp8390.local_dma = 0; + dev->dp8390.page_start = 0; + dev->dp8390.page_stop = 0; + dev->dp8390.bound_ptr = 0; + dev->dp8390.tx_page_start = 0; + dev->dp8390.num_coll = 0; + dev->dp8390.tx_bytes = 0; + dev->dp8390.fifo = 0; + dev->dp8390.remote_dma = 0; + dev->dp8390.remote_start = 0; + dev->dp8390.remote_bytes = 0; + dev->dp8390.tallycnt_0 = 0; + dev->dp8390.tallycnt_1 = 0; + dev->dp8390.tallycnt_2 = 0; - dev->curr_page = 0; + dev->dp8390.curr_page = 0; - dev->rempkt_ptr = 0; - dev->localpkt_ptr = 0; - dev->address_cnt = 0; + dev->dp8390.rempkt_ptr = 0; + dev->dp8390.localpkt_ptr = 0; + dev->dp8390.address_cnt = 0; - memset(&dev->mem, 0x00, sizeof(dev->mem)); + memset(&dev->dp8390.mem, 0x00, sizeof(dev->dp8390.mem)); /* Set power-up conditions */ - dev->CR.stop = 1; - dev->CR.rdma_cmd = 4; - dev->ISR.reset = 1; - dev->DCR.longaddr = 1; + dev->dp8390.CR.stop = 1; + dev->dp8390.CR.rdma_cmd = 4; + dev->dp8390.ISR.reset = 1; + dev->dp8390.DCR.longaddr = 1; nic_interrupt(dev, 0); } @@ -407,8 +261,8 @@ nic_soft_reset(void *priv) { nic_t *dev = (nic_t *)priv; - memset(&(dev->ISR), 0x00, sizeof(dev->ISR)); - dev->ISR.reset = 1; + memset(&(dev->dp8390.ISR), 0x00, sizeof(dev->dp8390.ISR)); + dev->dp8390.ISR.reset = 1; } @@ -444,14 +298,14 @@ chipmem_read(nic_t *dev, uint32_t addr, unsigned int len) return(retval); } - if ((addr >= NE2K_MEMSTART) && (addr < NE2K_MEMEND)) { - retval = dev->mem[addr - NE2K_MEMSTART]; + if ((addr >= DP8390_DWORD_MEMSTART) && (addr < DP8390_DWORD_MEMEND)) { + retval = dev->dp8390.mem[addr - DP8390_DWORD_MEMSTART]; if ((len == 2) || (len == 4)) { - retval |= (dev->mem[addr - NE2K_MEMSTART + 1] << 8); + retval |= (dev->dp8390.mem[addr - DP8390_DWORD_MEMSTART + 1] << 8); } if (len == 4) { - retval |= (dev->mem[addr - NE2K_MEMSTART + 2] << 16); - retval |= (dev->mem[addr - NE2K_MEMSTART + 3] << 24); + retval |= (dev->dp8390.mem[addr - DP8390_DWORD_MEMSTART + 2] << 16); + retval |= (dev->dp8390.mem[addr - DP8390_DWORD_MEMSTART + 3] << 24); } return(retval); } @@ -464,10 +318,10 @@ chipmem_read(nic_t *dev, uint32_t addr, unsigned int len) return(retval); } - if ((addr >= NE1K_MEMSTART) && (addr < NE1K_MEMEND)) { - retval = dev->mem[addr - NE1K_MEMSTART]; + if ((addr >= DP8390_WORD_MEMSTART) && (addr < DP8390_WORD_MEMEND)) { + retval = dev->dp8390.mem[addr - DP8390_WORD_MEMSTART]; if (len == 2) { - retval |= (dev->mem[addr - NE1K_MEMSTART + 1] << 8); + retval |= (dev->dp8390.mem[addr - DP8390_WORD_MEMSTART + 1] << 8); } return(retval); } @@ -498,23 +352,23 @@ chipmem_write(nic_t *dev, uint32_t addr, uint32_t val, unsigned len) } if (dev->board >= NE2K_NE2000) { - if ((addr >= NE2K_MEMSTART) && (addr < NE2K_MEMEND)) { - dev->mem[addr-NE2K_MEMSTART] = val & 0xff; + if ((addr >= DP8390_DWORD_MEMSTART) && (addr < DP8390_DWORD_MEMEND)) { + dev->dp8390.mem[addr-DP8390_DWORD_MEMSTART] = val & 0xff; if ((len == 2) || (len == 4)) { - dev->mem[addr-NE2K_MEMSTART+1] = val >> 8; + dev->dp8390.mem[addr-DP8390_DWORD_MEMSTART+1] = val >> 8; } if (len == 4) { - dev->mem[addr-NE2K_MEMSTART+2] = val >> 16; - dev->mem[addr-NE2K_MEMSTART+3] = val >> 24; + dev->dp8390.mem[addr-DP8390_DWORD_MEMSTART+2] = val >> 16; + dev->dp8390.mem[addr-DP8390_DWORD_MEMSTART+3] = val >> 24; } } else { nelog(3, "%s: out-of-bounds chipmem write, %04X\n", dev->name, addr); } } else { - if ((addr >= NE1K_MEMSTART) && (addr < NE1K_MEMEND)) { - dev->mem[addr-NE1K_MEMSTART] = val & 0xff; + if ((addr >= DP8390_WORD_MEMSTART) && (addr < DP8390_WORD_MEMEND)) { + dev->dp8390.mem[addr-DP8390_WORD_MEMSTART] = val & 0xff; if (len == 2) { - dev->mem[addr-NE1K_MEMSTART+1] = val >> 8; + dev->dp8390.mem[addr-DP8390_WORD_MEMSTART+1] = val >> 8; } } else { nelog(3, "%s: out-of-bounds chipmem write, %04X\n", dev->name, addr); @@ -546,43 +400,43 @@ asic_read(nic_t *dev, uint32_t off, unsigned int len) /* A read remote-DMA command must have been issued, and the source-address and length registers must have been initialised. */ - if (len > dev->remote_bytes) { + if (len > dev->dp8390.remote_bytes) { nelog(3, "%s: DMA read underrun iolen=%d remote_bytes=%d\n", - dev->name, len, dev->remote_bytes); + dev->name, len, dev->dp8390.remote_bytes); } nelog(3, "%s: DMA read: addr=%4x remote_bytes=%d\n", - dev->name, dev->remote_dma,dev->remote_bytes); - retval = chipmem_read(dev, dev->remote_dma, len); + dev->name, dev->dp8390.remote_dma,dev->dp8390.remote_bytes); + retval = chipmem_read(dev, dev->dp8390.remote_dma, len); /* The 8390 bumps the address and decreases the byte count by the selected word size after every access, not by the amount of data requested by the host (io_len). */ if (len == 4) { - dev->remote_dma += len; + dev->dp8390.remote_dma += len; } else { - dev->remote_dma += (dev->DCR.wdsize + 1); + dev->dp8390.remote_dma += (dev->dp8390.DCR.wdsize + 1); } - if (dev->remote_dma == dev->page_stop << 8) { - dev->remote_dma = dev->page_start << 8; + if (dev->dp8390.remote_dma == dev->dp8390.page_stop << 8) { + dev->dp8390.remote_dma = dev->dp8390.page_start << 8; } /* keep s.remote_bytes from underflowing */ - if (dev->remote_bytes > dev->DCR.wdsize) { + if (dev->dp8390.remote_bytes > dev->dp8390.DCR.wdsize) { if (len == 4) { - dev->remote_bytes -= len; + dev->dp8390.remote_bytes -= len; } else { - dev->remote_bytes -= (dev->DCR.wdsize + 1); + dev->dp8390.remote_bytes -= (dev->dp8390.DCR.wdsize + 1); } } else { - dev->remote_bytes = 0; + dev->dp8390.remote_bytes = 0; } /* If all bytes have been written, signal remote-DMA complete */ - if (dev->remote_bytes == 0) { - dev->ISR.rdma_done = 1; - if (dev->IMR.rdma_inte) + if (dev->dp8390.remote_bytes == 0) { + dev->dp8390.ISR.rdma_done = 1; + if (dev->dp8390.IMR.rdma_inte) nic_interrupt(dev, 1); } break; @@ -609,35 +463,35 @@ asic_write(nic_t *dev, uint32_t off, uint32_t val, unsigned len) switch(off) { case 0x00: /* Data register - see asic_read for a description */ - if ((len > 1) && (dev->DCR.wdsize == 0)) { + if ((len > 1) && (dev->dp8390.DCR.wdsize == 0)) { nelog(3, "%s: DMA write length %d on byte mode operation\n", dev->name, len); break; } - if (dev->remote_bytes == 0) + if (dev->dp8390.remote_bytes == 0) nelog(3, "%s: DMA write, byte count 0\n", dev->name); - chipmem_write(dev, dev->remote_dma, val, len); + chipmem_write(dev, dev->dp8390.remote_dma, val, len); if (len == 4) - dev->remote_dma += len; + dev->dp8390.remote_dma += len; else - dev->remote_dma += (dev->DCR.wdsize + 1); + dev->dp8390.remote_dma += (dev->dp8390.DCR.wdsize + 1); - if (dev->remote_dma == dev->page_stop << 8) - dev->remote_dma = dev->page_start << 8; + if (dev->dp8390.remote_dma == dev->dp8390.page_stop << 8) + dev->dp8390.remote_dma = dev->dp8390.page_start << 8; if (len == 4) - dev->remote_bytes -= len; + dev->dp8390.remote_bytes -= len; else - dev->remote_bytes -= (dev->DCR.wdsize + 1); + dev->dp8390.remote_bytes -= (dev->dp8390.DCR.wdsize + 1); - if (dev->remote_bytes > NE2K_MEMSIZ) - dev->remote_bytes = 0; + if (dev->dp8390.remote_bytes > DP8390_DWORD_MEMSIZ) + dev->dp8390.remote_bytes = 0; /* If all bytes have been written, signal remote-DMA complete */ - if (dev->remote_bytes == 0) { - dev->ISR.rdma_done = 1; - if (dev->IMR.rdma_inte) + if (dev->dp8390.remote_bytes == 0) { + dev->dp8390.ISR.rdma_done = 1; + if (dev->dp8390.IMR.rdma_inte) nic_interrupt(dev, 1); } break; @@ -669,54 +523,54 @@ page0_read(nic_t *dev, uint32_t off, unsigned int len) switch(off) { case 0x01: /* CLDA0 */ - retval = (dev->local_dma & 0xff); + retval = (dev->dp8390.local_dma & 0xff); break; case 0x02: /* CLDA1 */ - retval = (dev->local_dma >> 8); + retval = (dev->dp8390.local_dma >> 8); break; case 0x03: /* BNRY */ - retval = dev->bound_ptr; + retval = dev->dp8390.bound_ptr; break; case 0x04: /* TSR */ - retval = ((dev->TSR.ow_coll << 7) | - (dev->TSR.cd_hbeat << 6) | - (dev->TSR.fifo_ur << 5) | - (dev->TSR.no_carrier << 4) | - (dev->TSR.aborted << 3) | - (dev->TSR.collided << 2) | - (dev->TSR.tx_ok)); + retval = ((dev->dp8390.TSR.ow_coll << 7) | + (dev->dp8390.TSR.cd_hbeat << 6) | + (dev->dp8390.TSR.fifo_ur << 5) | + (dev->dp8390.TSR.no_carrier << 4) | + (dev->dp8390.TSR.aborted << 3) | + (dev->dp8390.TSR.collided << 2) | + (dev->dp8390.TSR.tx_ok)); break; case 0x05: /* NCR */ - retval = dev->num_coll; + retval = dev->dp8390.num_coll; break; case 0x06: /* FIFO */ /* reading FIFO is only valid in loopback mode */ nelog(3, "%s: reading FIFO not supported yet\n", dev->name); - retval = dev->fifo; + retval = dev->dp8390.fifo; break; case 0x07: /* ISR */ - retval = ((dev->ISR.reset << 7) | - (dev->ISR.rdma_done << 6) | - (dev->ISR.cnt_oflow << 5) | - (dev->ISR.overwrite << 4) | - (dev->ISR.tx_err << 3) | - (dev->ISR.rx_err << 2) | - (dev->ISR.pkt_tx << 1) | - (dev->ISR.pkt_rx)); + retval = ((dev->dp8390.ISR.reset << 7) | + (dev->dp8390.ISR.rdma_done << 6) | + (dev->dp8390.ISR.cnt_oflow << 5) | + (dev->dp8390.ISR.overwrite << 4) | + (dev->dp8390.ISR.tx_err << 3) | + (dev->dp8390.ISR.rx_err << 2) | + (dev->dp8390.ISR.pkt_tx << 1) | + (dev->dp8390.ISR.pkt_rx)); break; case 0x08: /* CRDA0 */ - retval = (dev->remote_dma & 0xff); + retval = (dev->dp8390.remote_dma & 0xff); break; case 0x09: /* CRDA1 */ - retval = (dev->remote_dma >> 8); + retval = (dev->dp8390.remote_dma >> 8); break; case 0x0a: /* reserved / RTL8029ID0 */ @@ -742,26 +596,26 @@ page0_read(nic_t *dev, uint32_t off, unsigned int len) break; case 0x0c: /* RSR */ - retval = ((dev->RSR.deferred << 7) | - (dev->RSR.rx_disabled << 6) | - (dev->RSR.rx_mbit << 5) | - (dev->RSR.rx_missed << 4) | - (dev->RSR.fifo_or << 3) | - (dev->RSR.bad_falign << 2) | - (dev->RSR.bad_crc << 1) | - (dev->RSR.rx_ok)); + retval = ((dev->dp8390.RSR.deferred << 7) | + (dev->dp8390.RSR.rx_disabled << 6) | + (dev->dp8390.RSR.rx_mbit << 5) | + (dev->dp8390.RSR.rx_missed << 4) | + (dev->dp8390.RSR.fifo_or << 3) | + (dev->dp8390.RSR.bad_falign << 2) | + (dev->dp8390.RSR.bad_crc << 1) | + (dev->dp8390.RSR.rx_ok)); break; case 0x0d: /* CNTR0 */ - retval = dev->tallycnt_0; + retval = dev->dp8390.tallycnt_0; break; case 0x0e: /* CNTR1 */ - retval = dev->tallycnt_1; + retval = dev->dp8390.tallycnt_1; break; case 0x0f: /* CNTR2 */ - retval = dev->tallycnt_2; + retval = dev->dp8390.tallycnt_2; break; default: @@ -797,85 +651,85 @@ page0_write(nic_t *dev, uint32_t off, uint32_t val, unsigned len) switch(off) { case 0x01: /* PSTART */ - dev->page_start = val; + dev->dp8390.page_start = val; break; case 0x02: /* PSTOP */ - dev->page_stop = val; + dev->dp8390.page_stop = val; break; case 0x03: /* BNRY */ - dev->bound_ptr = val; + dev->dp8390.bound_ptr = val; break; case 0x04: /* TPSR */ - dev->tx_page_start = val; + dev->dp8390.tx_page_start = val; break; case 0x05: /* TBCR0 */ /* Clear out low byte and re-insert */ - dev->tx_bytes &= 0xff00; - dev->tx_bytes |= (val & 0xff); + dev->dp8390.tx_bytes &= 0xff00; + dev->dp8390.tx_bytes |= (val & 0xff); break; case 0x06: /* TBCR1 */ /* Clear out high byte and re-insert */ - dev->tx_bytes &= 0x00ff; - dev->tx_bytes |= ((val & 0xff) << 8); + dev->dp8390.tx_bytes &= 0x00ff; + dev->dp8390.tx_bytes |= ((val & 0xff) << 8); break; case 0x07: /* ISR */ val &= 0x7f; /* clear RST bit - status-only bit */ /* All other values are cleared iff the ISR bit is 1 */ - dev->ISR.pkt_rx &= !((int)((val & 0x01) == 0x01)); - dev->ISR.pkt_tx &= !((int)((val & 0x02) == 0x02)); - dev->ISR.rx_err &= !((int)((val & 0x04) == 0x04)); - dev->ISR.tx_err &= !((int)((val & 0x08) == 0x08)); - dev->ISR.overwrite &= !((int)((val & 0x10) == 0x10)); - dev->ISR.cnt_oflow &= !((int)((val & 0x20) == 0x20)); - dev->ISR.rdma_done &= !((int)((val & 0x40) == 0x40)); - val = ((dev->ISR.rdma_done << 6) | - (dev->ISR.cnt_oflow << 5) | - (dev->ISR.overwrite << 4) | - (dev->ISR.tx_err << 3) | - (dev->ISR.rx_err << 2) | - (dev->ISR.pkt_tx << 1) | - (dev->ISR.pkt_rx)); - val &= ((dev->IMR.rdma_inte << 6) | - (dev->IMR.cofl_inte << 5) | - (dev->IMR.overw_inte << 4) | - (dev->IMR.txerr_inte << 3) | - (dev->IMR.rxerr_inte << 2) | - (dev->IMR.tx_inte << 1) | - (dev->IMR.rx_inte)); + dev->dp8390.ISR.pkt_rx &= !((int)((val & 0x01) == 0x01)); + dev->dp8390.ISR.pkt_tx &= !((int)((val & 0x02) == 0x02)); + dev->dp8390.ISR.rx_err &= !((int)((val & 0x04) == 0x04)); + dev->dp8390.ISR.tx_err &= !((int)((val & 0x08) == 0x08)); + dev->dp8390.ISR.overwrite &= !((int)((val & 0x10) == 0x10)); + dev->dp8390.ISR.cnt_oflow &= !((int)((val & 0x20) == 0x20)); + dev->dp8390.ISR.rdma_done &= !((int)((val & 0x40) == 0x40)); + val = ((dev->dp8390.ISR.rdma_done << 6) | + (dev->dp8390.ISR.cnt_oflow << 5) | + (dev->dp8390.ISR.overwrite << 4) | + (dev->dp8390.ISR.tx_err << 3) | + (dev->dp8390.ISR.rx_err << 2) | + (dev->dp8390.ISR.pkt_tx << 1) | + (dev->dp8390.ISR.pkt_rx)); + val &= ((dev->dp8390.IMR.rdma_inte << 6) | + (dev->dp8390.IMR.cofl_inte << 5) | + (dev->dp8390.IMR.overw_inte << 4) | + (dev->dp8390.IMR.txerr_inte << 3) | + (dev->dp8390.IMR.rxerr_inte << 2) | + (dev->dp8390.IMR.tx_inte << 1) | + (dev->dp8390.IMR.rx_inte)); if (val == 0x00) nic_interrupt(dev, 0); break; case 0x08: /* RSAR0 */ /* Clear out low byte and re-insert */ - dev->remote_start &= 0xff00; - dev->remote_start |= (val & 0xff); - dev->remote_dma = dev->remote_start; + dev->dp8390.remote_start &= 0xff00; + dev->dp8390.remote_start |= (val & 0xff); + dev->dp8390.remote_dma = dev->dp8390.remote_start; break; case 0x09: /* RSAR1 */ /* Clear out high byte and re-insert */ - dev->remote_start &= 0x00ff; - dev->remote_start |= ((val & 0xff) << 8); - dev->remote_dma = dev->remote_start; + dev->dp8390.remote_start &= 0x00ff; + dev->dp8390.remote_start |= ((val & 0xff) << 8); + dev->dp8390.remote_dma = dev->dp8390.remote_start; break; case 0x0a: /* RBCR0 */ /* Clear out low byte and re-insert */ - dev->remote_bytes &= 0xff00; - dev->remote_bytes |= (val & 0xff); + dev->dp8390.remote_bytes &= 0xff00; + dev->dp8390.remote_bytes |= (val & 0xff); break; case 0x0b: /* RBCR1 */ /* Clear out high byte and re-insert */ - dev->remote_bytes &= 0x00ff; - dev->remote_bytes |= ((val & 0xff) << 8); + dev->dp8390.remote_bytes &= 0x00ff; + dev->dp8390.remote_bytes |= ((val & 0xff) << 8); break; case 0x0c: /* RCR */ @@ -886,12 +740,12 @@ page0_write(nic_t *dev, uint32_t off, uint32_t val, unsigned len) } /* Set all other bit-fields */ - dev->RCR.errors_ok = ((val & 0x01) == 0x01); - dev->RCR.runts_ok = ((val & 0x02) == 0x02); - dev->RCR.broadcast = ((val & 0x04) == 0x04); - dev->RCR.multicast = ((val & 0x08) == 0x08); - dev->RCR.promisc = ((val & 0x10) == 0x10); - dev->RCR.monitor = ((val & 0x20) == 0x20); + dev->dp8390.RCR.errors_ok = ((val & 0x01) == 0x01); + dev->dp8390.RCR.runts_ok = ((val & 0x02) == 0x02); + dev->dp8390.RCR.broadcast = ((val & 0x04) == 0x04); + dev->dp8390.RCR.multicast = ((val & 0x08) == 0x08); + dev->dp8390.RCR.promisc = ((val & 0x10) == 0x10); + dev->dp8390.RCR.monitor = ((val & 0x20) == 0x20); /* Monitor bit is a little suspicious... */ if (val & 0x20) nelog(3, "%s: RCR write, monitor bit set!\n", @@ -905,11 +759,11 @@ page0_write(nic_t *dev, uint32_t off, uint32_t val, unsigned len) /* Test loop mode (not supported) */ if (val & 0x06) { - dev->TCR.loop_cntl = (val & 0x6) >> 1; + dev->dp8390.TCR.loop_cntl = (val & 0x6) >> 1; nelog(3, "%s: TCR write, loop mode %d not supported\n", - dev->name, dev->TCR.loop_cntl); + dev->name, dev->dp8390.TCR.loop_cntl); } else { - dev->TCR.loop_cntl = 0; + dev->dp8390.TCR.loop_cntl = 0; } /* Inhibit-CRC not supported. */ @@ -922,7 +776,7 @@ page0_write(nic_t *dev, uint32_t off, uint32_t val, unsigned len) dev->name); /* Allow collision-offset to be set, although not used */ - dev->TCR.coll_prio = ((val & 0x08) == 0x08); + dev->dp8390.TCR.coll_prio = ((val & 0x08) == 0x08); break; case 0x0e: /* DCR */ @@ -939,12 +793,12 @@ page0_write(nic_t *dev, uint32_t off, uint32_t val, unsigned len) nelog(3, "%s: DCR write - AR set ???\n", dev->name); /* Set other values. */ - dev->DCR.wdsize = ((val & 0x01) == 0x01); - dev->DCR.endian = ((val & 0x02) == 0x02); - dev->DCR.longaddr = ((val & 0x04) == 0x04); /* illegal ? */ - dev->DCR.loop = ((val & 0x08) == 0x08); - dev->DCR.auto_rx = ((val & 0x10) == 0x10); /* also illegal ? */ - dev->DCR.fifo_size = (val & 0x50) >> 5; + dev->dp8390.DCR.wdsize = ((val & 0x01) == 0x01); + dev->dp8390.DCR.endian = ((val & 0x02) == 0x02); + dev->dp8390.DCR.longaddr = ((val & 0x04) == 0x04); /* illegal ? */ + dev->dp8390.DCR.loop = ((val & 0x08) == 0x08); + dev->dp8390.DCR.auto_rx = ((val & 0x10) == 0x10); /* also illegal ? */ + dev->dp8390.DCR.fifo_size = (val & 0x50) >> 5; break; case 0x0f: /* IMR */ @@ -953,20 +807,20 @@ page0_write(nic_t *dev, uint32_t off, uint32_t val, unsigned len) nelog(3, "%s: IMR write, reserved bit set\n",dev->name); /* Set other values */ - dev->IMR.rx_inte = ((val & 0x01) == 0x01); - dev->IMR.tx_inte = ((val & 0x02) == 0x02); - dev->IMR.rxerr_inte = ((val & 0x04) == 0x04); - dev->IMR.txerr_inte = ((val & 0x08) == 0x08); - dev->IMR.overw_inte = ((val & 0x10) == 0x10); - dev->IMR.cofl_inte = ((val & 0x20) == 0x20); - dev->IMR.rdma_inte = ((val & 0x40) == 0x40); - val2 = ((dev->ISR.rdma_done << 6) | - (dev->ISR.cnt_oflow << 5) | - (dev->ISR.overwrite << 4) | - (dev->ISR.tx_err << 3) | - (dev->ISR.rx_err << 2) | - (dev->ISR.pkt_tx << 1) | - (dev->ISR.pkt_rx)); + dev->dp8390.IMR.rx_inte = ((val & 0x01) == 0x01); + dev->dp8390.IMR.tx_inte = ((val & 0x02) == 0x02); + dev->dp8390.IMR.rxerr_inte = ((val & 0x04) == 0x04); + dev->dp8390.IMR.txerr_inte = ((val & 0x08) == 0x08); + dev->dp8390.IMR.overw_inte = ((val & 0x10) == 0x10); + dev->dp8390.IMR.cofl_inte = ((val & 0x20) == 0x20); + dev->dp8390.IMR.rdma_inte = ((val & 0x40) == 0x40); + val2 = ((dev->dp8390.ISR.rdma_done << 6) | + (dev->dp8390.ISR.cnt_oflow << 5) | + (dev->dp8390.ISR.overwrite << 4) | + (dev->dp8390.ISR.tx_err << 3) | + (dev->dp8390.ISR.rx_err << 2) | + (dev->dp8390.ISR.pkt_tx << 1) | + (dev->dp8390.ISR.pkt_rx)); if (((val & val2) & 0x7f) == 0) nic_interrupt(dev, 0); else @@ -995,12 +849,12 @@ page1_read(nic_t *dev, uint32_t off, unsigned int len) case 0x04: case 0x05: case 0x06: - return(dev->physaddr[off - 1]); + return(dev->dp8390.physaddr[off - 1]); case 0x07: /* CURR */ nelog(3, "%s: returning current page: 0x%02x\n", - dev->name, (dev->curr_page)); - return(dev->curr_page); + dev->name, (dev->dp8390.curr_page)); + return(dev->dp8390.curr_page); case 0x08: /* MAR0-7 */ case 0x09: @@ -1010,7 +864,7 @@ page1_read(nic_t *dev, uint32_t off, unsigned int len) case 0x0d: case 0x0e: case 0x0f: - return(dev->mchash[off - 8]); + return(dev->dp8390.mchash[off - 8]); default: nelog(3, "%s: Page1 read register 0x%02x out of range\n", @@ -1033,17 +887,17 @@ page1_write(nic_t *dev, uint32_t off, uint32_t val, unsigned len) case 0x04: case 0x05: case 0x06: - dev->physaddr[off - 1] = val; + dev->dp8390.physaddr[off - 1] = val; if (off == 6) nelog(3, "%s: physical address set to %02x:%02x:%02x:%02x:%02x:%02x\n", dev->name, - dev->physaddr[0], dev->physaddr[1], - dev->physaddr[2], dev->physaddr[3], - dev->physaddr[4], dev->physaddr[5]); + dev->dp8390.physaddr[0], dev->dp8390.physaddr[1], + dev->dp8390.physaddr[2], dev->dp8390.physaddr[3], + dev->dp8390.physaddr[4], dev->dp8390.physaddr[5]); break; case 0x07: /* CURR */ - dev->curr_page = val; + dev->dp8390.curr_page = val; break; case 0x08: /* MAR0-7 */ @@ -1054,7 +908,7 @@ page1_write(nic_t *dev, uint32_t off, uint32_t val, unsigned len) case 0x0d: case 0x0e: case 0x0f: - dev->mchash[off - 8] = val; + dev->dp8390.mchash[off - 8] = val; break; default: @@ -1074,25 +928,25 @@ page2_read(nic_t *dev, uint32_t off, unsigned int len) switch(off) { case 0x01: /* PSTART */ - return(dev->page_start); + return(dev->dp8390.page_start); case 0x02: /* PSTOP */ - return(dev->page_stop); + return(dev->dp8390.page_stop); case 0x03: /* Remote Next-packet pointer */ - return(dev->rempkt_ptr); + return(dev->dp8390.rempkt_ptr); case 0x04: /* TPSR */ - return(dev->tx_page_start); + return(dev->dp8390.tx_page_start); case 0x05: /* Local Next-packet pointer */ - return(dev->localpkt_ptr); + return(dev->dp8390.localpkt_ptr); case 0x06: /* Address counter (upper) */ - return(dev->address_cnt >> 8); + return(dev->dp8390.address_cnt >> 8); case 0x07: /* Address counter (lower) */ - return(dev->address_cnt & 0xff); + return(dev->dp8390.address_cnt & 0xff); case 0x08: /* Reserved */ case 0x09: @@ -1103,35 +957,35 @@ page2_read(nic_t *dev, uint32_t off, unsigned int len) return(0xff); case 0x0c: /* RCR */ - return ((dev->RCR.monitor << 5) | - (dev->RCR.promisc << 4) | - (dev->RCR.multicast << 3) | - (dev->RCR.broadcast << 2) | - (dev->RCR.runts_ok << 1) | - (dev->RCR.errors_ok)); + return ((dev->dp8390.RCR.monitor << 5) | + (dev->dp8390.RCR.promisc << 4) | + (dev->dp8390.RCR.multicast << 3) | + (dev->dp8390.RCR.broadcast << 2) | + (dev->dp8390.RCR.runts_ok << 1) | + (dev->dp8390.RCR.errors_ok)); case 0x0d: /* TCR */ - return ((dev->TCR.coll_prio << 4) | - (dev->TCR.ext_stoptx << 3) | - ((dev->TCR.loop_cntl & 0x3) << 1) | - (dev->TCR.crc_disable)); + return ((dev->dp8390.TCR.coll_prio << 4) | + (dev->dp8390.TCR.ext_stoptx << 3) | + ((dev->dp8390.TCR.loop_cntl & 0x3) << 1) | + (dev->dp8390.TCR.crc_disable)); case 0x0e: /* DCR */ - return (((dev->DCR.fifo_size & 0x3) << 5) | - (dev->DCR.auto_rx << 4) | - (dev->DCR.loop << 3) | - (dev->DCR.longaddr << 2) | - (dev->DCR.endian << 1) | - (dev->DCR.wdsize)); + return (((dev->dp8390.DCR.fifo_size & 0x3) << 5) | + (dev->dp8390.DCR.auto_rx << 4) | + (dev->dp8390.DCR.loop << 3) | + (dev->dp8390.DCR.longaddr << 2) | + (dev->dp8390.DCR.endian << 1) | + (dev->dp8390.DCR.wdsize)); case 0x0f: /* IMR */ - return ((dev->IMR.rdma_inte << 6) | - (dev->IMR.cofl_inte << 5) | - (dev->IMR.overw_inte << 4) | - (dev->IMR.txerr_inte << 3) | - (dev->IMR.rxerr_inte << 2) | - (dev->IMR.tx_inte << 1) | - (dev->IMR.rx_inte)); + return ((dev->dp8390.IMR.rdma_inte << 6) | + (dev->dp8390.IMR.cofl_inte << 5) | + (dev->dp8390.IMR.overw_inte << 4) | + (dev->dp8390.IMR.txerr_inte << 3) | + (dev->dp8390.IMR.rxerr_inte << 2) | + (dev->dp8390.IMR.tx_inte << 1) | + (dev->dp8390.IMR.rx_inte)); default: nelog(3, "%s: Page2 register 0x%02x out of range\n", @@ -1154,18 +1008,18 @@ page2_write(nic_t *dev, uint32_t off, uint32_t val, unsigned len) switch(off) { case 0x01: /* CLDA0 */ /* Clear out low byte and re-insert */ - dev->local_dma &= 0xff00; - dev->local_dma |= (val & 0xff); + dev->dp8390.local_dma &= 0xff00; + dev->dp8390.local_dma |= (val & 0xff); break; case 0x02: /* CLDA1 */ /* Clear out high byte and re-insert */ - dev->local_dma &= 0x00ff; - dev->local_dma |= ((val & 0xff) << 8); + dev->dp8390.local_dma &= 0x00ff; + dev->dp8390.local_dma |= ((val & 0xff) << 8); break; case 0x03: /* Remote Next-pkt pointer */ - dev->rempkt_ptr = val; + dev->dp8390.rempkt_ptr = val; break; case 0x04: @@ -1173,19 +1027,19 @@ page2_write(nic_t *dev, uint32_t off, uint32_t val, unsigned len) break; case 0x05: /* Local Next-packet pointer */ - dev->localpkt_ptr = val; + dev->dp8390.localpkt_ptr = val; break; case 0x06: /* Address counter (upper) */ /* Clear out high byte and re-insert */ - dev->address_cnt &= 0x00ff; - dev->address_cnt |= ((val & 0xff) << 8); + dev->dp8390.address_cnt &= 0x00ff; + dev->dp8390.address_cnt |= ((val & 0xff) << 8); break; case 0x07: /* Address counter (lower) */ /* Clear out low byte and re-insert */ - dev->address_cnt &= 0xff00; - dev->address_cnt |= (val & 0xff); + dev->dp8390.address_cnt &= 0xff00; + dev->dp8390.address_cnt |= (val & 0xff); break; case 0x08: @@ -1282,11 +1136,11 @@ read_cr(nic_t *dev) { uint32_t retval; - retval = (((dev->CR.pgsel & 0x03) << 6) | - ((dev->CR.rdma_cmd & 0x07) << 3) | - (dev->CR.tx_packet << 2) | - (dev->CR.start << 1) | - (dev->CR.stop)); + retval = (((dev->dp8390.CR.pgsel & 0x03) << 6) | + ((dev->dp8390.CR.rdma_cmd & 0x07) << 3) | + (dev->dp8390.CR.tx_packet << 2) | + (dev->dp8390.CR.start << 1) | + (dev->dp8390.CR.stop)); nelog(3, "%s: read CR returns 0x%02x\n", dev->name, retval); return(retval); @@ -1306,70 +1160,70 @@ write_cr(nic_t *dev, uint32_t val) /* Check for s/w reset */ if (val & 0x01) { - dev->ISR.reset = 1; - dev->CR.stop = 1; + dev->dp8390.ISR.reset = 1; + dev->dp8390.CR.stop = 1; } else { - dev->CR.stop = 0; + dev->dp8390.CR.stop = 0; } - dev->CR.rdma_cmd = (val & 0x38) >> 3; + dev->dp8390.CR.rdma_cmd = (val & 0x38) >> 3; /* If start command issued, the RST bit in the ISR */ /* must be cleared */ - if ((val & 0x02) && !dev->CR.start) - dev->ISR.reset = 0; + if ((val & 0x02) && !dev->dp8390.CR.start) + dev->dp8390.ISR.reset = 0; - dev->CR.start = ((val & 0x02) == 0x02); - dev->CR.pgsel = (val & 0xc0) >> 6; + dev->dp8390.CR.start = ((val & 0x02) == 0x02); + dev->dp8390.CR.pgsel = (val & 0xc0) >> 6; /* Check for send-packet command */ - if (dev->CR.rdma_cmd == 3) { + if (dev->dp8390.CR.rdma_cmd == 3) { /* Set up DMA read from receive ring */ - dev->remote_start = dev->remote_dma = dev->bound_ptr * 256; - dev->remote_bytes = (uint16_t) chipmem_read(dev, dev->bound_ptr * 256 + 2, 2); + dev->dp8390.remote_start = dev->dp8390.remote_dma = dev->dp8390.bound_ptr * 256; + dev->dp8390.remote_bytes = (uint16_t) chipmem_read(dev, dev->dp8390.bound_ptr * 256 + 2, 2); nelog(3, "%s: sending buffer #x%x length %d\n", - dev->name, dev->remote_start, dev->remote_bytes); + dev->name, dev->dp8390.remote_start, dev->dp8390.remote_bytes); } /* Check for start-tx */ - if ((val & 0x04) && dev->TCR.loop_cntl) { - if (dev->TCR.loop_cntl != 1) { + if ((val & 0x04) && dev->dp8390.TCR.loop_cntl) { + if (dev->dp8390.TCR.loop_cntl != 1) { nelog(3, "%s: loop mode %d not supported\n", - dev->name, dev->TCR.loop_cntl); + dev->name, dev->dp8390.TCR.loop_cntl); } else { if (dev->board >= NE2K_NE2000) { nic_rx(dev, - &dev->mem[dev->tx_page_start*256 - NE2K_MEMSTART], - dev->tx_bytes); + &dev->dp8390.mem[dev->dp8390.tx_page_start*256 - DP8390_DWORD_MEMSTART], + dev->dp8390.tx_bytes); } else { nic_rx(dev, - &dev->mem[dev->tx_page_start*256 - NE1K_MEMSTART], - dev->tx_bytes); + &dev->dp8390.mem[dev->dp8390.tx_page_start*256 - DP8390_WORD_MEMSTART], + dev->dp8390.tx_bytes); } } } else if (val & 0x04) { - if (dev->CR.stop || (!dev->CR.start && (dev->board < NE2K_RTL8019AS))) { - if (dev->tx_bytes == 0) /* njh@bandsman.co.uk */ { + if (dev->dp8390.CR.stop || (!dev->dp8390.CR.start && (dev->board < NE2K_RTL8019AS))) { + if (dev->dp8390.tx_bytes == 0) /* njh@bandsman.co.uk */ { return; /* Solaris9 probe */ } nelog(3, "%s: CR write - tx start, dev in reset\n", dev->name); } - if (dev->tx_bytes == 0) + if (dev->dp8390.tx_bytes == 0) nelog(3, "%s: CR write - tx start, tx bytes == 0\n", dev->name); /* Send the packet to the system driver */ - dev->CR.tx_packet = 1; + dev->dp8390.CR.tx_packet = 1; if (dev->board >= NE2K_NE2000) { - network_tx(&dev->mem[dev->tx_page_start*256 - NE2K_MEMSTART], - dev->tx_bytes); + network_tx(&dev->dp8390.mem[dev->dp8390.tx_page_start*256 - DP8390_DWORD_MEMSTART], + dev->dp8390.tx_bytes); } else { - network_tx(&dev->mem[dev->tx_page_start*256 - NE1K_MEMSTART], - dev->tx_bytes); + network_tx(&dev->dp8390.mem[dev->dp8390.tx_page_start*256 - DP8390_WORD_MEMSTART], + dev->dp8390.tx_bytes); } /* some more debug */ - if (dev->tx_timer_active) + if (dev->dp8390.tx_timer_active) nelog(3, "%s: CR write, tx timer still active\n", dev->name); nic_tx(dev, val); @@ -1378,9 +1232,9 @@ write_cr(nic_t *dev, uint32_t val) /* Linux probes for an interrupt by setting up a remote-DMA read * of 0 bytes with remote-DMA completion interrupts enabled. * Detect this here */ - if (dev->CR.rdma_cmd == 0x01 && dev->CR.start && dev->remote_bytes == 0) { - dev->ISR.rdma_done = 1; - if (dev->IMR.rdma_inte) { + if (dev->dp8390.CR.rdma_cmd == 0x01 && dev->dp8390.CR.start && dev->dp8390.remote_bytes == 0) { + dev->dp8390.ISR.rdma_done = 1; + if (dev->dp8390.IMR.rdma_inte) { nic_interrupt(dev, 1); if (! dev->is_pci) nic_interrupt(dev, 0); @@ -1401,7 +1255,7 @@ nic_read(nic_t *dev, uint32_t addr, unsigned len) retval = asic_read(dev, off - 0x10, len); } else if (off == 0x00) { retval = read_cr(dev); - } else switch(dev->CR.pgsel) { + } else switch(dev->dp8390.CR.pgsel) { case 0x00: retval = page0_read(dev, off, len); break; @@ -1420,7 +1274,7 @@ nic_read(nic_t *dev, uint32_t addr, unsigned len) default: nelog(3, "%s: unknown value of pgsel in read - %d\n", - dev->name, dev->CR.pgsel); + dev->name, dev->dp8390.CR.pgsel); break; } @@ -1440,7 +1294,7 @@ nic_readw(uint16_t addr, void *priv) { nic_t *dev = (nic_t *)priv; - if (dev->DCR.wdsize & 1) + if (dev->dp8390.DCR.wdsize & 1) return(nic_read(dev, addr, 2)); else return(nic_read(dev, addr, 1)); @@ -1469,7 +1323,7 @@ nic_write(nic_t *dev, uint32_t addr, uint32_t val, unsigned len) asic_write(dev, off - 0x10, val, len); } else if (off == 0x00) { write_cr(dev, val); - } else switch(dev->CR.pgsel) { + } else switch(dev->dp8390.CR.pgsel) { case 0x00: page0_write(dev, off, val, len); break; @@ -1488,7 +1342,7 @@ nic_write(nic_t *dev, uint32_t addr, uint32_t val, unsigned len) default: nelog(3, "%s: unknown value of pgsel in write - %d\n", - dev->name, dev->CR.pgsel); + dev->name, dev->dp8390.CR.pgsel); break; } } @@ -1506,7 +1360,7 @@ nic_writew(uint16_t addr, uint16_t val, void *priv) { nic_t *dev = (nic_t *)priv; - if (dev->DCR.wdsize & 1) + if (dev->dp8390.DCR.wdsize & 1) nic_write(dev, addr, val, 2); else nic_write(dev, addr, val, 1); @@ -2134,45 +1988,17 @@ nic_pci_write(int func, int addr, uint8_t val, void *priv) } -/* - * Return the 6-bit index into the multicast - * table. Stolen unashamedly from FreeBSD's if_ed.c - */ -static int -mcast_index(const void *dst) -{ -#define POLYNOMIAL 0x04c11db6 - uint32_t crc = 0xffffffffL; - int carry, i, j; - uint8_t b; - uint8_t *ep = (uint8_t *)dst; - - for (i=6; --i>=0;) { - b = *ep++; - for (j = 8; --j >= 0;) { - carry = ((crc & 0x80000000L) ? 1 : 0) ^ (b & 0x01); - crc <<= 1; - b >>= 1; - if (carry) - crc = ((crc ^ POLYNOMIAL) | carry); - } - } - return(crc >> 26); -#undef POLYNOMIAL -} - - static void nic_tx(nic_t *dev, uint32_t val) { - dev->CR.tx_packet = 0; - dev->TSR.tx_ok = 1; - dev->ISR.pkt_tx = 1; + dev->dp8390.CR.tx_packet = 0; + dev->dp8390.TSR.tx_ok = 1; + dev->dp8390.ISR.pkt_tx = 1; /* Generate an interrupt if not masked */ - if (dev->IMR.tx_inte) + if (dev->dp8390.IMR.tx_inte) nic_interrupt(dev, 1); - dev->tx_timer_active = 0; + dev->dp8390.tx_timer_active = 0; } @@ -2199,18 +2025,18 @@ nic_rx(void *priv, uint8_t *buf, int io_len) if (io_len != 60) nelog(2, "%s: rx_frame with length %d\n", dev->name, io_len); - if ((dev->CR.stop != 0) || (dev->page_start == 0)) return; + if ((dev->dp8390.CR.stop != 0) || (dev->dp8390.page_start == 0)) return; /* * Add the pkt header + CRC to the length, and work * out how many 256-byte pages the frame would occupy. */ pages = (io_len + sizeof(pkthdr) + sizeof(uint32_t) + 255)/256; - if (dev->curr_page < dev->bound_ptr) { - avail = dev->bound_ptr - dev->curr_page; + if (dev->dp8390.curr_page < dev->dp8390.bound_ptr) { + avail = dev->dp8390.bound_ptr - dev->dp8390.curr_page; } else { - avail = (dev->page_stop - dev->page_start) - - (dev->curr_page - dev->bound_ptr); + avail = (dev->dp8390.page_stop - dev->dp8390.page_start) - + (dev->dp8390.curr_page - dev->dp8390.bound_ptr); } /* @@ -2230,7 +2056,7 @@ nic_rx(void *priv, uint8_t *buf, int io_len) return; } - if ((io_len < 40/*60*/) && !dev->RCR.runts_ok) { + if ((io_len < 40/*60*/) && !dev->dp8390.RCR.runts_ok) { nelog(1, "%s: rejected small packet, length %d\n", dev->name, io_len); //FIXME: move to upper layer @@ -2249,11 +2075,11 @@ nic_rx(void *priv, uint8_t *buf, int io_len) io_len); /* Do address filtering if not in promiscuous mode. */ - if (! dev->RCR.promisc) { + if (! dev->dp8390.RCR.promisc) { /* If this is a broadcast frame.. */ if (! memcmp(buf, bcast_addr, 6)) { /* Broadcast not enabled, we're done. */ - if (! dev->RCR.broadcast) { + if (! dev->dp8390.RCR.broadcast) { nelog(2, "%s: RX BC disabled\n", dev->name); //FIXME: move to upper layer @@ -2265,7 +2091,7 @@ nic_rx(void *priv, uint8_t *buf, int io_len) /* If this is a multicast frame.. */ else if (buf[0] & 0x01) { /* Multicast not enabled, we're done. */ - if (! dev->RCR.multicast) { + if (! dev->dp8390.RCR.multicast) { #if 1 nelog(2, "%s: RX MC disabled\n", dev->name); #endif @@ -2277,7 +2103,7 @@ nic_rx(void *priv, uint8_t *buf, int io_len) /* Are we listening to this multicast address? */ idx = mcast_index(buf); - if (! (dev->mchash[idx>>3] & (1<<(idx&0x7)))) { + if (! (dev->dp8390.mchash[idx>>3] & (1<<(idx&0x7)))) { nelog(2, "%s: RX MC not listed\n", dev->name); //FIXME: move to upper layer @@ -2287,14 +2113,14 @@ nic_rx(void *priv, uint8_t *buf, int io_len) } /* Unicast, must be for us.. */ - else if (memcmp(buf, dev->physaddr, 6)) return; + else if (memcmp(buf, dev->dp8390.physaddr, 6)) return; } else { nelog(2, "%s: RX promiscuous receive\n", dev->name); } - nextpage = dev->curr_page + pages; - if (nextpage >= dev->page_stop) - nextpage -= (dev->page_stop - dev->page_start); + nextpage = dev->dp8390.curr_page + pages; + if (nextpage >= dev->dp8390.page_stop) + nextpage -= (dev->dp8390.page_stop - dev->dp8390.page_start); /* Set up packet header. */ pkthdr[0] = 0x01; /* RXOK - packet is OK */ @@ -2308,29 +2134,29 @@ nic_rx(void *priv, uint8_t *buf, int io_len) /* Copy into buffer, update curpage, and signal interrupt if config'd */ if (dev->board >= NE2K_NE2000) - startptr = &dev->mem[(dev->curr_page * 256) - NE2K_MEMSTART]; + startptr = &dev->dp8390.mem[(dev->dp8390.curr_page * 256) - DP8390_DWORD_MEMSTART]; else - startptr = &dev->mem[(dev->curr_page * 256) - NE1K_MEMSTART]; + startptr = &dev->dp8390.mem[(dev->dp8390.curr_page * 256) - DP8390_WORD_MEMSTART]; memcpy(startptr, pkthdr, sizeof(pkthdr)); - if ((nextpage > dev->curr_page) || - ((dev->curr_page + pages) == dev->page_stop)) { + if ((nextpage > dev->dp8390.curr_page) || + ((dev->dp8390.curr_page + pages) == dev->dp8390.page_stop)) { memcpy(startptr+sizeof(pkthdr), buf, io_len); } else { - endbytes = (dev->page_stop - dev->curr_page) * 256; + endbytes = (dev->dp8390.page_stop - dev->dp8390.curr_page) * 256; memcpy(startptr+sizeof(pkthdr), buf, endbytes-sizeof(pkthdr)); if (dev->board >= NE2K_NE2000) - startptr = &dev->mem[(dev->page_start * 256) - NE2K_MEMSTART]; + startptr = &dev->dp8390.mem[(dev->dp8390.page_start * 256) - DP8390_DWORD_MEMSTART]; else - startptr = &dev->mem[(dev->page_start * 256) - NE1K_MEMSTART]; + startptr = &dev->dp8390.mem[(dev->dp8390.page_start * 256) - DP8390_WORD_MEMSTART]; memcpy(startptr, buf+endbytes-sizeof(pkthdr), io_len-endbytes+8); } - dev->curr_page = nextpage; + dev->dp8390.curr_page = nextpage; - dev->RSR.rx_ok = 1; - dev->RSR.rx_mbit = (buf[0] & 0x01) ? 1 : 0; - dev->ISR.pkt_rx = 1; + dev->dp8390.RSR.rx_ok = 1; + dev->dp8390.RSR.rx_mbit = (buf[0] & 0x01) ? 1 : 0; + dev->dp8390.ISR.pkt_rx = 1; - if (dev->IMR.rx_inte) + if (dev->dp8390.IMR.rx_inte) nic_interrupt(dev, 1); //FIXME: move to upper layer @@ -2472,12 +2298,12 @@ nic_init(const device_t *info) dev->maclocal[4] = (mac>>8) & 0xff; dev->maclocal[5] = (mac & 0xff); } - memcpy(dev->physaddr, dev->maclocal, sizeof(dev->maclocal)); + memcpy(dev->dp8390.physaddr, dev->maclocal, sizeof(dev->maclocal)); nelog(0, "%s: I/O=%04x, IRQ=%d, MAC=%02x:%02x:%02x:%02x:%02x:%02x\n", dev->name, dev->base_address, dev->base_irq, - dev->physaddr[0], dev->physaddr[1], dev->physaddr[2], - dev->physaddr[3], dev->physaddr[4], dev->physaddr[5]); + dev->dp8390.physaddr[0], dev->dp8390.physaddr[1], dev->dp8390.physaddr[2], + dev->dp8390.physaddr[3], dev->dp8390.physaddr[4], dev->dp8390.physaddr[5]); if (dev->board >= NE2K_RTL8019AS) { if (dev->is_pci) { @@ -2616,7 +2442,7 @@ nic_init(const device_t *info) nic_reset(dev); /* Attach ourselves to the network module. */ - network_attach(dev, dev->physaddr, nic_rx); + network_attach(dev, dev->dp8390.physaddr, nic_rx); nelog(1, "%s: %s attached IO=0x%X IRQ=%d\n", dev->name, dev->is_pci?"PCI":"ISA", dev->base_address, dev->base_irq); diff --git a/src/network/network.c b/src/network/network.c index 0eeef5aa9..107ffef6c 100644 --- a/src/network/network.c +++ b/src/network/network.c @@ -12,7 +12,7 @@ * it should be malloc'ed and then linked to the NETCARD def. * Will be done later. * - * Version: @(#)network.c 1.0.4 2018/04/29 + * Version: @(#)network.c 1.0.5 2018/06/09 * * Author: Fred N. van Kempen, * @@ -60,12 +60,15 @@ #include "../plat.h" #include "../ui.h" #include "network.h" +#include "net_3c503.h" #include "net_ne2000.h" static netcard_t net_cards[] = { { "None", "none", NULL, NULL }, + { "[ISA] 3Com EtherLink II (3C503)","3c503", &threec503_device, + NULL }, { "[ISA] Novell NE1000", "ne1k", &ne1000_device, NULL }, { "[ISA] Novell NE2000", "ne2k", &ne2000_device, @@ -296,7 +299,7 @@ network_reset(void) if (i < 0) { /* Tell user we can't do this (at the moment.) */ - ui_msgbox(MBX_ERROR, (wchar_t *)IDS_2139); + ui_msgbox(MBX_ERROR, (wchar_t *)IDS_2102); // FIXME: we should ask in the dialog if they want to // reconfigure or quit, and throw them into the diff --git a/src/nvr.c b/src/nvr.c index 2f38445b9..2037b68e9 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -8,7 +8,7 @@ * * Implement a generic NVRAM/CMOS/RTC device. * - * Version: @(#)nvr.c 1.0.9 2018/04/29 + * Version: @(#)nvr.c 1.0.10 2018/06/08 * * Author: Fred N. van Kempen, * @@ -117,7 +117,7 @@ nvr_get_days(int month, int year) /* One more second has passed, update the internal clock. */ -static void +void rtc_tick(void) { /* Ping the internal clock. */ @@ -150,7 +150,8 @@ onesec_timer(void *priv) if (++nvr->onesec_cnt >= 100) { /* Update the internal clock. */ - rtc_tick(); + if (!(machines[machine].flags & MACHINE_AT)) + rtc_tick(); /* Update the RTC device if needed. */ if (nvr->tick != NULL) @@ -251,7 +252,8 @@ nvr_load(void) if (saved_nvr == NULL) return(0); /* Clear out any old data. */ - memset(saved_nvr->regs, 0x00, sizeof(saved_nvr->regs)); + // memset(saved_nvr->regs, 0x00, sizeof(saved_nvr->regs)); + memset(saved_nvr->regs, 0xff, sizeof(saved_nvr->regs)); /* Set the defaults. */ if (saved_nvr->reset != NULL) diff --git a/src/nvr.h b/src/nvr.h index 7bfe72ba1..11321fd6a 100644 --- a/src/nvr.h +++ b/src/nvr.h @@ -8,7 +8,7 @@ * * Definitions for the generic NVRAM/CMOS driver. * - * Version: @(#)nvr.h 1.0.6 2018/04/11 + * Version: @(#)nvr.h 1.0.7 2018/06/08 * * Author: Fred N. van Kempen, * @@ -79,12 +79,15 @@ typedef struct _nvr_ { extern int nvr_dosave; #ifdef EMU_DEVICE_H +extern const device_t at_nvr_old_device; extern const device_t at_nvr_device; extern const device_t ps_nvr_device; extern const device_t amstrad_nvr_device; #endif +extern void rtc_tick(void); + extern void nvr_init(nvr_t *); extern wchar_t *nvr_path(wchar_t *str); extern FILE *nvr_fopen(wchar_t *str, wchar_t *mode); diff --git a/src/nvr_at.c b/src/nvr_at.c index 6896be6a8..e6cd8cc71 100644 --- a/src/nvr_at.c +++ b/src/nvr_at.c @@ -311,7 +311,8 @@ time_get(nvr_t *nvr, struct tm *tm) tm->tm_mday = nvr->regs[RTC_DOM]; tm->tm_mon = (nvr->regs[RTC_MONTH] - 1); tm->tm_year = nvr->regs[RTC_YEAR]; - tm->tm_year += (nvr->regs[local->cent] * 100) - 1900; + if (local->cent != 0xFF) + tm->tm_year += (nvr->regs[local->cent] * 100) - 1900; } else { /* NVR is in BCD data mode. */ tm->tm_sec = RTC_DCB(nvr->regs[RTC_SECONDS]); @@ -321,7 +322,8 @@ time_get(nvr_t *nvr, struct tm *tm) tm->tm_mday = RTC_DCB(nvr->regs[RTC_DOM]); tm->tm_mon = (RTC_DCB(nvr->regs[RTC_MONTH]) - 1); tm->tm_year = RTC_DCB(nvr->regs[RTC_YEAR]); - tm->tm_year += (RTC_DCB(nvr->regs[local->cent]) * 100) - 1900; + if (local->cent != 0xFF) + tm->tm_year += (RTC_DCB(nvr->regs[local->cent]) * 100) - 1900; } /* Adjust for 12/24 hour mode. */ @@ -347,7 +349,8 @@ time_set(nvr_t *nvr, struct tm *tm) nvr->regs[RTC_DOM] = tm->tm_mday; nvr->regs[RTC_MONTH] = (tm->tm_mon + 1); nvr->regs[RTC_YEAR] = (year % 100); - nvr->regs[local->cent] = (year / 100); + if (local->cent != 0xFF) + nvr->regs[local->cent] = (year / 100); if (nvr->regs[RTC_REGB] & REGB_2412) { /* NVR is in 24h mode. */ @@ -366,7 +369,8 @@ time_set(nvr_t *nvr, struct tm *tm) nvr->regs[RTC_DOM] = RTC_BCD(tm->tm_mday); nvr->regs[RTC_MONTH] = RTC_BCD(tm->tm_mon + 1); nvr->regs[RTC_YEAR] = RTC_BCD(year % 100); - nvr->regs[local->cent] = RTC_BCD(year / 100); + if (local->cent != 0xFF) + nvr->regs[local->cent] = RTC_BCD(year / 100); if (nvr->regs[RTC_REGB] & REGB_2412) { /* NVR is in 24h mode. */ @@ -451,9 +455,12 @@ timer_recalc(nvr_t *nvr, int add) c = 1ULL << ((nvr->regs[RTC_REGA] & REGA_RS) - 1); nt = (int64_t)(RTCCONST * c * (1<rtctime = nt; + return; + } else if (add == 1) local->rtctime += nt; - else if (local->rtctime > nt) + else if (local->rtctime > nt) local->rtctime = nt; } @@ -494,7 +501,7 @@ timer_tick(nvr_t *nvr) /* Set the UIP bit, announcing the update. */ local->stat = REGA_UIP; - timer_recalc(nvr, 0); + rtc_tick(); /* Schedule the actual update. */ local->ecount = (int64_t)((244.0 + 1984.0) * TIMER_USEC); @@ -545,7 +552,7 @@ nvr_write(uint16_t addr, uint8_t val, void *priv) break; } - if ((local->addr < RTC_REGA) || (local->addr == local->cent)) { + if ((local->addr < RTC_REGA) || ((local->cent != 0xff) && (local->addr == local->cent))) { if ((local->addr != 1) && (local->addr != 3) && (local->addr != 5)) { if ((old != val) && !enable_sync) { /* Update internal clock. */ @@ -611,7 +618,8 @@ nvr_reset(nvr_t *nvr) nvr->regs[RTC_DOM] = 1; nvr->regs[RTC_MONTH] = 1; nvr->regs[RTC_YEAR] = RTC_BCD(80); - nvr->regs[local->cent] = RTC_BCD(19); + if (local->cent != 0xFF) + nvr->regs[local->cent] = RTC_BCD(19); } @@ -656,27 +664,34 @@ nvr_at_init(const device_t *info) nvr = (nvr_t *)malloc(sizeof(nvr_t)); if (nvr == NULL) return(NULL); /* FIXME: See which is correct, this or 0xFF. */ - /* memset(nvr, 0x00, sizeof(nvr_t)); */ - memset(nvr, 0xFF, sizeof(nvr_t)); + if (info->local == 0) + memset(nvr, 0xff, sizeof(nvr_t)); + else + memset(nvr, 0x00, sizeof(nvr_t)); local = (local_t *)malloc(sizeof(local_t)); - memset(local, 0xff, sizeof(local_t)); + memset(local, 0x00, sizeof(local_t)); nvr->data = local; /* This is machine specific. */ nvr->size = machines[machine].nvrmask + 1; switch(info->local) { - case 0: /* standard AT */ + case 0: /* standard AT, no century register */ + nvr->irq = 8; + local->cent = 0xff; + break; + + case 1: /* standard AT */ nvr->irq = 8; local->cent = RTC_CENTURY_AT; break; - case 1: /* PS/1 or PS/2 */ + case 2: /* PS/1 or PS/2 */ nvr->irq = 8; local->cent = RTC_CENTURY_PS; break; - case 2: /* Amstrad PC's */ + case 3: /* Amstrad PC's */ nvr->irq = 1; local->cent = RTC_CENTURY_AT; break; @@ -718,10 +733,19 @@ nvr_at_close(void *priv) } +const device_t at_nvr_old_device = { + "PC/AT NVRAM (No century)", + DEVICE_ISA | DEVICE_AT, + 0, + nvr_at_init, nvr_at_close, NULL, + NULL, NULL, + NULL +}; + const device_t at_nvr_device = { "PC/AT NVRAM", DEVICE_ISA | DEVICE_AT, - 0, + 1, nvr_at_init, nvr_at_close, NULL, NULL, NULL, NULL @@ -730,7 +754,7 @@ const device_t at_nvr_device = { const device_t ps_nvr_device = { "PS/1 or PS/2 NVRAM", DEVICE_PS2, - 1, + 2, nvr_at_init, nvr_at_close, NULL, NULL, NULL, NULL @@ -739,7 +763,7 @@ const device_t ps_nvr_device = { const device_t amstrad_nvr_device = { "Amstrad NVRAM", MACHINE_ISA | MACHINE_AT, - 2, + 3, nvr_at_init, nvr_at_close, NULL, NULL, NULL, NULL diff --git a/src/pc.c b/src/pc.c index 0fb550433..88fa42579 100644 --- a/src/pc.c +++ b/src/pc.c @@ -8,7 +8,7 @@ * * Main emulator module where most things are controlled. * - * Version: @(#)pc.c 1.0.71 2018/04/29 + * Version: @(#)pc.c 1.0.73 2018/06/02 * * Authors: Sarah Walker, * Miran Grca, @@ -57,9 +57,10 @@ #include "disk/hdd.h" #include "disk/hdc.h" #include "disk/hdc_ide.h" -#include "disk/zip.h" #include "scsi/scsi.h" #include "cdrom/cdrom.h" +#include "disk/zip.h" +#include "scsi/scsi_disk.h" #include "cdrom/cdrom_image.h" #include "cdrom/cdrom_null.h" #include "network/network.h" @@ -103,8 +104,7 @@ int vid_cga_contrast = 0, /* (C) video */ video_fullscreen_scale = 0, /* (C) video */ video_fullscreen_first = 0, /* (C) video */ enable_overscan = 0, /* (C) video */ - force_43 = 0, /* (C) video */ - video_speed = 0; /* (C) video */ + force_43 = 0; /* (C) video */ int serial_enabled[SERIAL_MAX] = {0,0}, /* (C) enable serial ports */ lpt_enabled = 0, /* (C) enable LPT ports */ bugger_enabled = 0; /* (C) enable ISAbugger */ @@ -416,6 +416,11 @@ usage: */ wcscpy(usr_path, path); } + + /* If the specified path does not yet exist, + create it. */ + if (! plat_dir_check(path)) + plat_dir_create(path); } /* Make sure we have a trailing backslash. */ @@ -484,6 +489,7 @@ usage: mouse_init(); cdrom_global_init(); zip_global_init(); + scsi_disk_global_init(); /* Load the configuration file. */ config_load(); @@ -500,9 +506,9 @@ pc_full_speed(void) if (! atfullspeed) { pc_log("Set fullspeed - %i %i %i\n", is386, AT, cpuspeed2); - if (AT) + if (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type >= CPU_286) setpitclock(machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].rspeed); - else + else setpitclock(14318184.0); } atfullspeed = 1; @@ -514,9 +520,9 @@ pc_full_speed(void) void pc_speed_changed(void) { - if (AT) + if (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type >= CPU_286) setpitclock(machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].rspeed); - else + else setpitclock(14318184.0); nvr_period_recalc(); @@ -548,6 +554,8 @@ pc_reload(wchar_t *fn) zip_hard_reset(); + scsi_disk_hard_reset(); + fdd_load(0, floppyfns[0]); fdd_load(1, floppyfns[1]); fdd_load(2, floppyfns[2]); @@ -625,7 +633,8 @@ again2: } } - cpuspeed2 = (AT) ? 2 : 1; + // cpuspeed2 = (AT) ? 2 : 1; + cpuspeed2 = (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type >= CPU_286) ? 2 : 1; atfullspeed = 0; random_init(); @@ -650,8 +659,11 @@ again2: hdc_init(hdc_name); cdrom_hard_reset(); + zip_hard_reset(); + scsi_disk_hard_reset(); + scsi_card_init(); pc_full_speed(); @@ -748,8 +760,11 @@ pc_reset_hard_init(void) serial_init(); cdrom_hard_reset(); + zip_hard_reset(); + scsi_disk_hard_reset(); + /* Initialize the actual machine and its basic modules. */ machine_init(); @@ -813,7 +828,7 @@ pc_reset_hard_init(void) pic_reset(); cpu_cache_int_enabled = cpu_cache_ext_enabled = 0; - if (AT) + if (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type >= CPU_286) setpitclock(machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].rspeed); else setpitclock(14318184.0); @@ -876,9 +891,6 @@ pc_close(thread_t *ptr) lpt_devices_close(); - for (i=0; i= CPU_286) { exec386(clockrate/100); } else { execx86(clockrate/100); diff --git a/src/pit.c b/src/pit.c index 3a7565c25..3ba096154 100644 --- a/src/pit.c +++ b/src/pit.c @@ -2,6 +2,7 @@ Write B0 Write aa55 Expects aa55 back*/ +#include #include #include #include diff --git a/src/scsi/scsi.c b/src/scsi/scsi.c index ff36f0b8b..8fc535dc3 100644 --- a/src/scsi/scsi.c +++ b/src/scsi/scsi.c @@ -8,7 +8,7 @@ * * Handling of the SCSI controllers. * - * Version: @(#)scsi.c 1.0.19 2018/04/29 + * Version: @(#)scsi.c 1.0.20 2018/06/02 * * Authors: Miran Grca, * Fred N. van Kempen, @@ -30,10 +30,12 @@ #include "../timer.h" #include "../device.h" #include "../disk/hdc.h" -#include "../disk/zip.h" +#include "../disk/hdd.h" #include "../plat.h" #include "scsi.h" #include "../cdrom/cdrom.h" +#include "../disk/zip.h" +#include "scsi_disk.h" #include "scsi_device.h" #include "scsi_aha154x.h" #include "scsi_buslogic.h" @@ -45,11 +47,9 @@ #include "scsi_x54x.h" -scsi_device_t SCSIDevices[SCSI_ID_MAX][SCSI_LUN_MAX]; -// uint8_t SCSIPhase = 0xff; -// uint8_t SCSIStatus = SCSI_STATUS_OK; +scsi_device_t SCSIDevices[SCSI_ID_MAX]; char scsi_fn[SCSI_NUM][512]; -uint16_t scsi_hd_location[SCSI_NUM]; +uint16_t scsi_disk_location[SCSI_NUM]; int scsi_card_current = 0; int scsi_card_last = 0; @@ -169,30 +169,30 @@ void scsi_mutex(uint8_t start) void scsi_card_init(void) { - int i, j; + int i; if (!scsi_cards[scsi_card_current].device) return; scsi_log("Building SCSI hard disk map...\n"); - build_scsi_hd_map(); + build_scsi_disk_map(); scsi_log("Building SCSI CD-ROM map...\n"); build_scsi_cdrom_map(); scsi_log("Building SCSI ZIP map...\n"); build_scsi_zip_map(); for (i=0; i * Miran Grca, @@ -290,9 +290,9 @@ typedef struct { } scsi_device_t; -extern scsi_device_t SCSIDevices[SCSI_ID_MAX][SCSI_LUN_MAX]; +extern scsi_device_t SCSIDevices[SCSI_ID_MAX]; -extern void SCSIReset(uint8_t id, uint8_t lun); +extern void SCSIReset(uint8_t id); extern int cdrom_add_error_and_subchannel(uint8_t *b, int real_sector_type); extern int cdrom_LBAtoMSF_accurate(void); @@ -314,17 +314,6 @@ extern int scsi_card_get_from_internal_name(char *s); extern void scsi_mutex(uint8_t start); extern void scsi_card_init(void); -extern uint8_t scsi_hard_disks[16][8]; - -extern int scsi_hd_err_stat_to_scsi(uint8_t id); -extern int scsi_hd_phase_to_scsi(uint8_t id); -extern int find_hdc_for_scsi_id(uint8_t scsi_id, uint8_t scsi_lun); -extern void build_scsi_hd_map(void); -extern void scsi_hd_reset(uint8_t id); -extern void scsi_hd_request_sense_for_scsi(uint8_t id, uint8_t *buffer, uint8_t alloc_length); -extern void scsi_hd_command(uint8_t id, uint8_t *cdb); -extern void scsi_hd_callback(uint8_t id); - #pragma pack(push,1) typedef struct { diff --git a/src/scsi/scsi_aha154x.c b/src/scsi/scsi_aha154x.c index 270af90ef..59e48129c 100644 --- a/src/scsi/scsi_aha154x.c +++ b/src/scsi/scsi_aha154x.c @@ -10,7 +10,7 @@ * made by Adaptec, Inc. These controllers were designed for * the ISA bus. * - * Version: @(#)scsi_aha154x.c 1.0.41 2018/04/26 + * Version: @(#)scsi_aha154x.c 1.0.42 2018/06/12 * * Authors: Fred N. van Kempen, * Original Buslogic version by SA1988 and Miran Grca. @@ -573,7 +573,7 @@ aha_mca_write(int port, uint8_t val, void *priv) } /* Say hello. */ - pclog("AHA-1640: I/O=%04x, IRQ=%d, DMA=%d, BIOS @%05X, HOST ID %i\n", + aha_log("AHA-1640: I/O=%04x, IRQ=%d, DMA=%d, BIOS @%05X, HOST ID %i\n", dev->Base, dev->Irq, dev->DmaChannel, dev->rom_addr, dev->HostID); } } diff --git a/src/scsi/scsi_bus.c b/src/scsi/scsi_bus.c index 5d870954d..930c4daff 100644 --- a/src/scsi/scsi_bus.c +++ b/src/scsi/scsi_bus.c @@ -8,7 +8,7 @@ * * The generic SCSI bus operations handler. * - * Version: @(#)scsi_bus.c 1.0.6 2018/01/06 + * Version: @(#)scsi_bus.c 1.0.7 2018/06/18 * * NOTES: For now ported from PCem with some modifications * but at least it's a start. @@ -94,7 +94,6 @@ int scsi_bus_update(scsi_bus_t *bus, int bus_assert) { scsi_device_t *dev; - uint8_t lun = 0; if (bus_assert & BUS_ARB) bus->state = STATE_IDLE; @@ -108,7 +107,7 @@ scsi_bus_update(scsi_bus_t *bus, int bus_assert) bus->dev_id = get_dev_id(sel_data); - if ((bus->dev_id != -1) && scsi_device_present(bus->dev_id, 0)) { + if ((bus->dev_id != -1) && scsi_device_present(bus->dev_id)) { bus->bus_out |= BUS_BSY; bus->state = STATE_PHASESEL; } @@ -122,7 +121,7 @@ scsi_bus_update(scsi_bus_t *bus, int bus_assert) if (! (bus_assert & BUS_SEL)) { if (! (bus_assert & BUS_ATN)) { if ((bus->dev_id != -1) && - scsi_device_present(bus->dev_id, 0)) { + scsi_device_present(bus->dev_id)) { bus->state = STATE_COMMAND; bus->bus_out = BUS_BSY | BUS_REQ; bus->command_pos = 0; @@ -146,20 +145,17 @@ scsi_bus_update(scsi_bus_t *bus, int bus_assert) bus->bus_out &= ~BUS_REQ; if (get_cmd_len(bus->command[0]) == bus->command_pos) { - lun = (bus->command[1] >> 5) & 7; bus->data_pos = 0; - dev = &SCSIDevices[bus->dev_id][lun]; + dev = &SCSIDevices[bus->dev_id]; scsi_bus_log("Command 0x%02X\n", bus->command[0]); dev->BufferLength = -1; - scsi_device_command_phase0(bus->dev_id, lun, - get_cmd_len(bus->command[0]), - bus->command); + scsi_device_command_phase0(bus->dev_id, bus->command); - scsi_bus_log("(%02X:%02X): Command %02X: Buffer Length %i, SCSI Phase %02X\n", bus->dev_id, lun, bus->command[0], dev->BufferLength, dev->Phase); + scsi_bus_log("(ID %02X): Command %02X: Buffer Length %i, SCSI Phase %02X\n", bus->dev_id, bus->command[0], dev->BufferLength, dev->Phase); if ((dev->Phase == SCSI_PHASE_DATA_IN) || (dev->Phase == SCSI_PHASE_DATA_OUT)) { @@ -178,7 +174,7 @@ scsi_bus_update(scsi_bus_t *bus, int bus_assert) /* Other command - execute immediately. */ bus->new_state = dev->Phase; if (dev->Phase == SCSI_PHASE_DATA_IN) { - scsi_device_command_phase1(bus->dev_id, lun); + scsi_device_command_phase1(bus->dev_id); } bus->change_state_delay = 4; @@ -198,12 +194,9 @@ scsi_bus_update(scsi_bus_t *bus, int bus_assert) scsi_bus_log("State Data In\n"); /* This seems to be read, so we first execute the command, then we return the bytes to the host. */ + dev = &SCSIDevices[bus->dev_id]; - lun = (bus->command[1] >> 5) & 7; - - dev = &SCSIDevices[bus->dev_id][lun]; - - if (bus->data_pos >= SCSIDevices[bus->dev_id][lun].BufferLength) { + if (bus->data_pos >= SCSIDevices[bus->dev_id].BufferLength) { free(dev->CmdBuffer); dev->CmdBuffer = NULL; bus->bus_out &= ~BUS_REQ; @@ -224,18 +217,15 @@ scsi_bus_update(scsi_bus_t *bus, int bus_assert) case STATE_DATAOUT: if ((bus_assert & BUS_ACK) && !(bus->bus_in & BUS_ACK)) { scsi_bus_log("State Data Out\n"); - - lun = (bus->command[1] >> 5) & 7; - - dev = &SCSIDevices[bus->dev_id][lun]; + dev = &SCSIDevices[bus->dev_id]; /* This is write, so first get the data from the host, then execute the last phase of the command. */ dev->CmdBuffer[bus->data_pos++] = BUS_GETDATA(bus_assert); - if (bus->data_pos >= SCSIDevices[bus->dev_id][lun].BufferLength) { + if (bus->data_pos >= SCSIDevices[bus->dev_id].BufferLength) { /* scsi_bus_log("%04X bytes written (%02X %02X)\n", bus->data_pos, bus->command[0], bus->command[1]); */ scsi_bus_log("Actually executing write command\n"); - scsi_device_command_phase1(bus->dev_id, lun); + scsi_device_command_phase1(bus->dev_id); free(dev->CmdBuffer); dev->CmdBuffer = NULL; bus->bus_out &= ~BUS_REQ; @@ -281,7 +271,6 @@ int scsi_bus_read(scsi_bus_t *bus) { scsi_device_t *dev; - uint8_t lun = 0; if (bus->clear_req) { bus->clear_req--; @@ -304,8 +293,7 @@ scsi_bus_read(scsi_bus_t *bus) switch (bus->bus_out & SCSI_PHASE_MESSAGE_IN) { case SCSI_PHASE_DATA_IN: - lun = (bus->command[1] >> 5) & 7; - dev = &SCSIDevices[bus->dev_id][lun]; + dev = &SCSIDevices[bus->dev_id]; scsi_bus_log("Phase data in\n"); bus->state = STATE_DATAIN; @@ -324,8 +312,7 @@ scsi_bus_read(scsi_bus_t *bus) break; case SCSI_PHASE_STATUS: - lun = (bus->command[1] >> 5) & 7; - dev = &SCSIDevices[bus->dev_id][lun]; + dev = &SCSIDevices[bus->dev_id]; scsi_bus_log("Phase status\n"); bus->state = STATE_STATUS; diff --git a/src/scsi/scsi_buslogic.c b/src/scsi/scsi_buslogic.c index 6ce2fb2da..bc5eb421c 100644 --- a/src/scsi/scsi_buslogic.c +++ b/src/scsi/scsi_buslogic.c @@ -11,7 +11,7 @@ * 1 - BT-545S ISA; * 2 - BT-958D PCI * - * Version: @(#)scsi_buslogic.c 1.0.38 2018/04/26 + * Version: @(#)scsi_buslogic.c 1.0.39 2018/06/11 * * Authors: TheCollector1995, * Miran Grca, @@ -480,7 +480,7 @@ buslogic_get_irq(void *p) HALocalRAM *HALR = &bl->LocalRAM; - if (bl->chip == CHIP_BUSLOGIC_PCI) + if ((bl->chip == CHIP_BUSLOGIC_ISA_542) || (bl->chip == CHIP_BUSLOGIC_PCI)) return dev->Irq; else return bl_irq[HALR->structured.autoSCSIData.uIrqChannel]; @@ -499,6 +499,8 @@ buslogic_get_dma(void *p) if (bl->chip == CHIP_BUSLOGIC_PCI) return (dev->Base ? 7 : 0); + else if (bl->chip == CHIP_BUSLOGIC_ISA_542) + return dev->DmaChannel; else return bl_dma[HALR->structured.autoSCSIData.uDMAChannel]; } @@ -548,7 +550,7 @@ buslogic_param_len(void *p) static void -BuslogicSCSIBIOSDMATransfer(ESCMD *ESCSICmd, uint8_t TargetID, uint8_t LUN, int dir) +BuslogicSCSIBIOSDMATransfer(ESCMD *ESCSICmd, uint8_t TargetID, int dir) { uint32_t DataPointer = ESCSICmd->DataPointer; int DataLength = ESCSICmd->DataLength; @@ -565,16 +567,16 @@ BuslogicSCSIBIOSDMATransfer(ESCMD *ESCSICmd, uint8_t TargetID, uint8_t LUN, int /* If the control byte is 0x00, it means that the transfer direction is set up by the SCSI command without checking its length, so do this procedure for both read/write commands. */ - if ((DataLength > 0) && (SCSIDevices[TargetID][LUN].BufferLength > 0)) { + if ((DataLength > 0) && (SCSIDevices[TargetID].BufferLength > 0)) { Address = DataPointer; - TransferLength = MIN(DataLength, SCSIDevices[TargetID][LUN].BufferLength); + TransferLength = MIN(DataLength, SCSIDevices[TargetID].BufferLength); if (dir && ((ESCSICmd->DataDirection == CCB_DATA_XFER_OUT) || (ESCSICmd->DataDirection == 0x00))) { buslogic_log("BusLogic BIOS DMA: Reading %i bytes from %08X\n", TransferLength, Address); - DMAPageRead(Address, (uint8_t *)SCSIDevices[TargetID][LUN].CmdBuffer, TransferLength); + DMAPageRead(Address, (uint8_t *)SCSIDevices[TargetID].CmdBuffer, TransferLength); } else if (!dir && ((ESCSICmd->DataDirection == CCB_DATA_XFER_IN) || (ESCSICmd->DataDirection == 0x00))) { buslogic_log("BusLogic BIOS DMA: Writing %i bytes at %08X\n", TransferLength, Address); - DMAPageWrite(Address, (uint8_t *)SCSIDevices[TargetID][LUN].CmdBuffer, TransferLength); + DMAPageWrite(Address, (uint8_t *)SCSIDevices[TargetID].CmdBuffer, TransferLength); } } } @@ -600,14 +602,14 @@ BuslogicSCSIBIOSRequestSetup(x54x_t *dev, uint8_t *CmdBuf, uint8_t *DataInBuf, u buslogic_log("Scanning SCSI Target ID %i\n", ESCSICmd->TargetId); - SCSIDevices[ESCSICmd->TargetId][ESCSICmd->LogicalUnit].Status = SCSI_STATUS_OK; + SCSIDevices[ESCSICmd->TargetId].Status = SCSI_STATUS_OK; - if (!scsi_device_present(ESCSICmd->TargetId, 0)) { - buslogic_log("SCSI Target ID %i has no device attached\n",ESCSICmd->TargetId,ESCSICmd->LogicalUnit); + if (!scsi_device_present(ESCSICmd->TargetId)) { + buslogic_log("SCSI Target ID %i has no device attached\n", ESCSICmd->TargetId); DataInBuf[2] = CCB_SELECTION_TIMEOUT; DataInBuf[3] = SCSI_STATUS_OK; } else { - buslogic_log("SCSI Target ID %i detected and working\n", ESCSICmd->TargetId, ESCSICmd->LogicalUnit); + buslogic_log("SCSI Target ID %i detected and working\n", ESCSICmd->TargetId); buslogic_log("Transfer Control %02X\n", ESCSICmd->DataDirection); buslogic_log("CDB Length %i\n", ESCSICmd->CDBLength); @@ -617,11 +619,11 @@ BuslogicSCSIBIOSRequestSetup(x54x_t *dev, uint8_t *CmdBuf, uint8_t *DataInBuf, u } } - x54x_buf_alloc(ESCSICmd->TargetId, ESCSICmd->LogicalUnit, ESCSICmd->DataLength); + x54x_buf_alloc(ESCSICmd->TargetId, ESCSICmd->DataLength); - target_cdb_len = scsi_device_cdb_length(ESCSICmd->TargetId, ESCSICmd->LogicalUnit); + target_cdb_len = 12; - if (!scsi_device_valid(ESCSICmd->TargetId, ESCSICmd->LogicalUnit)) fatal("SCSI target on %02i:%02i has disappeared\n", ESCSICmd->TargetId, ESCSICmd->LogicalUnit); + if (!scsi_device_valid(ESCSICmd->TargetId)) fatal("SCSI target on ID %02i has disappeared\n", ESCSICmd->TargetId); buslogic_log("SCSI target command being executed on: SCSI ID %i, SCSI LUN %i, Target %i\n", ESCSICmd->TargetId, ESCSICmd->LogicalUnit, target_id); @@ -637,26 +639,26 @@ BuslogicSCSIBIOSRequestSetup(x54x_t *dev, uint8_t *CmdBuf, uint8_t *DataInBuf, u memcpy(temp_cdb, ESCSICmd->CDB, target_cdb_len); } - SCSIDevices[ESCSICmd->TargetId][ESCSICmd->LogicalUnit].BufferLength = ESCSICmd->DataLength; - scsi_device_command_phase0(ESCSICmd->TargetId, ESCSICmd->LogicalUnit, ESCSICmd->CDBLength, temp_cdb); + SCSIDevices[ESCSICmd->TargetId].BufferLength = ESCSICmd->DataLength; + scsi_device_command_phase0(ESCSICmd->TargetId, temp_cdb); - phase = SCSIDevices[ESCSICmd->TargetId][ESCSICmd->LogicalUnit].Phase; + phase = SCSIDevices[ESCSICmd->TargetId].Phase; if (phase != SCSI_PHASE_STATUS) { if (phase == SCSI_PHASE_DATA_IN) - scsi_device_command_phase1(ESCSICmd->TargetId, ESCSICmd->LogicalUnit); - BuslogicSCSIBIOSDMATransfer(ESCSICmd, ESCSICmd->TargetId, ESCSICmd->LogicalUnit, (phase == SCSI_PHASE_DATA_OUT)); + scsi_device_command_phase1(ESCSICmd->TargetId); + BuslogicSCSIBIOSDMATransfer(ESCSICmd, ESCSICmd->TargetId, (phase == SCSI_PHASE_DATA_OUT)); if (phase == SCSI_PHASE_DATA_OUT) - scsi_device_command_phase1(ESCSICmd->TargetId, ESCSICmd->LogicalUnit); + scsi_device_command_phase1(ESCSICmd->TargetId); } - x54x_buf_free(ESCSICmd->TargetId, ESCSICmd->LogicalUnit); + x54x_buf_free(ESCSICmd->TargetId); buslogic_log("BIOS Request complete\n"); - if (SCSIDevices[ESCSICmd->TargetId][ESCSICmd->LogicalUnit].Status == SCSI_STATUS_OK) { + if (SCSIDevices[ESCSICmd->TargetId].Status == SCSI_STATUS_OK) { DataInBuf[2] = CCB_COMPLETE; DataInBuf[3] = SCSI_STATUS_OK; - } else if (SCSIDevices[ESCSICmd->TargetId][ESCSICmd->LogicalUnit].Status == SCSI_STATUS_CHECK_CONDITION) { + } else if (SCSIDevices[ESCSICmd->TargetId].Status == SCSI_STATUS_CHECK_CONDITION) { DataInBuf[2] = CCB_COMPLETE; DataInBuf[3] = SCSI_STATUS_CHECK_CONDITION; } @@ -677,7 +679,6 @@ buslogic_cmds(void *p) uint16_t TargetsPresentMask = 0; uint32_t Offset; int i = 0; - int j = 0; MailboxInitExtended_t *MailboxInitE; ReplyInquireExtendedSetupInformation *ReplyIESI; BuslogicPCIInformation_t *ReplyPI; @@ -697,16 +698,14 @@ buslogic_cmds(void *p) memset(dev->DataBuf, 0, 8); for (i = 8; i < 15; i++) { dev->DataBuf[i-8] = 0; - for (j=0; j<8; j++) { - if (scsi_device_present(i, j) && (i != buslogic_get_host_id(dev))) - dev->DataBuf[i-8] |= (1<DataBuf[i-8] |= 1; } dev->DataReplyLeft = 8; break; case 0x24: for (i=0; i<15; i++) { - if (scsi_device_present(i, 0) && (i != buslogic_get_host_id(dev))) + if (scsi_device_present(i) && (i != buslogic_get_host_id(dev))) TargetsPresentMask |= (1 << i); } dev->DataBuf[0] = TargetsPresentMask & 0xFF; @@ -1387,6 +1386,7 @@ buslogic_mca_write(int port, uint8_t val, void *priv) * pos[2]=000xxxxx = 0 */ dev->HostID = (dev->pos_regs[4] >> 5) & 0x07; + HALR->structured.autoSCSIData.uSCSIId = dev->HostID; /* * SYNC mode is pos[2]=xxxxxx1x. @@ -1406,6 +1406,45 @@ buslogic_mca_write(int port, uint8_t val, void *priv) HALR->structured.autoSCSIData.uBIOSConfiguration &= ~4; HALR->structured.autoSCSIData.uBIOSConfiguration |= (dev->pos_regs[4] & 8) ? 4 : 0; + switch(dev->DmaChannel) { + case 5: + HALR->structured.autoSCSIData.uDMAChannel = 1; + break; + case 6: + HALR->structured.autoSCSIData.uDMAChannel = 2; + break; + case 7: + HALR->structured.autoSCSIData.uDMAChannel = 3; + break; + default: + HALR->structured.autoSCSIData.uDMAChannel = 0; + break; + } + + switch(dev->Irq) { + case 9: + HALR->structured.autoSCSIData.uIrqChannel = 1; + break; + case 10: + HALR->structured.autoSCSIData.uIrqChannel = 2; + break; + case 11: + HALR->structured.autoSCSIData.uIrqChannel = 3; + break; + case 12: + HALR->structured.autoSCSIData.uIrqChannel = 4; + break; + case 14: + HALR->structured.autoSCSIData.uIrqChannel = 5; + break; + case 15: + HALR->structured.autoSCSIData.uIrqChannel = 6; + break; + default: + HALR->structured.autoSCSIData.uIrqChannel = 0; + break; + } + /* * The PS/2 Model 80 BIOS always enables a card if it finds one, * even if no resources were assigned yet (because we only added @@ -1430,8 +1469,8 @@ buslogic_mca_write(int port, uint8_t val, void *priv) } /* Say hello. */ - pclog("BT-640A: I/O=%04x, IRQ=%d, DMA=%d, BIOS @%05X, HOST ID %i\n", - dev->Base, dev->Irq, dev->DmaChannel, bl->bios_addr, dev->HostID); + buslogic_log("BT-640A: I/O=%04x, IRQ=%d, DMA=%d, BIOS @%05X, HOST ID %i\n", + dev->Base, dev->Irq, dev->DmaChannel, bl->bios_addr, dev->HostID); } } diff --git a/src/scsi/scsi_device.c b/src/scsi/scsi_device.c index e4eeb5a0f..f5567cb74 100644 --- a/src/scsi/scsi_device.c +++ b/src/scsi/scsi_device.c @@ -8,7 +8,7 @@ * * The generic SCSI device command handler. * - * Version: @(#)scsi_device.c 1.0.16 2018/03/26 + * Version: @(#)scsi_device.c 1.0.17 2018/06/02 * * Authors: Miran Grca, * Fred N. van Kempen, @@ -23,120 +23,85 @@ #include "../86box.h" #include "../device.h" #include "../disk/hdd.h" -#include "../disk/zip.h" #include "scsi.h" +#include "scsi_device.h" #include "../cdrom/cdrom.h" +#include "../disk/zip.h" #include "scsi_disk.h" -static uint8_t scsi_null_device_sense[14] = { 0x70,0,SENSE_ILLEGAL_REQUEST,0,0,0,0,0,0,0,0,0,ASC_INV_LUN,0 }; +uint8_t scsi_null_device_sense[18] = { 0x70,0,SENSE_ILLEGAL_REQUEST,0,0,0,0,0,0,0,0,0,ASC_INV_LUN,0,0,0,0,0 }; -static uint8_t scsi_device_target_command(int lun_type, uint8_t id, uint8_t *cdb) +static uint8_t +scsi_device_target_command(int lun_type, uint8_t id, uint8_t *cdb) { - if (lun_type == SCSI_DISK) - { - scsi_hd_command(id, cdb); - return scsi_hd_err_stat_to_scsi(id); - } - else if (lun_type == SCSI_CDROM) - { + switch(lun_type) { + case SCSI_DISK: + scsi_disk_command(scsi_disk[id], cdb); + return scsi_disk_err_stat_to_scsi(scsi_disk[id]); + case SCSI_CDROM: cdrom_command(cdrom[id], cdb); return cdrom_CDROM_PHASE_to_scsi(cdrom[id]); - } - else if (lun_type == SCSI_ZIP) - { - zip_command(id, cdb); - return zip_ZIP_PHASE_to_scsi(id); - } - else - { + case SCSI_ZIP: + zip_command(zip[id], cdb); + return zip_ZIP_PHASE_to_scsi(zip[id]); + default: return SCSI_STATUS_CHECK_CONDITION; - } + } } static void scsi_device_target_phase_callback(int lun_type, uint8_t id) { - if (lun_type == SCSI_DISK) - { - scsi_hd_callback(id); - } - else if (lun_type == SCSI_CDROM) - { + switch(lun_type) { + case SCSI_DISK: + scsi_disk_callback(scsi_disk[id]); + break; + case SCSI_CDROM: cdrom_phase_callback(cdrom[id]); - } - else if (lun_type == SCSI_ZIP) - { - zip_phase_callback(id); - } - else - { - return; - } + break; + case SCSI_ZIP: + zip_phase_callback(zip[id]); + break; + } + return; } static int scsi_device_target_err_stat_to_scsi(int lun_type, uint8_t id) { - if (lun_type == SCSI_DISK) - { - return scsi_hd_err_stat_to_scsi(id); - } - else if (lun_type == SCSI_CDROM) - { + switch(lun_type) { + case SCSI_DISK: + return scsi_disk_err_stat_to_scsi(scsi_disk[id]); + case SCSI_CDROM: return cdrom_CDROM_PHASE_to_scsi(cdrom[id]); - } - else if (lun_type == SCSI_ZIP) - { - return zip_ZIP_PHASE_to_scsi(id); - } - else - { + case SCSI_ZIP: + return zip_ZIP_PHASE_to_scsi(zip[id]); + default: return SCSI_STATUS_CHECK_CONDITION; - } + } } -static void scsi_device_target_save_cdb_byte(int lun_type, uint8_t id, uint8_t cdb_byte) +int64_t scsi_device_get_callback(uint8_t scsi_id) { - if (lun_type == SCSI_DISK) - { - shdc[id].request_length = cdb_byte; - } - else if (lun_type == SCSI_CDROM) - { - cdrom[id]->request_length = cdb_byte; - } - else if (lun_type == SCSI_ZIP) - { - zip[id]->request_length = cdb_byte; - } - else - { - return; - } -} - - -int64_t scsi_device_get_callback(uint8_t scsi_id, uint8_t scsi_lun) -{ - uint8_t lun_type = SCSIDevices[scsi_id][scsi_lun].LunType; + uint8_t lun_type = SCSIDevices[scsi_id].LunType; uint8_t id = 0; switch (lun_type) { case SCSI_DISK: - id = scsi_hard_disks[scsi_id][scsi_lun]; - return shdc[id].callback; + id = scsi_disks[scsi_id]; + return scsi_disk[id]->callback; break; case SCSI_CDROM: - id = scsi_cdrom_drives[scsi_id][scsi_lun]; + id = scsi_cdrom_drives[scsi_id]; return cdrom[id]->callback; break; case SCSI_ZIP: - id = scsi_zip_drives[scsi_id][scsi_lun]; + id = scsi_zip_drives[scsi_id]; return zip[id]->callback; break; default: @@ -146,24 +111,24 @@ int64_t scsi_device_get_callback(uint8_t scsi_id, uint8_t scsi_lun) } -uint8_t *scsi_device_sense(uint8_t scsi_id, uint8_t scsi_lun) +uint8_t *scsi_device_sense(uint8_t scsi_id) { - uint8_t lun_type = SCSIDevices[scsi_id][scsi_lun].LunType; + uint8_t lun_type = SCSIDevices[scsi_id].LunType; uint8_t id = 0; switch (lun_type) { case SCSI_DISK: - id = scsi_hard_disks[scsi_id][scsi_lun]; - return shdc[id].sense; + id = scsi_disks[scsi_id]; + return scsi_disk[id]->sense; break; case SCSI_CDROM: - id = scsi_cdrom_drives[scsi_id][scsi_lun]; + id = scsi_cdrom_drives[scsi_id]; return cdrom[id]->sense; break; case SCSI_ZIP: - id = scsi_zip_drives[scsi_id][scsi_lun]; + id = scsi_zip_drives[scsi_id]; return zip[id]->sense; break; default: @@ -173,25 +138,25 @@ uint8_t *scsi_device_sense(uint8_t scsi_id, uint8_t scsi_lun) } -void scsi_device_request_sense(uint8_t scsi_id, uint8_t scsi_lun, uint8_t *buffer, uint8_t alloc_length) +void scsi_device_request_sense(uint8_t scsi_id, uint8_t *buffer, uint8_t alloc_length) { - uint8_t lun_type = SCSIDevices[scsi_id][scsi_lun].LunType; + uint8_t lun_type = SCSIDevices[scsi_id].LunType; uint8_t id = 0; switch (lun_type) { case SCSI_DISK: - id = scsi_hard_disks[scsi_id][scsi_lun]; - scsi_hd_request_sense_for_scsi(id, buffer, alloc_length); + id = scsi_disks[scsi_id]; + scsi_disk_request_sense_for_scsi(scsi_disk[id], buffer, alloc_length); break; case SCSI_CDROM: - id = scsi_cdrom_drives[scsi_id][scsi_lun]; + id = scsi_cdrom_drives[scsi_id]; cdrom_request_sense_for_scsi(cdrom[id], buffer, alloc_length); break; case SCSI_ZIP: - id = scsi_zip_drives[scsi_id][scsi_lun]; - zip_request_sense_for_scsi(id, buffer, alloc_length); + id = scsi_zip_drives[scsi_id]; + zip_request_sense_for_scsi(zip[id], buffer, alloc_length); break; default: memcpy(buffer, scsi_null_device_sense, alloc_length); @@ -200,33 +165,33 @@ void scsi_device_request_sense(uint8_t scsi_id, uint8_t scsi_lun, uint8_t *buffe } -void scsi_device_reset(uint8_t scsi_id, uint8_t scsi_lun) +void scsi_device_reset(uint8_t scsi_id) { - uint8_t lun_type = SCSIDevices[scsi_id][scsi_lun].LunType; + uint8_t lun_type = SCSIDevices[scsi_id].LunType; uint8_t id = 0; switch (lun_type) { case SCSI_DISK: - id = scsi_hard_disks[scsi_id][scsi_lun]; - scsi_hd_reset(id); + id = scsi_disks[scsi_id]; + scsi_disk_reset(scsi_disk[id]); break; case SCSI_CDROM: - id = scsi_cdrom_drives[scsi_id][scsi_lun]; + id = scsi_cdrom_drives[scsi_id]; cdrom_reset(cdrom[id]); break; case SCSI_ZIP: - id = scsi_zip_drives[scsi_id][scsi_lun]; - zip_reset(id); + id = scsi_zip_drives[scsi_id]; + zip_reset(zip[id]); break; } } -void scsi_device_type_data(uint8_t scsi_id, uint8_t scsi_lun, uint8_t *type, uint8_t *rmb) +void scsi_device_type_data(uint8_t scsi_id, uint8_t *type, uint8_t *rmb) { - uint8_t lun_type = SCSIDevices[scsi_id][scsi_lun].LunType; + uint8_t lun_type = SCSIDevices[scsi_id].LunType; switch (lun_type) { @@ -248,32 +213,32 @@ void scsi_device_type_data(uint8_t scsi_id, uint8_t scsi_lun, uint8_t *type, uin } -int scsi_device_read_capacity(uint8_t scsi_id, uint8_t scsi_lun, uint8_t *cdb, uint8_t *buffer, uint32_t *len) +int scsi_device_read_capacity(uint8_t scsi_id, uint8_t *cdb, uint8_t *buffer, uint32_t *len) { - uint8_t lun_type = SCSIDevices[scsi_id][scsi_lun].LunType; + uint8_t lun_type = SCSIDevices[scsi_id].LunType; uint8_t id = 0; switch (lun_type) { case SCSI_DISK: - id = scsi_hard_disks[scsi_id][scsi_lun]; - return scsi_hd_read_capacity(id, cdb, buffer, len); + id = scsi_disks[scsi_id]; + return scsi_disk_read_capacity(scsi_disk[id], cdb, buffer, len); case SCSI_CDROM: - id = scsi_cdrom_drives[scsi_id][scsi_lun]; + id = scsi_cdrom_drives[scsi_id]; return cdrom_read_capacity(cdrom[id], cdb, buffer, len); case SCSI_ZIP: - id = scsi_zip_drives[scsi_id][scsi_lun]; - return zip_read_capacity(id, cdb, buffer, len); + id = scsi_zip_drives[scsi_id]; + return zip_read_capacity(zip[id], cdb, buffer, len); default: return 0; } } -int scsi_device_present(uint8_t scsi_id, uint8_t scsi_lun) +int scsi_device_present(uint8_t scsi_id) { - uint8_t lun_type = SCSIDevices[scsi_id][scsi_lun].LunType; + uint8_t lun_type = SCSIDevices[scsi_id].LunType; switch (lun_type) { @@ -285,22 +250,22 @@ int scsi_device_present(uint8_t scsi_id, uint8_t scsi_lun) } -int scsi_device_valid(uint8_t scsi_id, uint8_t scsi_lun) +int scsi_device_valid(uint8_t scsi_id) { - uint8_t lun_type = SCSIDevices[scsi_id][scsi_lun].LunType; + uint8_t lun_type = SCSIDevices[scsi_id].LunType; uint8_t id = 0; switch (lun_type) { case SCSI_DISK: - id = scsi_hard_disks[scsi_id][scsi_lun]; + id = scsi_disks[scsi_id]; break; case SCSI_CDROM: - id = scsi_cdrom_drives[scsi_id][scsi_lun]; + id = scsi_cdrom_drives[scsi_id]; break; case SCSI_ZIP: - id = scsi_zip_drives[scsi_id][scsi_lun]; + id = scsi_zip_drives[scsi_id]; break; default: id = 0; @@ -311,106 +276,74 @@ int scsi_device_valid(uint8_t scsi_id, uint8_t scsi_lun) } -int scsi_device_cdb_length(uint8_t scsi_id, uint8_t scsi_lun) +int scsi_device_cdb_length(uint8_t scsi_id) { - uint8_t lun_type = SCSIDevices[scsi_id][scsi_lun].LunType; - - uint8_t id = 0; - - switch (lun_type) - { - case SCSI_CDROM: - id = scsi_cdrom_drives[scsi_id][scsi_lun]; - return cdrom[id]->cdb_len; - case SCSI_ZIP: - id = scsi_zip_drives[scsi_id][scsi_lun]; - return zip[id]->cdb_len; - default: - return 12; - } + /* Right now, it's 12 for all devices. */ + return 12; } -void scsi_device_command_phase0(uint8_t scsi_id, uint8_t scsi_lun, int cdb_len, uint8_t *cdb) +void scsi_device_command_phase0(uint8_t scsi_id, uint8_t *cdb) { - uint8_t lun_type = SCSIDevices[scsi_id][scsi_lun].LunType; - uint8_t id = 0; + uint8_t lun_type = SCSIDevices[scsi_id].LunType; - switch (lun_type) - { + switch (lun_type) { case SCSI_DISK: - id = scsi_hard_disks[scsi_id][scsi_lun]; + id = scsi_disks[scsi_id]; break; case SCSI_CDROM: - id = scsi_cdrom_drives[scsi_id][scsi_lun]; + id = scsi_cdrom_drives[scsi_id]; break; case SCSI_ZIP: - id = scsi_zip_drives[scsi_id][scsi_lun]; + id = scsi_zip_drives[scsi_id]; break; default: id = 0; - SCSIDevices[scsi_id][scsi_lun].Phase = SCSI_PHASE_STATUS; - SCSIDevices[scsi_id][scsi_lun].Status = SCSI_STATUS_CHECK_CONDITION; + SCSIDevices[scsi_id].Phase = SCSI_PHASE_STATUS; + SCSIDevices[scsi_id].Status = SCSI_STATUS_CHECK_CONDITION; return; } - /* - * Since that field in the target struct is never used when - * the bus type is SCSI, let's use it for this scope. - */ - scsi_device_target_save_cdb_byte(lun_type, id, cdb[1]); - - if (cdb_len != 12) { - /* - * Make sure the LUN field of the temporary CDB is always 0, - * otherwise Daemon Tools drives will misbehave when a command - * is passed through to them. - */ - cdb[1] &= 0x1f; - } - /* Finally, execute the SCSI command immediately and get the transfer length. */ - SCSIDevices[scsi_id][scsi_lun].Phase = SCSI_PHASE_COMMAND; - SCSIDevices[scsi_id][scsi_lun].Status = scsi_device_target_command(lun_type, id, cdb); + SCSIDevices[scsi_id].Phase = SCSI_PHASE_COMMAND; + SCSIDevices[scsi_id].Status = scsi_device_target_command(lun_type, id, cdb); - if (SCSIDevices[scsi_id][scsi_lun].Phase == SCSI_PHASE_STATUS) { + if (SCSIDevices[scsi_id].Phase == SCSI_PHASE_STATUS) { /* Command completed (either OK or error) - call the phase callback to complete the command. */ scsi_device_target_phase_callback(lun_type, id); } /* If the phase is DATA IN or DATA OUT, finish this here. */ } -void scsi_device_command_phase1(uint8_t scsi_id, uint8_t scsi_lun) +void scsi_device_command_phase1(uint8_t scsi_id) { - uint8_t lun_type = SCSIDevices[scsi_id][scsi_lun].LunType; + uint8_t id = 0; + uint8_t lun_type = SCSIDevices[scsi_id].LunType; - uint8_t id = 0; + switch (lun_type) { + case SCSI_DISK: + id = scsi_disks[scsi_id]; + break; + case SCSI_CDROM: + id = scsi_cdrom_drives[scsi_id]; + break; + case SCSI_ZIP: + id = scsi_zip_drives[scsi_id]; + break; + default: + id = 0; + return; + } - switch (lun_type) - { - case SCSI_DISK: - id = scsi_hard_disks[scsi_id][scsi_lun]; - break; - case SCSI_CDROM: - id = scsi_cdrom_drives[scsi_id][scsi_lun]; - break; - case SCSI_ZIP: - id = scsi_zip_drives[scsi_id][scsi_lun]; - break; - default: - id = 0; - return; - } - - /* Call the second phase. */ - scsi_device_target_phase_callback(lun_type, id); - SCSIDevices[scsi_id][scsi_lun].Status = scsi_device_target_err_stat_to_scsi(lun_type, id); - /* Command second phase complete - call the callback to complete the command. */ - scsi_device_target_phase_callback(lun_type, id); + /* Call the second phase. */ + scsi_device_target_phase_callback(lun_type, id); + SCSIDevices[scsi_id].Status = scsi_device_target_err_stat_to_scsi(lun_type, id); + /* Command second phase complete - call the callback to complete the command. */ + scsi_device_target_phase_callback(lun_type, id); } -int32_t *scsi_device_get_buf_len(uint8_t scsi_id, uint8_t scsi_lun) +int32_t *scsi_device_get_buf_len(uint8_t scsi_id) { - return &SCSIDevices[scsi_id][scsi_lun].BufferLength; + return &SCSIDevices[scsi_id].BufferLength; } diff --git a/src/scsi/scsi_device.h b/src/scsi/scsi_device.h index 23d6cbc02..d0da9a19b 100644 --- a/src/scsi/scsi_device.h +++ b/src/scsi/scsi_device.h @@ -8,7 +8,7 @@ * * Definitions for the generic SCSI device command handler. * - * Version: @(#)scsi_device.h 1.0.7 2018/03/29 + * Version: @(#)scsi_device.h 1.0.8 2018/06/12 * * Authors: Miran Grca, * Fred N. van Kempen, @@ -32,26 +32,21 @@ typedef struct int new_req_delay; } scsi_bus_t; -extern uint8_t *scsi_device_sense(uint8_t id, uint8_t lun); -extern void scsi_device_type_data(uint8_t id, uint8_t lun, - uint8_t *type, uint8_t *rmb); -extern int64_t scsi_device_get_callback(uint8_t scsi_id, uint8_t scsi_lun); -extern void scsi_device_request_sense(uint8_t scsi_id, uint8_t scsi_lun, - uint8_t *buffer, +extern uint8_t *scsi_device_sense(uint8_t id); +extern void scsi_device_type_data(uint8_t id, uint8_t *type, uint8_t *rmb); +extern int64_t scsi_device_get_callback(uint8_t scsi_id); +extern void scsi_device_request_sense(uint8_t scsi_id, uint8_t *buffer, uint8_t alloc_length); -extern void scsi_device_reset(uint8_t scsi_id, uint8_t scsi_lun); -extern int scsi_device_read_capacity(uint8_t id, uint8_t lun, - uint8_t *cdb, uint8_t *buffer, - uint32_t *len); -extern int scsi_device_present(uint8_t id, uint8_t lun); -extern int scsi_device_valid(uint8_t id, uint8_t lun); -extern int scsi_device_cdb_length(uint8_t id, uint8_t lun); -extern void scsi_device_command(uint8_t id, uint8_t lun, int cdb_len, - uint8_t *cdb); -extern void scsi_device_command_phase0(uint8_t scsi_id, uint8_t scsi_lun, - int cdb_len, uint8_t *cdb); -extern void scsi_device_command_phase1(uint8_t scsi_id, uint8_t scsi_lun); -extern int32_t *scsi_device_get_buf_len(uint8_t scsi_id, uint8_t scsi_lun); +extern void scsi_device_reset(uint8_t scsi_id); +extern int scsi_device_read_capacity(uint8_t id, uint8_t *cdb, + uint8_t *buffer, uint32_t *len); +extern int scsi_device_present(uint8_t id); +extern int scsi_device_valid(uint8_t id); +extern int scsi_device_cdb_length(uint8_t id); +extern void scsi_device_command(uint8_t id, int cdb_len, uint8_t *cdb); +extern void scsi_device_command_phase0(uint8_t scsi_id, uint8_t *cdb); +extern void scsi_device_command_phase1(uint8_t scsi_id); +extern int32_t *scsi_device_get_buf_len(uint8_t scsi_id); extern int scsi_bus_update(scsi_bus_t *bus, int bus_assert); extern int scsi_bus_read(scsi_bus_t *bus); diff --git a/src/scsi/scsi_disk.c b/src/scsi/scsi_disk.c index 4a7c0cfe4..22d7f117b 100644 --- a/src/scsi/scsi_disk.c +++ b/src/scsi/scsi_disk.c @@ -6,7 +6,7 @@ * * Emulation of SCSI fixed disks. * - * Version: @(#)scsi_disk.c 1.0.19 2018/03/26 + * Version: @(#)scsi_disk.c 1.0.20 2018/05/28 * * Author: Miran Grca, * @@ -48,37 +48,22 @@ #define MAX_BLOCKS_AT_ONCE 340 -#define scsi_hd_sense_error shdc[id].sense[0] -#define scsi_hd_sense_key shdc[id].sense[2] -#define scsi_hd_asc shdc[id].sense[12] -#define scsi_hd_ascq shdc[id].sense[13] +#define scsi_disk_sense_error dev->sense[0] +#define scsi_disk_sense_key dev->sense[2] +#define scsi_disk_asc dev->sense[12] +#define scsi_disk_ascq dev->sense[13] -scsi_hard_disk_t shdc[HDD_NUM]; -FILE *shdf[HDD_NUM]; +scsi_disk_t *scsi_disk[HDD_NUM]; -uint8_t scsi_hard_disks[16][8] = { - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } +uint8_t scsi_disks[16] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; /* Table of all SCSI commands and their flags, needed for the new disc change / not ready handler. */ -const uint8_t scsi_hd_command_flags[0x100] = { +const uint8_t scsi_disk_command_flags[0x100] = { IMPLEMENTED | CHECK_READY | NONDATA, /* 0x00 */ IMPLEMENTED | ALLOW_UA | NONDATA | SCSI_ONLY, /* 0x01 */ 0, @@ -88,7 +73,8 @@ const uint8_t scsi_hd_command_flags[0x100] = { IMPLEMENTED | CHECK_READY, /* 0x08 */ 0, IMPLEMENTED | CHECK_READY, /* 0x0A */ - 0, 0, 0, 0, 0, 0, 0, + IMPLEMENTED | CHECK_READY | NONDATA, /* 0x0B */ + 0, 0, 0, 0, 0, 0, IMPLEMENTED | ALLOW_UA, /* 0x12 */ IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, /* 0x13 */ 0, @@ -106,7 +92,8 @@ const uint8_t scsi_hd_command_flags[0x100] = { IMPLEMENTED | CHECK_READY, /* 0x28 */ 0, IMPLEMENTED | CHECK_READY, /* 0x2A */ - 0, 0, 0, + IMPLEMENTED | CHECK_READY | NONDATA, /* 0x2B */ + 0, 0, IMPLEMENTED | CHECK_READY, /* 0x2E */ IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, /* 0x2F */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -139,36 +126,34 @@ const uint8_t scsi_hd_command_flags[0x100] = { }; -uint64_t scsi_hd_mode_sense_page_flags = (1LL << 0x03) | (1LL << 0x04) | (1LL << 0x30) | (1LL << 0x3F); +uint64_t scsi_disk_mode_sense_page_flags = (1LL << 0x03) | (1LL << 0x04) | (1LL << 0x30) | (1LL << 0x3F); /* This should be done in a better way but for time being, it's been done this way so it's not as huge and more readable. */ -static const mode_sense_pages_t scsi_hd_mode_sense_pages_default = +static const mode_sense_pages_t scsi_disk_mode_sense_pages_default = { { [0x03] = { 0x03, 0x16, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, [0x04] = { 0x04, 0x16, 0, 0x10, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x10, 0, 0, 0 }, [0x30] = { 0xB0, 0x16, '8', '6', 'B', 'o', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' } } }; -static const mode_sense_pages_t scsi_hd_mode_sense_pages_changeable = +static const mode_sense_pages_t scsi_disk_mode_sense_pages_changeable = { { [0x03] = { 0x03, 0x16, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, [0x04] = { 0x04, 0x16, 0, 0x10, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x10, 0, 0, 0 }, [0x30] = { 0xB0, 0x16, '8', '6', 'B', 'o', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' } } }; -static mode_sense_pages_t scsi_hd_mode_sense_pages_saved[HDD_NUM]; - #ifdef ENABLE_SCSI_DISK_LOG -int scsi_hd_do_log = ENABLE_SCSI_DISK_LOG; +int scsi_disk_do_log = ENABLE_SCSI_DISK_LOG; #endif static void -scsi_hd_log(const char *fmt, ...) +scsi_disk_log(const char *fmt, ...) { #ifdef ENABLE_SCSI_DISK_LOG va_list ap; - if (scsi_hd_do_log) { + if (scsi_disk_do_log) { va_start(ap, fmt); pclog_ex(fmt, ap); va_end(ap); @@ -179,9 +164,9 @@ scsi_hd_log(const char *fmt, ...) /* Translates ATAPI status (ERR_STAT flag) to SCSI status. */ int -scsi_hd_err_stat_to_scsi(uint8_t id) +scsi_disk_err_stat_to_scsi(scsi_disk_t *dev) { - if (shdc[id].status & ERR_STAT) + if (dev->status & ERR_STAT) return SCSI_STATUS_CHECK_CONDITION; else return SCSI_STATUS_OK; @@ -189,7 +174,7 @@ scsi_hd_err_stat_to_scsi(uint8_t id) int -find_hdd_for_scsi_id(uint8_t scsi_id, uint8_t scsi_lun) +find_hdd_for_scsi_id(uint8_t scsi_id) { uint8_t i = 0; @@ -198,7 +183,7 @@ find_hdd_for_scsi_id(uint8_t scsi_id, uint8_t scsi_lun) continue; if ((hdd[i].spt == 0) || (hdd[i].hpc == 0) || (hdd[i].tracks == 0)) continue; - if ((hdd[i].bus == HDD_BUS_SCSI) && (hdd[i].scsi_id == scsi_id) && (hdd[i].scsi_lun == scsi_lun)) + if ((hdd[i].bus == HDD_BUS_SCSI) && (hdd[i].scsi_id == scsi_id)) return i; } return 0xff; @@ -206,77 +191,74 @@ find_hdd_for_scsi_id(uint8_t scsi_id, uint8_t scsi_lun) void -scsi_loadhd(int scsi_id, int scsi_lun, int id) +scsi_loadhd(int scsi_id, int id) { if (! hdd_image_load(id)) - scsi_hard_disks[scsi_id][scsi_lun] = 0xff; + scsi_disks[scsi_id] = 0xff; } void -build_scsi_hd_map(void) +build_scsi_disk_map(void) { - uint8_t i = 0, j = 0; + uint8_t i = 0; - for (i = 0; i < 16; i++) - memset(scsi_hard_disks[i], 0xff, 8); + memset(scsi_disks, 0xff, 16); for (i = 0; i < 16; i++) { - for (j = 0; j < 8; j++) { - scsi_hard_disks[i][j] = find_hdd_for_scsi_id(i, j); - if (scsi_hard_disks[i][j] != 0xff) { - memset(&(shdc[scsi_hard_disks[i][j]]), 0, - sizeof(shdc[scsi_hard_disks[i][j]])); - if (wcslen(hdd[scsi_hard_disks[i][j]].fn) > 0) - scsi_loadhd(i, j, scsi_hard_disks[i][j]); - } + scsi_disks[i] = find_hdd_for_scsi_id(i); + if (scsi_disks[i] != 0xff) { + if (wcslen(hdd[scsi_disks[i]].fn) > 0) + scsi_loadhd(i, scsi_disks[i]); } } } void -scsi_hd_mode_sense_load(uint8_t id) +scsi_disk_mode_sense_load(scsi_disk_t *dev) { FILE *f; wchar_t file_name[512]; int i; - memset(&scsi_hd_mode_sense_pages_saved[id], 0, sizeof(mode_sense_pages_t)); + memset(&dev->ms_pages_saved, 0, sizeof(mode_sense_pages_t)); for (i = 0; i < 0x3f; i++) { - if (scsi_hd_mode_sense_pages_default.pages[i][1] != 0) - memcpy(scsi_hd_mode_sense_pages_saved[id].pages[i], scsi_hd_mode_sense_pages_default.pages[i], scsi_hd_mode_sense_pages_default.pages[i][1] + 2); + if (scsi_disk_mode_sense_pages_default.pages[i][1] != 0) { + memcpy(dev->ms_pages_saved.pages[i], scsi_disk_mode_sense_pages_default.pages[i], + scsi_disk_mode_sense_pages_default.pages[i][1] + 2); + } } - swprintf(file_name, 512, L"scsi_hd_%02i_mode_sense.bin", id); + swprintf(file_name, 512, L"scsi_disk_%02i_mode_sense.bin", dev->id); memset(file_name, 0, 512 * sizeof(wchar_t)); f = plat_fopen(nvr_path(file_name), L"rb"); if (f) { - fread(scsi_hd_mode_sense_pages_saved[id].pages[0x30], 1, 0x18, f); + fread(dev->ms_pages_saved.pages[0x30], 1, 0x18, f); fclose(f); } } void -scsi_hd_mode_sense_save(uint8_t id) +scsi_disk_mode_sense_save(scsi_disk_t *dev) { FILE *f; wchar_t file_name[512]; memset(file_name, 0, 512 * sizeof(wchar_t)); - swprintf(file_name, 512, L"scsi_hd_%02i_mode_sense.bin", id); + swprintf(file_name, 512, L"scsi_disk_%02i_mode_sense.bin", dev->id); f = plat_fopen(nvr_path(file_name), L"wb"); if (f) { - fwrite(scsi_hd_mode_sense_pages_saved[id].pages[0x30], 1, 0x18, f); + fwrite(dev->ms_pages_saved.pages[0x30], 1, 0x18, f); fclose(f); } } int -scsi_hd_read_capacity(uint8_t id, uint8_t *cdb, uint8_t *buffer, uint32_t *len) +scsi_disk_read_capacity(scsi_disk_t *dev, uint8_t *cdb, uint8_t *buffer, uint32_t *len) { int size = 0; - size = hdd_image_get_last_sector(id); + size = hdd_image_get_last_sector(dev->id); memset(buffer, 0, 8); buffer[0] = (size >> 24) & 0xff; buffer[1] = (size >> 16) & 0xff; @@ -291,18 +273,18 @@ scsi_hd_read_capacity(uint8_t id, uint8_t *cdb, uint8_t *buffer, uint32_t *len) /*SCSI Mode Sense 6/10*/ uint8_t -scsi_hd_mode_sense_read(uint8_t id, uint8_t page_control, uint8_t page, uint8_t pos) +scsi_disk_mode_sense_read(scsi_disk_t *dev, uint8_t page_control, uint8_t page, uint8_t pos) { switch (page_control) { case 0: case 3: - return scsi_hd_mode_sense_pages_saved[id].pages[page][pos]; + return dev->ms_pages_saved.pages[page][pos]; break; case 1: - return scsi_hd_mode_sense_pages_changeable.pages[page][pos]; + return scsi_disk_mode_sense_pages_changeable.pages[page][pos]; break; case 2: - return scsi_hd_mode_sense_pages_default.pages[page][pos]; + return scsi_disk_mode_sense_pages_default.pages[page][pos]; break; } @@ -311,7 +293,7 @@ scsi_hd_mode_sense_read(uint8_t id, uint8_t page_control, uint8_t page, uint8_t uint32_t -scsi_hd_mode_sense(uint8_t id, uint8_t *buf, uint32_t pos, uint8_t type, uint8_t block_descriptor_len) +scsi_disk_mode_sense(scsi_disk_t *dev, uint8_t *buf, uint32_t pos, uint8_t type, uint8_t block_descriptor_len) { uint8_t msplen, page_control = (type >> 6) & 3; @@ -320,7 +302,7 @@ scsi_hd_mode_sense(uint8_t id, uint8_t *buf, uint32_t pos, uint8_t type, uint8_t type &= 0x3f; - size = hdd_image_get_last_sector(id); + size = hdd_image_get_last_sector(dev->id); if (block_descriptor_len) { buf[pos++] = 1; /* Density code. */ @@ -335,13 +317,13 @@ scsi_hd_mode_sense(uint8_t id, uint8_t *buf, uint32_t pos, uint8_t type, uint8_t for (i = 0; i < 0x40; i++) { if ((type == GPMODE_ALL_PAGES) || (type == i)) { - if (scsi_hd_mode_sense_page_flags & (1LL << shdc[id].current_page_code)) { - buf[pos++] = scsi_hd_mode_sense_read(id, page_control, i, 0); - msplen = scsi_hd_mode_sense_read(id, page_control, i, 1); + if (scsi_disk_mode_sense_page_flags & (1LL << dev->current_page_code)) { + buf[pos++] = scsi_disk_mode_sense_read(dev, page_control, i, 0); + msplen = scsi_disk_mode_sense_read(dev, page_control, i, 1); buf[pos++] = msplen; - scsi_hd_log("SCSI HDD %i: MODE SENSE: Page [%02X] length %i\n", id, i, msplen); + scsi_disk_log("SCSI HDD %i: MODE SENSE: Page [%02X] length %i\n", dev->id, i, msplen); for (j = 0; j < msplen; j++) - buf[pos++] = scsi_hd_mode_sense_read(id, page_control, i, 2 + j); + buf[pos++] = scsi_disk_mode_sense_read(dev, page_control, i, 2 + j); } } } @@ -351,250 +333,250 @@ scsi_hd_mode_sense(uint8_t id, uint8_t *buf, uint32_t pos, uint8_t type, uint8_t static void -scsi_hd_command_common(uint8_t id) +scsi_disk_command_common(scsi_disk_t *dev) { - shdc[id].status = BUSY_STAT; - shdc[id].phase = 1; - if (shdc[id].packet_status == CDROM_PHASE_COMPLETE) { - scsi_hd_callback(id); - shdc[id].callback = 0LL; + dev->status = BUSY_STAT; + dev->phase = 1; + if (dev->packet_status == CDROM_PHASE_COMPLETE) { + scsi_disk_callback(dev); + dev->callback = 0LL; } else - shdc[id].callback = -1LL; /* Speed depends on SCSI controller */ + dev->callback = -1LL; /* Speed depends on SCSI controller */ } static void -scsi_hd_command_complete(uint8_t id) +scsi_disk_command_complete(scsi_disk_t *dev) { - shdc[id].packet_status = CDROM_PHASE_COMPLETE; - scsi_hd_command_common(id); + dev->packet_status = CDROM_PHASE_COMPLETE; + scsi_disk_command_common(dev); } static void -scsi_hd_command_read_dma(uint8_t id) +scsi_disk_command_read_dma(scsi_disk_t *dev) { - shdc[id].packet_status = CDROM_PHASE_DATA_IN_DMA; - scsi_hd_command_common(id); + dev->packet_status = CDROM_PHASE_DATA_IN_DMA; + scsi_disk_command_common(dev); } static void -scsi_hd_command_write_dma(uint8_t id) +scsi_disk_command_write_dma(scsi_disk_t *dev) { - shdc[id].packet_status = CDROM_PHASE_DATA_OUT_DMA; - scsi_hd_command_common(id); + dev->packet_status = CDROM_PHASE_DATA_OUT_DMA; + scsi_disk_command_common(dev); } static void -scsi_hd_data_command_finish(uint8_t id, int len, int block_len, int alloc_len, int direction) +scsi_disk_data_command_finish(scsi_disk_t *dev, int len, int block_len, int alloc_len, int direction) { - scsi_hd_log("SCSI HD %i: Finishing command (%02X): %i, %i, %i, %i, %i\n", id, - shdc[id].current_cdb[0], len, block_len, alloc_len, direction, shdc[id].request_length); + scsi_disk_log("SCSI HD %i: Finishing command (%02X): %i, %i, %i, %i, %i\n", dev->id, + dev->current_cdb[0], len, block_len, alloc_len, direction, dev->request_length); if (alloc_len >= 0) { if (alloc_len < len) len = alloc_len; } if (len == 0) - scsi_hd_command_complete(id); + scsi_disk_command_complete(dev); else { if (direction == 0) - scsi_hd_command_read_dma(id); + scsi_disk_command_read_dma(dev); else - scsi_hd_command_write_dma(id); + scsi_disk_command_write_dma(dev); } } static void -scsi_hd_sense_clear(int id, int command) +scsi_disk_sense_clear(scsi_disk_t *dev, int command) { - scsi_hd_sense_key = scsi_hd_asc = scsi_hd_ascq = 0; + scsi_disk_sense_key = scsi_disk_asc = scsi_disk_ascq = 0; } static void -scsi_hd_set_phase(uint8_t id, uint8_t phase) +scsi_disk_set_phase(scsi_disk_t *dev, uint8_t phase) { - uint8_t scsi_id = hdd[id].scsi_id; - uint8_t scsi_lun = hdd[id].scsi_lun; + uint8_t scsi_id = dev->drv->scsi_id; - if (hdd[id].bus != HDD_BUS_SCSI) + if (dev->drv->bus != HDD_BUS_SCSI) return; - SCSIDevices[scsi_id][scsi_lun].Phase = phase; + SCSIDevices[scsi_id].Phase = phase; } static void -scsi_hd_cmd_error(uint8_t id) +scsi_disk_cmd_error(scsi_disk_t *dev) { - scsi_hd_set_phase(id, SCSI_PHASE_STATUS); - shdc[id].error = ((scsi_hd_sense_key & 0xf) << 4) | ABRT_ERR; - shdc[id].status = READY_STAT | ERR_STAT; - shdc[id].phase = 3; - shdc[id].packet_status = 0x80; - shdc[id].callback = 50 * SCSI_TIME; - scsi_hd_log("SCSI HD %i: ERROR: %02X/%02X/%02X\n", id, scsi_hd_sense_key, scsi_hd_asc, scsi_hd_ascq); + scsi_disk_set_phase(dev, SCSI_PHASE_STATUS); + dev->error = ((scsi_disk_sense_key & 0xf) << 4) | ABRT_ERR; + dev->status = READY_STAT | ERR_STAT; + dev->phase = 3; + dev->packet_status = 0x80; + dev->callback = 50 * SCSI_TIME; + scsi_disk_log("SCSI HD %i: ERROR: %02X/%02X/%02X\n", dev->id, scsi_disk_sense_key, scsi_disk_asc, scsi_disk_ascq); } static void -scsi_hd_invalid_lun(uint8_t id) +scsi_disk_invalid_lun(scsi_disk_t *dev) { - scsi_hd_sense_key = SENSE_ILLEGAL_REQUEST; - scsi_hd_asc = ASC_INV_LUN; - scsi_hd_ascq = 0; - scsi_hd_set_phase(id, SCSI_PHASE_STATUS); - scsi_hd_cmd_error(id); + scsi_disk_sense_key = SENSE_ILLEGAL_REQUEST; + scsi_disk_asc = ASC_INV_LUN; + scsi_disk_ascq = 0; + scsi_disk_set_phase(dev, SCSI_PHASE_STATUS); + scsi_disk_cmd_error(dev); } static void -scsi_hd_illegal_opcode(uint8_t id) +scsi_disk_illegal_opcode(scsi_disk_t *dev) { - scsi_hd_sense_key = SENSE_ILLEGAL_REQUEST; - scsi_hd_asc = ASC_ILLEGAL_OPCODE; - scsi_hd_ascq = 0; - scsi_hd_cmd_error(id); + scsi_disk_sense_key = SENSE_ILLEGAL_REQUEST; + scsi_disk_asc = ASC_ILLEGAL_OPCODE; + scsi_disk_ascq = 0; + scsi_disk_cmd_error(dev); } static void -scsi_hd_lba_out_of_range(uint8_t id) +scsi_disk_lba_out_of_range(scsi_disk_t *dev) { - scsi_hd_sense_key = SENSE_ILLEGAL_REQUEST; - scsi_hd_asc = ASC_LBA_OUT_OF_RANGE; - scsi_hd_ascq = 0; - scsi_hd_cmd_error(id); + scsi_disk_sense_key = SENSE_ILLEGAL_REQUEST; + scsi_disk_asc = ASC_LBA_OUT_OF_RANGE; + scsi_disk_ascq = 0; + scsi_disk_cmd_error(dev); } static void -scsi_hd_invalid_field(uint8_t id) +scsi_disk_invalid_field(scsi_disk_t *dev) { - scsi_hd_sense_key = SENSE_ILLEGAL_REQUEST; - scsi_hd_asc = ASC_INV_FIELD_IN_CMD_PACKET; - scsi_hd_ascq = 0; - scsi_hd_cmd_error(id); - shdc[id].status = 0x53; + scsi_disk_sense_key = SENSE_ILLEGAL_REQUEST; + scsi_disk_asc = ASC_INV_FIELD_IN_CMD_PACKET; + scsi_disk_ascq = 0; + scsi_disk_cmd_error(dev); + dev->status = 0x53; } static void -scsi_hd_invalid_field_pl(uint8_t id) +scsi_disk_invalid_field_pl(scsi_disk_t *dev) { - scsi_hd_sense_key = SENSE_ILLEGAL_REQUEST; - scsi_hd_asc = ASC_INV_FIELD_IN_PARAMETER_LIST; - scsi_hd_ascq = 0; - scsi_hd_cmd_error(id); - shdc[id].status = 0x53; + scsi_disk_sense_key = SENSE_ILLEGAL_REQUEST; + scsi_disk_asc = ASC_INV_FIELD_IN_PARAMETER_LIST; + scsi_disk_ascq = 0; + scsi_disk_cmd_error(dev); + dev->status = 0x53; } static void -scsi_hd_data_phase_error(uint8_t id) +scsi_disk_data_phase_error(scsi_disk_t *dev) { - scsi_hd_sense_key = SENSE_ILLEGAL_REQUEST; - scsi_hd_asc = ASC_DATA_PHASE_ERROR; - scsi_hd_ascq = 0; - scsi_hd_cmd_error(id); + scsi_disk_sense_key = SENSE_ILLEGAL_REQUEST; + scsi_disk_asc = ASC_DATA_PHASE_ERROR; + scsi_disk_ascq = 0; + scsi_disk_cmd_error(dev); } static int -scsi_hd_pre_execution_check(uint8_t id, uint8_t *cdb) +scsi_disk_pre_execution_check(scsi_disk_t *dev, uint8_t *cdb) { - if (((shdc[id].request_length >> 5) & 7) != hdd[id].scsi_lun) { - scsi_hd_log("SCSI HD %i: Attempting to execute a unknown command targeted at SCSI LUN %i\n", - id, ((shdc[id].request_length >> 5) & 7)); - scsi_hd_invalid_lun(id); + if ((cdb[0] != GPCMD_REQUEST_SENSE) && (cdb[1] & 0xe0)) { + scsi_disk_log("SCSI HD %i: Attempting to execute a unknown command targeted at SCSI LUN %i\n", + dev->id, ((dev->request_length >> 5) & 7)); + scsi_disk_invalid_lun(dev); return 0; } - if (!(scsi_hd_command_flags[cdb[0]] & IMPLEMENTED)) { - scsi_hd_log("SCSI HD %i: Attempting to execute unknown command %02X\n", id, cdb[0]); - scsi_hd_illegal_opcode(id); + if (!(scsi_disk_command_flags[cdb[0]] & IMPLEMENTED)) { + scsi_disk_log("SCSI HD %i: Attempting to execute unknown command %02X\n", dev->id, cdb[0]); + scsi_disk_illegal_opcode(dev); return 0; } /* Unless the command is REQUEST SENSE, clear the sense. This will *NOT* the UNIT ATTENTION condition if it's set. */ if (cdb[0] != GPCMD_REQUEST_SENSE) - scsi_hd_sense_clear(id, cdb[0]); + scsi_disk_sense_clear(dev, cdb[0]); - scsi_hd_log("SCSI HD %i: Continuing with command\n", id); + scsi_disk_log("SCSI HD %i: Continuing with command\n", dev->id); return 1; } static void -scsi_hd_seek(uint8_t id, uint32_t pos) +scsi_disk_seek(scsi_disk_t *dev, uint32_t pos) { - /* scsi_hd_log("SCSI HD %i: Seek %08X\n", id, pos); */ - hdd_image_seek(id, pos); + /* scsi_disk_log("SCSI HD %i: Seek %08X\n", dev->id, pos); */ + hdd_image_seek(dev->id, pos); } static void -scsi_hd_rezero(uint8_t id) +scsi_disk_rezero(scsi_disk_t *dev) { - if (id == 0xff) + if (dev->id == 0xff) return; - shdc[id].sector_pos = shdc[id].sector_len = 0; - scsi_hd_seek(id, 0); + dev->sector_pos = dev->sector_len = 0; + scsi_disk_seek(dev, 0); } void -scsi_hd_reset(uint8_t id) +scsi_disk_reset(scsi_disk_t *dev) { - scsi_hd_rezero(id); - shdc[id].status = 0; - shdc[id].callback = 0; - shdc[id].packet_status = 0xff; + scsi_disk_rezero(dev); + dev->status = 0; + dev->callback = 0; + dev->packet_status = 0xff; } void -scsi_hd_request_sense(uint8_t id, uint8_t *buffer, uint8_t alloc_length, int desc) +scsi_disk_request_sense(scsi_disk_t *dev, uint8_t *buffer, uint8_t alloc_length, int desc) { /*Will return 18 bytes of 0*/ if (alloc_length != 0) { memset(buffer, 0, alloc_length); if (!desc) - memcpy(buffer, shdc[id].sense, alloc_length); + memcpy(buffer, dev->sense, alloc_length); else { - buffer[1] = scsi_hd_sense_key; - buffer[2] = scsi_hd_asc; - buffer[3] = scsi_hd_ascq; + buffer[1] = scsi_disk_sense_key; + buffer[2] = scsi_disk_asc; + buffer[3] = scsi_disk_ascq; } } else return; buffer[0] = 0x70; - scsi_hd_log("SCSI HD %i: Reporting sense: %02X %02X %02X\n", id, buffer[2], buffer[12], buffer[13]); + scsi_disk_log("SCSI HD %i: Reporting sense: %02X %02X %02X\n", dev->id, buffer[2], buffer[12], buffer[13]); /* Clear the sense stuff as per the spec. */ - scsi_hd_sense_clear(id, GPCMD_REQUEST_SENSE); + scsi_disk_sense_clear(dev, GPCMD_REQUEST_SENSE); } void -scsi_hd_request_sense_for_scsi(uint8_t id, uint8_t *buffer, uint8_t alloc_length) +scsi_disk_request_sense_for_scsi(scsi_disk_t *dev, uint8_t *buffer, uint8_t alloc_length) { - scsi_hd_request_sense(id, buffer, alloc_length, 0); + scsi_disk_request_sense(dev, buffer, alloc_length, 0); } void -scsi_hd_command(uint8_t id, uint8_t *cdb) +scsi_disk_command(scsi_disk_t *dev, uint8_t *cdb) { - uint8_t *hdbufferb = SCSIDevices[hdd[id].scsi_id][hdd[id].scsi_lun].CmdBuffer; + uint8_t *hdbufferb; + int32_t *BufLen; uint32_t len; int max_len, pos = 0; unsigned idx = 0; @@ -603,60 +585,62 @@ scsi_hd_command(uint8_t id, uint8_t *cdb) char device_identify[9] = { '8', '6', 'B', '_', 'H', 'D', '0', '0', 0 }; char device_identify_ex[15] = { '8', '6', 'B', '_', 'H', 'D', '0', '0', ' ', 'v', '1', '.', '0', '0', 0 }; int block_desc = 0; - int32_t *BufLen = &SCSIDevices[hdd[id].scsi_id][hdd[id].scsi_lun].BufferLength; - last_sector = hdd_image_get_last_sector(id); + hdbufferb = SCSIDevices[dev->drv->scsi_id].CmdBuffer; + BufLen = &SCSIDevices[dev->drv->scsi_id].BufferLength; - shdc[id].status &= ~ERR_STAT; - shdc[id].packet_len = 0; + last_sector = hdd_image_get_last_sector(dev->id); - device_identify[6] = (id / 10) + 0x30; - device_identify[7] = (id % 10) + 0x30; + dev->status &= ~ERR_STAT; + dev->packet_len = 0; - device_identify_ex[6] = (id / 10) + 0x30; - device_identify_ex[7] = (id % 10) + 0x30; + device_identify[6] = (dev->id / 10) + 0x30; + device_identify[7] = (dev->id % 10) + 0x30; + + device_identify_ex[6] = (dev->id / 10) + 0x30; + device_identify_ex[7] = (dev->id % 10) + 0x30; device_identify_ex[10] = EMU_VERSION[0]; device_identify_ex[12] = EMU_VERSION[2]; device_identify_ex[13] = EMU_VERSION[3]; - memcpy(shdc[id].current_cdb, cdb, 12); + memcpy(dev->current_cdb, cdb, 12); if (cdb[0] != 0) { - scsi_hd_log("SCSI HD %i: Command 0x%02X, Sense Key %02X, Asc %02X, Ascq %02X\n", - id, cdb[0], scsi_hd_sense_key, scsi_hd_asc, scsi_hd_ascq); - scsi_hd_log("SCSI HD %i: Request length: %04X\n", id, shdc[id].request_length); + scsi_disk_log("SCSI HD %i: Command 0x%02X, Sense Key %02X, Asc %02X, Ascq %02X\n", + dev->id, cdb[0], scsi_disk_sense_key, scsi_disk_asc, scsi_disk_ascq); + scsi_disk_log("SCSI HD %i: Request length: %04X\n", dev->id, dev->request_length); - scsi_hd_log("SCSI HD %i: CDB: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", id, + scsi_disk_log("SCSI HD %i: CDB: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", dev->id, cdb[0], cdb[1], cdb[2], cdb[3], cdb[4], cdb[5], cdb[6], cdb[7], cdb[8], cdb[9], cdb[10], cdb[11]); } - shdc[id].sector_len = 0; + dev->sector_len = 0; - scsi_hd_set_phase(id, SCSI_PHASE_STATUS); + scsi_disk_set_phase(dev, SCSI_PHASE_STATUS); /* This handles the Not Ready/Unit Attention check if it has to be handled at this point. */ - if (scsi_hd_pre_execution_check(id, cdb) == 0) + if (scsi_disk_pre_execution_check(dev, cdb) == 0) return; switch (cdb[0]) { case GPCMD_SEND_DIAGNOSTIC: if (!(cdb[1] & (1 << 2))) { - scsi_hd_invalid_field(id); + scsi_disk_invalid_field(dev); return; } case GPCMD_SCSI_RESERVE: case GPCMD_SCSI_RELEASE: case GPCMD_TEST_UNIT_READY: case GPCMD_FORMAT_UNIT: - scsi_hd_set_phase(id, SCSI_PHASE_STATUS); - scsi_hd_command_complete(id); + scsi_disk_set_phase(dev, SCSI_PHASE_STATUS); + scsi_disk_command_complete(dev); break; case GPCMD_REZERO_UNIT: - shdc[id].sector_pos = shdc[id].sector_len = 0; - scsi_hd_seek(id, 0); - scsi_hd_set_phase(id, SCSI_PHASE_STATUS); + dev->sector_pos = dev->sector_len = 0; + scsi_disk_seek(dev, 0); + scsi_disk_set_phase(dev, SCSI_PHASE_STATUS); break; case GPCMD_REQUEST_SENSE: @@ -670,8 +654,8 @@ scsi_hd_command(uint8_t id, uint8_t *cdb) len = (cdb[1] & 1) ? 8 : 18; - scsi_hd_set_phase(id, SCSI_PHASE_DATA_IN); - scsi_hd_data_command_finish(id, len, len, cdb[4], 0); + scsi_disk_set_phase(dev, SCSI_PHASE_DATA_IN); + scsi_disk_data_command_finish(dev, len, len, cdb[4], 0); break; case GPCMD_MECHANISM_STATUS: @@ -680,8 +664,8 @@ scsi_hd_command(uint8_t id, uint8_t *cdb) if ((*BufLen == -1) || (len < *BufLen)) *BufLen = len; - scsi_hd_set_phase(id, SCSI_PHASE_DATA_IN); - scsi_hd_data_command_finish(id, 8, 8, len, 0); + scsi_disk_set_phase(dev, SCSI_PHASE_DATA_IN); + scsi_disk_data_command_finish(dev, 8, 8, len, 0); break; case GPCMD_READ_6: @@ -689,55 +673,54 @@ scsi_hd_command(uint8_t id, uint8_t *cdb) case GPCMD_READ_12: switch(cdb[0]) { case GPCMD_READ_6: - shdc[id].sector_len = cdb[4]; - shdc[id].sector_pos = ((((uint32_t) cdb[1]) & 0x1f) << 16) | (((uint32_t) cdb[2]) << 8) | ((uint32_t) cdb[3]); + dev->sector_len = cdb[4]; + dev->sector_pos = ((((uint32_t) cdb[1]) & 0x1f) << 16) | (((uint32_t) cdb[2]) << 8) | ((uint32_t) cdb[3]); break; case GPCMD_READ_10: - shdc[id].sector_len = (cdb[7] << 8) | cdb[8]; - shdc[id].sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; + dev->sector_len = (cdb[7] << 8) | cdb[8]; + dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; break; case GPCMD_READ_12: - shdc[id].sector_len = (((uint32_t) cdb[6]) << 24) | (((uint32_t) cdb[7]) << 16) | (((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]); - shdc[id].sector_pos = (((uint32_t) cdb[2]) << 24) | (((uint32_t) cdb[3]) << 16) | (((uint32_t) cdb[4]) << 8) | ((uint32_t) cdb[5]); + dev->sector_len = (((uint32_t) cdb[6]) << 24) | (((uint32_t) cdb[7]) << 16) | (((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]); + dev->sector_pos = (((uint32_t) cdb[2]) << 24) | (((uint32_t) cdb[3]) << 16) | (((uint32_t) cdb[4]) << 8) | ((uint32_t) cdb[5]); break; } - if ((shdc[id].sector_pos > last_sector) || - ((shdc[id].sector_pos + shdc[id].sector_len - 1) > last_sector)) { - scsi_hd_lba_out_of_range(id); + if ((dev->sector_pos > last_sector) || ((dev->sector_pos + dev->sector_len - 1) > last_sector)) { + scsi_disk_lba_out_of_range(dev); return; } - if ((!shdc[id].sector_len) || (*BufLen == 0)) { - scsi_hd_set_phase(id, SCSI_PHASE_STATUS); - scsi_hd_log("SCSI HD %i: All done - callback set\n", id); - shdc[id].packet_status = CDROM_PHASE_COMPLETE; - shdc[id].callback = 20 * SCSI_TIME; + if ((!dev->sector_len) || (*BufLen == 0)) { + scsi_disk_set_phase(dev, SCSI_PHASE_STATUS); + scsi_disk_log("SCSI HD %i: All done - callback set\n", dev); + dev->packet_status = CDROM_PHASE_COMPLETE; + dev->callback = 20 * SCSI_TIME; break; } - max_len = shdc[id].sector_len; - shdc[id].requested_blocks = max_len; + max_len = dev->sector_len; + dev->requested_blocks = max_len; - alloc_length = shdc[id].packet_len = max_len << 9; + alloc_length = dev->packet_len = max_len << 9; if ((*BufLen == -1) || (alloc_length < *BufLen)) *BufLen = alloc_length; - scsi_hd_set_phase(id, SCSI_PHASE_DATA_IN); + scsi_disk_set_phase(dev, SCSI_PHASE_DATA_IN); - if (shdc[id].requested_blocks > 1) - scsi_hd_data_command_finish(id, alloc_length, alloc_length / shdc[id].requested_blocks, alloc_length, 0); + if (dev->requested_blocks > 1) + scsi_disk_data_command_finish(dev, alloc_length, alloc_length / dev->requested_blocks, alloc_length, 0); else - scsi_hd_data_command_finish(id, alloc_length, alloc_length, alloc_length, 0); + scsi_disk_data_command_finish(dev, alloc_length, alloc_length, alloc_length, 0); return; case GPCMD_VERIFY_6: case GPCMD_VERIFY_10: case GPCMD_VERIFY_12: if (!(cdb[1] & 2)) { - scsi_hd_set_phase(id, SCSI_PHASE_STATUS); - scsi_hd_command_complete(id); + scsi_disk_set_phase(dev, SCSI_PHASE_STATUS); + scsi_disk_command_complete(dev); break; } case GPCMD_WRITE_6: @@ -749,98 +732,98 @@ scsi_hd_command(uint8_t id, uint8_t *cdb) { case GPCMD_VERIFY_6: case GPCMD_WRITE_6: - shdc[id].sector_len = cdb[4]; - shdc[id].sector_pos = ((((uint32_t) cdb[1]) & 0x1f) << 16) | (((uint32_t) cdb[2]) << 8) | ((uint32_t) cdb[3]); - scsi_hd_log("SCSI HD %i: Length: %i, LBA: %i\n", id, shdc[id].sector_len, shdc[id].sector_pos); + dev->sector_len = cdb[4]; + dev->sector_pos = ((((uint32_t) cdb[1]) & 0x1f) << 16) | (((uint32_t) cdb[2]) << 8) | ((uint32_t) cdb[3]); + scsi_disk_log("SCSI HD %i: Length: %i, LBA: %i\n", dev->id, dev->sector_len, dev->sector_pos); break; case GPCMD_VERIFY_10: case GPCMD_WRITE_10: case GPCMD_WRITE_AND_VERIFY_10: - shdc[id].sector_len = (cdb[7] << 8) | cdb[8]; - shdc[id].sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - scsi_hd_log("SCSI HD %i: Length: %i, LBA: %i\n", id, shdc[id].sector_len, shdc[id].sector_pos); + dev->sector_len = (cdb[7] << 8) | cdb[8]; + dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; + scsi_disk_log("SCSI HD %i: Length: %i, LBA: %i\n", dev->id, dev->sector_len, dev->sector_pos); break; case GPCMD_VERIFY_12: case GPCMD_WRITE_12: case GPCMD_WRITE_AND_VERIFY_12: - shdc[id].sector_len = (((uint32_t) cdb[6]) << 24) | (((uint32_t) cdb[7]) << 16) | (((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]); - shdc[id].sector_pos = (((uint32_t) cdb[2]) << 24) | (((uint32_t) cdb[3]) << 16) | (((uint32_t) cdb[4]) << 8) | ((uint32_t) cdb[5]); + dev->sector_len = (((uint32_t) cdb[6]) << 24) | (((uint32_t) cdb[7]) << 16) | (((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]); + dev->sector_pos = (((uint32_t) cdb[2]) << 24) | (((uint32_t) cdb[3]) << 16) | (((uint32_t) cdb[4]) << 8) | ((uint32_t) cdb[5]); break; } - if ((shdc[id].sector_pos > last_sector) || - ((shdc[id].sector_pos + shdc[id].sector_len - 1) > last_sector)) { - scsi_hd_lba_out_of_range(id); + if ((dev->sector_pos > last_sector) || + ((dev->sector_pos + dev->sector_len - 1) > last_sector)) { + scsi_disk_lba_out_of_range(dev); return; } - if ((!shdc[id].sector_len) || (*BufLen == 0)) { - scsi_hd_set_phase(id, SCSI_PHASE_STATUS); - scsi_hd_log("SCSI HD %i: All done - callback set\n", id); - shdc[id].packet_status = CDROM_PHASE_COMPLETE; - shdc[id].callback = 20 * SCSI_TIME; + if ((!dev->sector_len) || (*BufLen == 0)) { + scsi_disk_set_phase(dev, SCSI_PHASE_STATUS); + scsi_disk_log("SCSI HD %i: All done - callback set\n", dev->id); + dev->packet_status = CDROM_PHASE_COMPLETE; + dev->callback = 20 * SCSI_TIME; break; } - max_len = shdc[id].sector_len; - shdc[id].requested_blocks = max_len; + max_len = dev->sector_len; + dev->requested_blocks = max_len; - alloc_length = shdc[id].packet_len = max_len << 9; + alloc_length = dev->packet_len = max_len << 9; if ((*BufLen == -1) || (alloc_length < *BufLen)) *BufLen = alloc_length; - scsi_hd_set_phase(id, SCSI_PHASE_DATA_OUT); + scsi_disk_set_phase(dev, SCSI_PHASE_DATA_OUT); - if (shdc[id].requested_blocks > 1) - scsi_hd_data_command_finish(id, alloc_length, alloc_length / shdc[id].requested_blocks, alloc_length, 1); + if (dev->requested_blocks > 1) + scsi_disk_data_command_finish(dev, alloc_length, alloc_length / dev->requested_blocks, alloc_length, 1); else - scsi_hd_data_command_finish(id, alloc_length, alloc_length, alloc_length, 1); + scsi_disk_data_command_finish(dev, alloc_length, alloc_length, alloc_length, 1); return; case GPCMD_WRITE_SAME_10: if ((cdb[1] & 6) == 6) { - scsi_hd_invalid_field(id); + scsi_disk_invalid_field(dev); return; } - shdc[id].sector_len = (cdb[7] << 8) | cdb[8]; - shdc[id].sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - scsi_hd_log("SCSI HD %i: Length: %i, LBA: %i\n", id, shdc[id].sector_len, shdc[id].sector_pos); + dev->sector_len = (cdb[7] << 8) | cdb[8]; + dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; + scsi_disk_log("SCSI HD %i: Length: %i, LBA: %i\n", dev->id, dev->sector_len, dev->sector_pos); - if ((shdc[id].sector_pos > last_sector) || - ((shdc[id].sector_pos + shdc[id].sector_len - 1) > last_sector)) { - scsi_hd_lba_out_of_range(id); + if ((dev->sector_pos > last_sector) || + ((dev->sector_pos + dev->sector_len - 1) > last_sector)) { + scsi_disk_lba_out_of_range(dev); return; } - if ((!shdc[id].sector_len) || (*BufLen == 0)) { - scsi_hd_set_phase(id, SCSI_PHASE_STATUS); - scsi_hd_log("SCSI HD %i: All done - callback set\n", id); - shdc[id].packet_status = CDROM_PHASE_COMPLETE; - shdc[id].callback = 20 * SCSI_TIME; + if ((!dev->sector_len) || (*BufLen == 0)) { + scsi_disk_set_phase(dev, SCSI_PHASE_STATUS); + scsi_disk_log("SCSI HD %i: All done - callback set\n", dev->id); + dev->packet_status = CDROM_PHASE_COMPLETE; + dev->callback = 20 * SCSI_TIME; break; } max_len = 1; - shdc[id].requested_blocks = max_len; + dev->requested_blocks = max_len; - alloc_length = shdc[id].packet_len = max_len << 9; + alloc_length = dev->packet_len = max_len << 9; if ((*BufLen == -1) || (alloc_length < *BufLen)) *BufLen = alloc_length; - scsi_hd_set_phase(id, SCSI_PHASE_DATA_OUT); + scsi_disk_set_phase(dev, SCSI_PHASE_DATA_OUT); - if (shdc[id].requested_blocks > 1) - scsi_hd_data_command_finish(id, alloc_length, alloc_length / shdc[id].requested_blocks, alloc_length, 1); + if (dev->requested_blocks > 1) + scsi_disk_data_command_finish(dev, alloc_length, alloc_length / dev->requested_blocks, alloc_length, 1); else - scsi_hd_data_command_finish(id, alloc_length, alloc_length, alloc_length, 1); + scsi_disk_data_command_finish(dev, alloc_length, alloc_length, alloc_length, 1); return; case GPCMD_MODE_SENSE_6: case GPCMD_MODE_SENSE_10: - scsi_hd_set_phase(id, SCSI_PHASE_DATA_IN); + scsi_disk_set_phase(dev, SCSI_PHASE_DATA_IN); block_desc = ((cdb[1] >> 3) & 1) ? 0 : 1; @@ -849,31 +832,31 @@ scsi_hd_command(uint8_t id, uint8_t *cdb) else len = (cdb[8] | (cdb[7] << 8)); - shdc[id].current_page_code = cdb[2] & 0x3F; + dev->current_page_code = cdb[2] & 0x3F; alloc_length = len; - shdc[id].temp_buffer = (uint8_t *) malloc(65536); - memset(shdc[id].temp_buffer, 0, 65536); + dev->temp_buffer = (uint8_t *) malloc(65536); + memset(dev->temp_buffer, 0, 65536); if (cdb[0] == GPCMD_MODE_SENSE_6) { - len = scsi_hd_mode_sense(id, shdc[id].temp_buffer, 4, cdb[2], block_desc); + len = scsi_disk_mode_sense(dev, dev->temp_buffer, 4, cdb[2], block_desc); if (len > alloc_length) len = alloc_length; - shdc[id].temp_buffer[0] = len - 1; - shdc[id].temp_buffer[1] = 0; + dev->temp_buffer[0] = len - 1; + dev->temp_buffer[1] = 0; if (block_desc) - shdc[id].temp_buffer[3] = 8; + dev->temp_buffer[3] = 8; } else { - len = scsi_hd_mode_sense(id, shdc[id].temp_buffer, 8, cdb[2], block_desc); + len = scsi_disk_mode_sense(dev, dev->temp_buffer, 8, cdb[2], block_desc); if (len > alloc_length) len = alloc_length; - shdc[id].temp_buffer[0]=(len - 2) >> 8; - shdc[id].temp_buffer[1]=(len - 2) & 255; - shdc[id].temp_buffer[2] = 0; + dev->temp_buffer[0]=(len - 2) >> 8; + dev->temp_buffer[1]=(len - 2) & 255; + dev->temp_buffer[2] = 0; if (block_desc) { - shdc[id].temp_buffer[6] = 0; - shdc[id].temp_buffer[7] = 8; + dev->temp_buffer[6] = 0; + dev->temp_buffer[7] = 8; } } @@ -885,14 +868,14 @@ scsi_hd_command(uint8_t id, uint8_t *cdb) if ((*BufLen == -1) || (alloc_length < *BufLen)) *BufLen = alloc_length; - scsi_hd_log("SCSI HDD %i: Reading mode page: %02X...\n", id, cdb[2]); + scsi_disk_log("SCSI HDD %i: Reading mode page: %02X...\n", dev->id, cdb[2]); - scsi_hd_data_command_finish(id, len, len, alloc_length, 0); + scsi_disk_data_command_finish(dev, len, len, alloc_length, 0); return; case GPCMD_MODE_SELECT_6: case GPCMD_MODE_SELECT_10: - scsi_hd_set_phase(id, SCSI_PHASE_DATA_OUT); + scsi_disk_set_phase(dev, SCSI_PHASE_DATA_OUT); if (cdb[0] == GPCMD_MODE_SELECT_6) len = cdb[4]; @@ -902,10 +885,10 @@ scsi_hd_command(uint8_t id, uint8_t *cdb) if ((*BufLen == -1) || (len < *BufLen)) *BufLen = len; - shdc[id].total_length = len; - shdc[id].do_page_save = cdb[1] & 1; + dev->total_length = len; + dev->do_page_save = cdb[1] & 1; - scsi_hd_data_command_finish(id, len, len, len, 1); + scsi_disk_data_command_finish(dev, len, len, len, 1); return; case GPCMD_INQUIRY: @@ -914,94 +897,94 @@ scsi_hd_command(uint8_t id, uint8_t *cdb) max_len |= cdb[4]; if ((!max_len) || (*BufLen == 0)) { - scsi_hd_set_phase(id, SCSI_PHASE_STATUS); - /* scsi_hd_log("SCSI HD %i: All done - callback set\n", id); */ - shdc[id].packet_status = CDROM_PHASE_COMPLETE; - shdc[id].callback = 20 * SCSI_TIME; + scsi_disk_set_phase(dev, SCSI_PHASE_STATUS); + /* scsi_disk_log("SCSI HD %i: All done - callback set\n", dev->id); */ + dev->packet_status = CDROM_PHASE_COMPLETE; + dev->callback = 20 * SCSI_TIME; break; } - shdc[id].temp_buffer = malloc(1024); + dev->temp_buffer = malloc(1024); if (cdb[1] & 1) { preamble_len = 4; size_idx = 3; - shdc[id].temp_buffer[idx++] = 05; - shdc[id].temp_buffer[idx++] = cdb[2]; - shdc[id].temp_buffer[idx++] = 0; + dev->temp_buffer[idx++] = 05; + dev->temp_buffer[idx++] = cdb[2]; + dev->temp_buffer[idx++] = 0; idx++; switch (cdb[2]) { case 0x00: - shdc[id].temp_buffer[idx++] = 0x00; - shdc[id].temp_buffer[idx++] = 0x83; + dev->temp_buffer[idx++] = 0x00; + dev->temp_buffer[idx++] = 0x83; break; case 0x83: if (idx + 24 > max_len) { - free(shdc[id].temp_buffer); - shdc[id].temp_buffer = NULL; - scsi_hd_data_phase_error(id); + free(dev->temp_buffer); + dev->temp_buffer = NULL; + scsi_disk_data_phase_error(dev); return; } - shdc[id].temp_buffer[idx++] = 0x02; - shdc[id].temp_buffer[idx++] = 0x00; - shdc[id].temp_buffer[idx++] = 0x00; - shdc[id].temp_buffer[idx++] = 20; - ide_padstr8(shdc[id].temp_buffer + idx, 20, "53R141"); /* Serial */ + dev->temp_buffer[idx++] = 0x02; + dev->temp_buffer[idx++] = 0x00; + dev->temp_buffer[idx++] = 0x00; + dev->temp_buffer[idx++] = 20; + ide_padstr8(dev->temp_buffer + idx, 20, "53R141"); /* Serial */ idx += 20; if (idx + 72 > cdb[4]) goto atapi_out; - shdc[id].temp_buffer[idx++] = 0x02; - shdc[id].temp_buffer[idx++] = 0x01; - shdc[id].temp_buffer[idx++] = 0x00; - shdc[id].temp_buffer[idx++] = 68; - ide_padstr8(shdc[id].temp_buffer + idx, 8, EMU_NAME); /* Vendor */ + dev->temp_buffer[idx++] = 0x02; + dev->temp_buffer[idx++] = 0x01; + dev->temp_buffer[idx++] = 0x00; + dev->temp_buffer[idx++] = 68; + ide_padstr8(dev->temp_buffer + idx, 8, EMU_NAME); /* Vendor */ idx += 8; - ide_padstr8(shdc[id].temp_buffer + idx, 40, device_identify_ex); /* Product */ + ide_padstr8(dev->temp_buffer + idx, 40, device_identify_ex); /* Product */ idx += 40; - ide_padstr8(shdc[id].temp_buffer + idx, 20, "53R141"); /* Product */ + ide_padstr8(dev->temp_buffer + idx, 20, "53R141"); /* Product */ idx += 20; break; default: - scsi_hd_log("INQUIRY: Invalid page: %02X\n", cdb[2]); - free(shdc[id].temp_buffer); - shdc[id].temp_buffer = NULL; - scsi_hd_invalid_field(id); + scsi_disk_log("INQUIRY: Invalid page: %02X\n", cdb[2]); + free(dev->temp_buffer); + dev->temp_buffer = NULL; + scsi_disk_invalid_field(dev); return; } } else { preamble_len = 5; size_idx = 4; - memset(shdc[id].temp_buffer, 0, 8); - shdc[id].temp_buffer[0] = 0; /*SCSI HD*/ - shdc[id].temp_buffer[1] = 0; /*Fixed*/ - shdc[id].temp_buffer[2] = 0x02; /*SCSI-2 compliant*/ - shdc[id].temp_buffer[3] = 0x02; - shdc[id].temp_buffer[4] = 31; - shdc[id].temp_buffer[6] = 1; /* 16-bit transfers supported */ - shdc[id].temp_buffer[7] = 0x20; /* Wide bus supported */ + memset(dev->temp_buffer, 0, 8); + dev->temp_buffer[0] = 0; /*SCSI HD*/ + dev->temp_buffer[1] = 0; /*Fixed*/ + dev->temp_buffer[2] = 0x02; /*SCSI-2 compliant*/ + dev->temp_buffer[3] = 0x02; + dev->temp_buffer[4] = 31; + dev->temp_buffer[6] = 1; /* 16-bit transfers supported */ + dev->temp_buffer[7] = 0x20; /* Wide bus supported */ - ide_padstr8(shdc[id].temp_buffer + 8, 8, EMU_NAME); /* Vendor */ - ide_padstr8(shdc[id].temp_buffer + 16, 16, device_identify); /* Product */ - ide_padstr8(shdc[id].temp_buffer + 32, 4, EMU_VERSION); /* Revision */ + ide_padstr8(dev->temp_buffer + 8, 8, EMU_NAME); /* Vendor */ + ide_padstr8(dev->temp_buffer + 16, 16, device_identify); /* Product */ + ide_padstr8(dev->temp_buffer + 32, 4, EMU_VERSION); /* Revision */ idx = 36; if (max_len == 96) { - shdc[id].temp_buffer[4] = 91; + dev->temp_buffer[4] = 91; idx = 96; } } atapi_out: - shdc[id].temp_buffer[size_idx] = idx - preamble_len; + dev->temp_buffer[size_idx] = idx - preamble_len; len=idx; - scsi_hd_log("scsi_hd_command(): Inquiry (%08X, %08X)\n", hdbufferb, shdc[id].temp_buffer); + scsi_disk_log("scsi_disk_command(): Inquiry (%08X, %08X)\n", hdbufferb, dev->temp_buffer); if (len > max_len) len = max_len; @@ -1012,13 +995,13 @@ atapi_out: if (len > *BufLen) len = *BufLen; - scsi_hd_set_phase(id, SCSI_PHASE_DATA_IN); - scsi_hd_data_command_finish(id, len, len, max_len, 0); + scsi_disk_set_phase(dev, SCSI_PHASE_DATA_IN); + scsi_disk_data_command_finish(dev, len, len, max_len, 0); break; case GPCMD_PREVENT_REMOVAL: - scsi_hd_set_phase(id, SCSI_PHASE_STATUS); - scsi_hd_command_complete(id); + scsi_disk_set_phase(dev, SCSI_PHASE_STATUS); + scsi_disk_command_complete(dev); break; case GPCMD_SEEK_6: @@ -1031,108 +1014,108 @@ atapi_out: pos = (cdb[2] << 24) | (cdb[3]<<16) | (cdb[4]<<8) | cdb[5]; break; } - scsi_hd_seek(id, pos); + scsi_disk_seek(dev, pos); - scsi_hd_set_phase(id, SCSI_PHASE_STATUS); - scsi_hd_command_complete(id); + scsi_disk_set_phase(dev, SCSI_PHASE_STATUS); + scsi_disk_command_complete(dev); break; case GPCMD_READ_CDROM_CAPACITY: - shdc[id].temp_buffer = (uint8_t *) malloc(8); + dev->temp_buffer = (uint8_t *) malloc(8); - if (scsi_hd_read_capacity(id, shdc[id].current_cdb, shdc[id].temp_buffer, &len) == 0) { - scsi_hd_set_phase(id, SCSI_PHASE_STATUS); + if (scsi_disk_read_capacity(dev, dev->current_cdb, dev->temp_buffer, &len) == 0) { + scsi_disk_set_phase(dev, SCSI_PHASE_STATUS); return; } if ((*BufLen == -1) || (len < *BufLen)) *BufLen = len; - scsi_hd_set_phase(id, SCSI_PHASE_DATA_IN); - scsi_hd_data_command_finish(id, len, len, len, 0); + scsi_disk_set_phase(dev, SCSI_PHASE_DATA_IN); + scsi_disk_data_command_finish(dev, len, len, len, 0); break; default: - scsi_hd_illegal_opcode(id); + scsi_disk_illegal_opcode(dev); break; } - /* scsi_hd_log("SCSI HD %i: Phase: %02X, request length: %i\n", shdc[id].phase, shdc[id].request_length); */ + /* scsi_disk_log("SCSI HD %i: Phase: %02X, request length: %i\n", dev->id, dev->phase, dev->request_length); */ } static void -scsi_hd_phase_data_in(uint8_t id) +scsi_disk_phase_data_in(scsi_disk_t *dev) { - uint8_t *hdbufferb = SCSIDevices[hdd[id].scsi_id][hdd[id].scsi_lun].CmdBuffer; - int32_t *BufLen = &SCSIDevices[hdd[id].scsi_id][hdd[id].scsi_lun].BufferLength; + uint8_t *hdbufferb = SCSIDevices[dev->drv->scsi_id].CmdBuffer; + int32_t *BufLen = &SCSIDevices[dev->drv->scsi_id].BufferLength; if (!*BufLen) { - scsi_hd_log("scsi_hd_phase_data_in(): Buffer length is 0\n"); - scsi_hd_set_phase(id, SCSI_PHASE_STATUS); + scsi_disk_log("scsi_disk_phase_data_in(): Buffer length is 0\n"); + scsi_disk_set_phase(dev, SCSI_PHASE_STATUS); return; } - switch (shdc[id].current_cdb[0]) { + switch (dev->current_cdb[0]) { case GPCMD_REQUEST_SENSE: - scsi_hd_log("SCSI HDD %i: %08X, %08X\n", id, hdbufferb, *BufLen); - scsi_hd_request_sense(id, hdbufferb, *BufLen, shdc[id].current_cdb[1] & 1); + scsi_disk_log("SCSI HDD %i: %08X, %08X\n", dev->id, hdbufferb, *BufLen); + scsi_disk_request_sense(dev, hdbufferb, *BufLen, dev->current_cdb[1] & 1); break; case GPCMD_MECHANISM_STATUS: - memset(hdbufferb, 0, *BufLen); + memset(hdbufferb, 0, *BufLen); hdbufferb[5] = 1; break; case GPCMD_READ_6: case GPCMD_READ_10: case GPCMD_READ_12: - if ((shdc[id].requested_blocks > 0) && (*BufLen > 0)) { - if (shdc[id].packet_len > *BufLen) - hdd_image_read(id, shdc[id].sector_pos, *BufLen >> 9, hdbufferb); + if ((dev->requested_blocks > 0) && (*BufLen > 0)) { + if (dev->packet_len > *BufLen) + hdd_image_read(dev->id, dev->sector_pos, *BufLen >> 9, hdbufferb); else - hdd_image_read(id, shdc[id].sector_pos, shdc[id].requested_blocks, hdbufferb); + hdd_image_read(dev->id, dev->sector_pos, dev->requested_blocks, hdbufferb); } break; case GPCMD_MODE_SENSE_6: case GPCMD_MODE_SENSE_10: case GPCMD_INQUIRY: case GPCMD_READ_CDROM_CAPACITY: - scsi_hd_log("scsi_hd_phase_data_in(): Filling buffer (%08X, %08X)\n", hdbufferb, shdc[id].temp_buffer); - memcpy(hdbufferb, shdc[id].temp_buffer, *BufLen); - free(shdc[id].temp_buffer); - shdc[id].temp_buffer = NULL; - scsi_hd_log("%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", + scsi_disk_log("scsi_disk_phase_data_in(): Filling buffer (%08X, %08X)\n", hdbufferb, dev->temp_buffer); + memcpy(hdbufferb, dev->temp_buffer, *BufLen); + free(dev->temp_buffer); + dev->temp_buffer = NULL; + scsi_disk_log("%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", hdbufferb[0], hdbufferb[1], hdbufferb[2], hdbufferb[3], hdbufferb[4], hdbufferb[5], hdbufferb[6], hdbufferb[7], hdbufferb[8], hdbufferb[9], hdbufferb[10], hdbufferb[11], hdbufferb[12], hdbufferb[13], hdbufferb[14], hdbufferb[15]); break; default: - fatal("SCSI HDD %i: Bad Command for phase 2 (%02X)\n", shdc[id].current_cdb[0]); + fatal("SCSI HDD %i: Bad Command for phase 2 (%02X)\n", dev->id, dev->current_cdb[0]); break; } - scsi_hd_set_phase(id, SCSI_PHASE_STATUS); + scsi_disk_set_phase(dev, SCSI_PHASE_STATUS); } static void -scsi_hd_phase_data_out(uint8_t id) +scsi_disk_phase_data_out(scsi_disk_t *dev) { - uint8_t *hdbufferb = SCSIDevices[hdd[id].scsi_id][hdd[id].scsi_lun].CmdBuffer; + uint8_t *hdbufferb = SCSIDevices[dev->drv->scsi_id].CmdBuffer; int i; - int32_t *BufLen = &SCSIDevices[hdd[id].scsi_id][hdd[id].scsi_lun].BufferLength; - uint32_t last_sector = hdd_image_get_last_sector(id); + int32_t *BufLen = &SCSIDevices[dev->drv->scsi_id].BufferLength; + uint32_t last_sector = hdd_image_get_last_sector(dev->id); uint32_t c, h, s, last_to_write = 0; uint16_t block_desc_len, pos; uint8_t hdr_len, val, old_val, ch, error = 0; uint8_t page, page_len; if (!*BufLen) { - scsi_hd_set_phase(id, SCSI_PHASE_STATUS); + scsi_disk_set_phase(dev, SCSI_PHASE_STATUS); return; } - switch (shdc[id].current_cdb[0]) { + switch (dev->current_cdb[0]) { case GPCMD_VERIFY_6: case GPCMD_VERIFY_10: case GPCMD_VERIFY_12: @@ -1142,29 +1125,29 @@ scsi_hd_phase_data_out(uint8_t id) case GPCMD_WRITE_AND_VERIFY_10: case GPCMD_WRITE_12: case GPCMD_WRITE_AND_VERIFY_12: - if ((shdc[id].requested_blocks > 0) && (*BufLen > 0)) { - if (shdc[id].packet_len > *BufLen) - hdd_image_write(id, shdc[id].sector_pos, *BufLen >> 9, hdbufferb); + if ((dev->requested_blocks > 0) && (*BufLen > 0)) { + if (dev->packet_len > *BufLen) + hdd_image_write(dev->id, dev->sector_pos, *BufLen >> 9, hdbufferb); else - hdd_image_write(id, shdc[id].sector_pos, shdc[id].requested_blocks, hdbufferb); + hdd_image_write(dev->id, dev->sector_pos, dev->requested_blocks, hdbufferb); } break; case GPCMD_WRITE_SAME_10: - if (!shdc[id].current_cdb[7] && !shdc[id].current_cdb[8]) + if (!dev->current_cdb[7] && !dev->current_cdb[8]) last_to_write = last_sector; else - last_to_write = shdc[id].sector_pos + shdc[id].sector_len - 1; + last_to_write = dev->sector_pos + dev->sector_len - 1; - for (i = shdc[id].sector_pos; i <= last_to_write; i++) { - if (shdc[id].current_cdb[1] & 2) { + for (i = dev->sector_pos; i <= last_to_write; i++) { + if (dev->current_cdb[1] & 2) { hdbufferb[0] = (i >> 24) & 0xff; hdbufferb[1] = (i >> 16) & 0xff; hdbufferb[2] = (i >> 8) & 0xff; hdbufferb[3] = i & 0xff; - } else if (shdc[id].current_cdb[1] & 4) { - s = (i % hdd[id].spt); - h = ((i - s) / hdd[id].spt) % hdd[id].hpc; - c = ((i - s) / hdd[id].spt) / hdd[id].hpc; + } else if (dev->current_cdb[1] & 4) { + s = (i % dev->drv->spt); + h = ((i - s) / dev->drv->spt) % dev->drv->hpc; + c = ((i - s) / dev->drv->spt) / dev->drv->hpc; hdbufferb[0] = (c >> 16) & 0xff; hdbufferb[1] = (c >> 8) & 0xff; hdbufferb[2] = c & 0xff; @@ -1174,17 +1157,17 @@ scsi_hd_phase_data_out(uint8_t id) hdbufferb[6] = (s >> 8) & 0xff; hdbufferb[7] = s & 0xff; } - hdd_image_write(id, i, 1, hdbufferb); + hdd_image_write(dev->id, i, 1, hdbufferb); } break; case GPCMD_MODE_SELECT_6: case GPCMD_MODE_SELECT_10: - if (shdc[id].current_cdb[0] == GPCMD_MODE_SELECT_10) + if (dev->current_cdb[0] == GPCMD_MODE_SELECT_10) hdr_len = 8; else hdr_len = 4; - if (shdc[id].current_cdb[0] == GPCMD_MODE_SELECT_6) { + if (dev->current_cdb[0] == GPCMD_MODE_SELECT_6) { block_desc_len = hdbufferb[2]; block_desc_len <<= 8; block_desc_len |= hdbufferb[3]; @@ -1202,16 +1185,16 @@ scsi_hd_phase_data_out(uint8_t id) pos += 2; - if (!(scsi_hd_mode_sense_page_flags & (1LL << ((uint64_t) page)))) + if (!(scsi_disk_mode_sense_page_flags & (1LL << ((uint64_t) page)))) error |= 1; else { for (i = 0; i < page_len; i++) { - ch = scsi_hd_mode_sense_pages_changeable.pages[page][i + 2]; + ch = scsi_disk_mode_sense_pages_changeable.pages[page][i + 2]; val = hdbufferb[pos + i]; - old_val = scsi_hd_mode_sense_pages_saved[id].pages[page][i + 2]; + old_val = dev->ms_pages_saved.pages[page][i + 2]; if (val != old_val) { if (ch) - scsi_hd_mode_sense_pages_saved[id].pages[page][i + 2] = val; + dev->ms_pages_saved.pages[page][i + 2] = val; else error |= 1; } @@ -1220,70 +1203,111 @@ scsi_hd_phase_data_out(uint8_t id) pos += page_len; - val = scsi_hd_mode_sense_pages_default.pages[page][0] & 0x80; - if (shdc[id].do_page_save && val) - scsi_hd_mode_sense_save(id); + val = scsi_disk_mode_sense_pages_default.pages[page][0] & 0x80; + if (dev->do_page_save && val) + scsi_disk_mode_sense_save(dev); - if (pos >= shdc[id].total_length) + if (pos >= dev->total_length) break; } if (error) - scsi_hd_invalid_field_pl(id); + scsi_disk_invalid_field_pl(dev); break; default: - fatal("SCSI HDD %i: Bad Command for phase 2 (%02X)\n", shdc[id].current_cdb[0]); + fatal("SCSI HDD %i: Bad Command for phase 2 (%02X)\n", dev->id, dev->current_cdb[0]); break; } - scsi_hd_set_phase(id, SCSI_PHASE_STATUS); + scsi_disk_set_phase(dev, SCSI_PHASE_STATUS); } /* If the result is 1, issue an IRQ, otherwise not. */ void -scsi_hd_callback(uint8_t id) +scsi_disk_callback(scsi_disk_t *dev) { - switch(shdc[id].packet_status) { + switch(dev->packet_status) { case CDROM_PHASE_IDLE: - scsi_hd_log("SCSI HD %i: PHASE_IDLE\n", id); - shdc[id].phase = 1; - shdc[id].status = READY_STAT | DRQ_STAT | (shdc[id].status & ERR_STAT); + scsi_disk_log("SCSI HD %i: PHASE_IDLE\n", dev->id); + dev->phase = 1; + dev->status = READY_STAT | DRQ_STAT | (dev->status & ERR_STAT); return; case CDROM_PHASE_COMPLETE: - scsi_hd_log("SCSI HD %i: PHASE_COMPLETE\n", id); - shdc[id].status = READY_STAT; - shdc[id].phase = 3; - shdc[id].packet_status = 0xFF; - return; - case CDROM_PHASE_DATA_OUT: - scsi_hd_log("SCSI HD %i: PHASE_DATA_OUT\n", id); - shdc[id].status = READY_STAT | DRQ_STAT | (shdc[id].status & ERR_STAT); - shdc[id].phase = 0; + scsi_disk_log("SCSI HD %i: PHASE_COMPLETE\n", dev->id); + dev->status = READY_STAT; + dev->phase = 3; + dev->packet_status = 0xFF; return; case CDROM_PHASE_DATA_OUT_DMA: - scsi_hd_log("SCSI HD %i: PHASE_DATA_OUT_DMA\n", id); - scsi_hd_phase_data_out(id); - shdc[id].packet_status = CDROM_PHASE_COMPLETE; - shdc[id].status = READY_STAT; - shdc[id].phase = 3; - return; - case CDROM_PHASE_DATA_IN: - scsi_hd_log("SCSI HD %i: PHASE_DATA_IN\n", id); - shdc[id].status = READY_STAT | DRQ_STAT | (shdc[id].status & ERR_STAT); - shdc[id].phase = 2; + scsi_disk_log("SCSI HD %i: PHASE_DATA_OUT_DMA\n", dev->id); + scsi_disk_phase_data_out(dev); + dev->packet_status = CDROM_PHASE_COMPLETE; + dev->status = READY_STAT; + dev->phase = 3; return; case CDROM_PHASE_DATA_IN_DMA: - scsi_hd_log("SCSI HD %i: PHASE_DATA_IN_DMA\n", id); - scsi_hd_phase_data_in(id); - shdc[id].packet_status = CDROM_PHASE_COMPLETE; - shdc[id].status = READY_STAT; - shdc[id].phase = 3; + scsi_disk_log("SCSI HD %i: PHASE_DATA_IN_DMA\n", dev->id); + scsi_disk_phase_data_in(dev); + dev->packet_status = CDROM_PHASE_COMPLETE; + dev->status = READY_STAT; + dev->phase = 3; return; case CDROM_PHASE_ERROR: - scsi_hd_log("SCSI HD %i: PHASE_ERROR\n", id); - shdc[id].status = READY_STAT | ERR_STAT; - shdc[id].phase = 3; + scsi_disk_log("SCSI HD %i: PHASE_ERROR\n", dev->id); + dev->status = READY_STAT | ERR_STAT; + dev->phase = 3; return; } } + + +/* Peform a master init on the entire module. */ +void +scsi_disk_global_init(void) +{ + /* Clear the global data. */ + memset(scsi_disk, 0x00, sizeof(scsi_disk)); +} + + +void +scsi_disk_hard_reset(void) +{ + int c; + + for (c = 0; c < HDD_NUM; c++) { + if (hdd[c].bus == HDD_BUS_SCSI) { + scsi_disk_log("SCSI disk hard_reset drive=%d\n", c); + + if (!scsi_disk[c]) { + scsi_disk[c] = (scsi_disk_t *) malloc(sizeof(scsi_disk_t)); + memset(scsi_disk[c], 0, sizeof(scsi_disk_t)); + } + + scsi_disk[c]->id = c; + scsi_disk[c]->drv = &hdd[c]; + + scsi_disk_mode_sense_load(scsi_disk[c]); + } + } +} + + +void +scsi_disk_close(void) +{ + scsi_disk_t *dev; + int c; + + for (c = 0; c < HDD_NUM; c++) { + dev = scsi_disk[c]; + + if (dev) { + hdd_image_close(c); + + free(scsi_disk[c]); + scsi_disk[c] = NULL; + } + } +} diff --git a/src/scsi/scsi_disk.h b/src/scsi/scsi_disk.h index f41906d46..36898f266 100644 --- a/src/scsi/scsi_disk.h +++ b/src/scsi/scsi_disk.h @@ -6,7 +6,7 @@ * * Emulation of SCSI fixed and removable disks. * - * Version: @(#)scsi_disk.h 1.0.4 2018/04/24 + * Version: @(#)scsi_disk.h 1.0.5 2018/06/02 * * Author: Miran Grca, * Copyright 2017,2018 Miran Grca. @@ -14,32 +14,47 @@ typedef struct { - /* Stuff for SCSI hard disks. */ - uint8_t status, phase, - error, - current_cdb[16], - sense[256]; + mode_sense_pages_t ms_pages_saved; - uint16_t request_length; + hard_disk_t *drv; - int requested_blocks, block_total, - packet_status, callback, - block_descriptor_len, - total_length, do_page_save; + /* Stuff for SCSI hard disks. */ + uint8_t status, phase, + error, id, + current_cdb[16], + sense[256]; - uint32_t sector_pos, sector_len, - packet_len; + uint16_t request_length; - uint64_t current_page_code; + int requested_blocks, block_total, + packet_status, callback, + block_descriptor_len, + total_length, do_page_save; - uint8_t *temp_buffer; -} scsi_hard_disk_t; + uint32_t sector_pos, sector_len, + packet_len; + + uint64_t current_page_code; + + uint8_t *temp_buffer; +} scsi_disk_t; -extern scsi_hard_disk_t shdc[HDD_NUM]; -extern FILE *shdf[HDD_NUM]; +extern scsi_disk_t *scsi_disk[HDD_NUM]; +extern uint8_t scsi_disks[16]; -extern void scsi_loadhd(int scsi_id, int scsi_lun, int id); +extern void scsi_loadhd(int scsi_id, int id); +extern void scsi_disk_global_init(void); +extern void scsi_disk_hard_reset(void); +extern void scsi_disk_close(void); -int scsi_hd_read_capacity(uint8_t id, uint8_t *cdb, uint8_t *buffer, uint32_t *len); +extern int scsi_disk_read_capacity(scsi_disk_t *dev, uint8_t *cdb, uint8_t *buffer, uint32_t *len); +extern int scsi_disk_err_stat_to_scsi(scsi_disk_t *dev); +extern int scsi_disk_phase_to_scsi(scsi_disk_t *dev); +extern int find_hdd_for_scsi_id(uint8_t scsi_id); +extern void build_scsi_disk_map(void); +extern void scsi_disk_reset(scsi_disk_t *dev); +extern void scsi_disk_request_sense_for_scsi(scsi_disk_t *dev, uint8_t *buffer, uint8_t alloc_length); +extern void scsi_disk_command(scsi_disk_t *dev, uint8_t *cdb); +extern void scsi_disk_callback(scsi_disk_t *dev); diff --git a/src/scsi/scsi_ncr5380.c b/src/scsi/scsi_ncr5380.c index 0a23c893e..e67407cd9 100644 --- a/src/scsi/scsi_ncr5380.c +++ b/src/scsi/scsi_ncr5380.c @@ -9,7 +9,7 @@ * Implementation of the NCR 5380 series of SCSI Host Adapters * made by NCR. These controllers were designed for the ISA bus. * - * Version: @(#)scsi_ncr5380.c 1.0.14 2018/04/26 + * Version: @(#)scsi_ncr5380.c 1.0.15 2018/06/13 * * Authors: Sarah Walker, * TheCollector1995, @@ -290,7 +290,7 @@ ncr_write(uint16_t port, uint8_t val, void *priv) default: #if 1 - pclog("NCR5380: bad write %04x %02x\n", port, val); + ncr_log("NCR5380: bad write %04x %02x\n", port, val); #endif break; } @@ -496,7 +496,7 @@ dma_callback(void *priv) default: #if 1 - pclog("DMA callback bad mode %i\n", scsi->ncr.dma_mode); + ncr_log("DMA callback bad mode %i\n", scsi->ncr.dma_mode); #endif break; } @@ -668,9 +668,12 @@ t130b_read(uint32_t addr, void *priv) uint8_t ret = 0xff; addr &= 0x3fff; - if (addr < 0x1800) + if ((addr < 0x1800) && scsi->rom_addr) ret = scsi->bios_rom.rom[addr & 0x1fff]; else + if ((addr < 0x1800) && !scsi->rom_addr) + ret = 0xff; + else if (addr < 0x1880) ret = scsi->ext_ram[addr & 0x7f]; @@ -849,47 +852,79 @@ ncr_init(const device_t *info) break; case 1: /* Ranco RT1000B */ - scsi->rom_addr = 0xDC000; - rom_init(&scsi->bios_rom, RT1000B_ROM, - scsi->rom_addr, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + scsi->base = device_get_config_hex16("base"); + scsi->rom_addr = device_get_config_hex20("bios_addr"); - mem_mapping_disable(&scsi->bios_rom.mapping); + if (scsi->rom_addr) { + rom_init(&scsi->bios_rom, RT1000B_ROM, + scsi->rom_addr, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + + mem_mapping_disable(&scsi->bios_rom.mapping); + } else { + scsi->bios_rom.rom = (uint8_t *) malloc(0x4000); + memset(scsi->bios_rom.rom, 0xff, 0x4000); + } mem_mapping_add(&scsi->mapping, scsi->rom_addr, 0x4000, memio_read, NULL, NULL, memio_write, NULL, NULL, scsi->bios_rom.rom, 0, scsi); + + if (scsi->base) { + io_sethandler(scsi->base, 16, + t130b_in,NULL,NULL, t130b_out,NULL,NULL, scsi); + } break; case 2: /* Trantor T130B */ - scsi->rom_addr = 0xDC000; - scsi->base = 0x0350; - rom_init(&scsi->bios_rom, T130B_ROM, - scsi->rom_addr, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + scsi->base = device_get_config_hex16("base"); + scsi->rom_addr = device_get_config_hex20("bios_addr"); + + if (scsi->rom_addr) { + rom_init(&scsi->bios_rom, T130B_ROM, + scsi->rom_addr, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + + mem_mapping_disable(&scsi->bios_rom.mapping); + } else { + scsi->bios_rom.rom = (uint8_t *) malloc(0x4000); + memset(scsi->bios_rom.rom, 0xff, 0x4000); + } mem_mapping_add(&scsi->mapping, scsi->rom_addr, 0x4000, t130b_read, NULL, NULL, t130b_write, NULL, NULL, scsi->bios_rom.rom, 0, scsi); - io_sethandler(scsi->base, 16, - t130b_in,NULL,NULL, t130b_out,NULL,NULL, scsi); + if (scsi->base) { + io_sethandler(scsi->base, 16, + t130b_in,NULL,NULL, t130b_out,NULL,NULL, scsi); + } break; case 3: /* Sumo SCSI-AT */ scsi->base = device_get_config_hex16("base"); scsi->irq = device_get_config_int("irq"); scsi->rom_addr = device_get_config_hex20("bios_addr"); - rom_init(&scsi->bios_rom, SCSIAT_ROM, - scsi->rom_addr, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + + if (scsi->rom_addr) { + rom_init(&scsi->bios_rom, SCSIAT_ROM, + scsi->rom_addr, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + + mem_mapping_disable(&scsi->bios_rom.mapping); + } else { + scsi->bios_rom.rom = (uint8_t *) malloc(0x4000); + memset(scsi->bios_rom.rom, 0xff, 0x4000); + } mem_mapping_add(&scsi->mapping, scsi->rom_addr, 0x4000, t130b_read, NULL, NULL, t130b_write, NULL, NULL, scsi->bios_rom.rom, 0, scsi); - io_sethandler(scsi->base, 16, - scsiat_in,NULL,NULL, scsiat_out,NULL,NULL, scsi); + if (scsi->base) { + io_sethandler(scsi->base, 16, + scsiat_in,NULL,NULL, scsiat_out,NULL,NULL, scsi); + } break; } @@ -898,7 +933,7 @@ ncr_init(const device_t *info) sprintf(&temp[strlen(temp)], " I/O=%04x", scsi->base); if (scsi->irq != 0) sprintf(&temp[strlen(temp)], " IRQ=%d", scsi->irq); - pclog("%s\n", temp); + ncr_log("%s\n", temp); ncr5380_reset(&scsi->ncr); @@ -948,6 +983,59 @@ scsiat_available(void) } +static const device_config_t ncr5380_config[] = { + { + "base", "Address", CONFIG_HEX16, "", 0x0350, + { + { + "None", 0 + }, + { + "240H", 0x0240 + }, + { + "250H", 0x0250 + }, + { + "340H", 0x0340 + }, + { + "350H", 0x0350 + }, + { + "" + } + }, + }, + { + "bios_addr", "BIOS Address", CONFIG_HEX20, "", 0xDC000, + { + { + "Disabled", 0 + }, + { + "C800H", 0xc8000 + }, + { + "CC00H", 0xcc000 + }, + { + "D800H", 0xd8000 + }, + { + "DC00H", 0xdc000 + }, + { + "" + } + }, + }, + { + "", "", -1 + } +}; + + static const device_config_t scsiat_config[] = { { "base", "Address", CONFIG_HEX16, "", 0x0310, @@ -1064,7 +1152,7 @@ const device_t scsi_rt1000b_device = ncr_init, ncr_close, NULL, rt1000b_available, NULL, NULL, - NULL + ncr5380_config }; const device_t scsi_t130b_device = @@ -1075,7 +1163,7 @@ const device_t scsi_t130b_device = ncr_init, ncr_close, NULL, t130b_available, NULL, NULL, - NULL + ncr5380_config }; const device_t scsi_scsiat_device = diff --git a/src/scsi/scsi_ncr53c810.c b/src/scsi/scsi_ncr53c810.c index 3ba77e144..459ca28fd 100644 --- a/src/scsi/scsi_ncr53c810.c +++ b/src/scsi/scsi_ncr53c810.c @@ -10,7 +10,7 @@ * NCR and later Symbios and LSI. This controller was designed * for the PCI bus. * - * Version: @(#)scsi_ncr53c810.c 1.0.13 2018/05/23 + * Version: @(#)scsi_ncr53c810.c 1.0.14 2018/05/28 * * Authors: Paul Brook (QEMU) * Artyom Tarasenko (QEMU) @@ -22,11 +22,12 @@ * Copyright 2017,2018 Miran Grca. */ #include +#include #include #include -#include #include -#include +#include +#define HAVE_STDARG_H #include #include "../86box.h" #include "../io.h" @@ -333,7 +334,7 @@ ncr53c810_irq_on_rsl(ncr53c810_t *dev) static void ncr53c810_soft_reset(ncr53c810_t *dev) { - int i, j; + int i; ncr53c810_log("LSI Reset\n"); dev->timer_period = dev->timer_enabled = 0; @@ -390,10 +391,8 @@ ncr53c810_soft_reset(ncr53c810_t *dev) dev->gpreg0 = 0; dev->sstop = 1; - for (i = 0; i < 16; i++) { - for (j = 0; j < 8; j++) - scsi_device_reset(i, j); - } + for (i = 0; i < 16; i++) + scsi_device_reset(i); } @@ -598,9 +597,9 @@ ncr53c810_do_dma(ncr53c810_t *dev, int out, uint8_t id) scsi_device_t *sd; - sd = &SCSIDevices[id][dev->current_lun]; + sd = &SCSIDevices[id]; - if ((!scsi_device_present(id, dev->current_lun))) { + if ((!scsi_device_present(id))) { ncr53c810_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: Device not present when attempting to do DMA\n", id, dev->current_lun, dev->last_command); return; } @@ -627,7 +626,7 @@ ncr53c810_do_dma(ncr53c810_t *dev, int out, uint8_t id) else { if (!dev->buffer_pos) { ncr53c810_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: SCSI Command Phase 1 on PHASE_DI\n", id, dev->current_lun, dev->last_command); - scsi_device_command_phase1(dev->current->tag, dev->current_lun); + scsi_device_command_phase1(dev->current->tag); } ncr53c810_write(dev, addr, sd->CmdBuffer+dev->buffer_pos, count); } @@ -638,7 +637,7 @@ ncr53c810_do_dma(ncr53c810_t *dev, int out, uint8_t id) if (dev->temp_buf_len <= 0) { if (out) { ncr53c810_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: SCSI Command Phase 1 on PHASE_DO\n", id, dev->current_lun, dev->last_command); - scsi_device_command_phase1(id, dev->current_lun); + scsi_device_command_phase1(id); } if (sd->CmdBuffer != NULL) { free(sd->CmdBuffer); @@ -684,8 +683,8 @@ ncr53c810_do_command(ncr53c810_t *dev, uint8_t id) dev->sfbr = buf[0]; dev->command_complete = 0; - sd = &SCSIDevices[id][dev->current_lun]; - if (!scsi_device_present(id, dev->current_lun)) { + sd = &SCSIDevices[id]; + if (!scsi_device_present(id)) { ncr53c810_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: Bad Selection\n", id, dev->current_lun, buf[0]); ncr53c810_bad_selection(dev, id); return 0; @@ -699,7 +698,7 @@ ncr53c810_do_command(ncr53c810_t *dev, uint8_t id) ncr53c810_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: DBC=%i\n", id, dev->current_lun, buf[0], dev->dbc); dev->last_command = buf[0]; - scsi_device_command_phase0(dev->current->tag, dev->current_lun, dev->dbc, buf); + scsi_device_command_phase0(dev->current->tag, buf); dev->hba_private = (void *)dev->current; dev->waiting = 0; @@ -715,7 +714,7 @@ ncr53c810_do_command(ncr53c810_t *dev, uint8_t id) if ((sd->Phase == SCSI_PHASE_DATA_IN) && (sd->BufferLength > 0)) { ncr53c810_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: PHASE_DI\n", id, dev->current_lun, buf[0]); ncr53c810_set_phase(dev, PHASE_DI); - p = scsi_device_get_callback(dev->current->tag, dev->current_lun); + p = scsi_device_get_callback(dev->current->tag); if (p <= 0LL) { period = ((double) sd->BufferLength) * 0.1 * ((double) TIMER_USEC); /* Fast SCSI: 10000000 bytes per second */ dev->timer_period += (int64_t) period; @@ -723,9 +722,9 @@ ncr53c810_do_command(ncr53c810_t *dev, uint8_t id) dev->timer_period += p; return 1; } else if ((sd->Phase == SCSI_PHASE_DATA_OUT) && (sd->BufferLength > 0)) { - ncr53c810_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: PHASE_DO\n", id, dev->current_lun, buf[0]); + ncr53c810_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: PHASE_DO\n", id, buf[0]); ncr53c810_set_phase(dev, PHASE_DO); - p = scsi_device_get_callback(dev->current->tag, dev->current_lun); + p = scsi_device_get_callback(dev->current->tag); if (p <= 0LL) { period = ((double) sd->BufferLength) * 0.1 * ((double) TIMER_USEC); /* Fast SCSI: 10000000 bytes per second */ dev->timer_period += (int64_t) period; @@ -833,7 +832,7 @@ ncr53c810_do_msgout(ncr53c810_t *dev, uint8_t id) uint32_t current_tag; scsi_device_t *sd; - sd = &SCSIDevices[id][dev->current_lun]; + sd = &SCSIDevices[id]; current_tag = id; @@ -1079,7 +1078,7 @@ again: } dev->sstat0 |= NCR_SSTAT0_WOA; dev->scntl1 &= ~NCR_SCNTL1_IARB; - if (!scsi_device_present(id, 0)) { + if (!scsi_device_present(id)) { ncr53c810_bad_selection(dev, id); break; } @@ -1098,8 +1097,12 @@ again: break; case 2: /* Wait Reselect */ ncr53c810_log("Wait Reselect\n"); - if (!ncr53c810_irq_on_rsl(dev)) - dev->waiting = 1; + if (dev->istat & NCR_ISTAT_SIGP) + dev->dsp = dev->dnad; /* If SIGP is set, this command causes an immediate jump to DNAD. */ + else { + if (!ncr53c810_irq_on_rsl(dev)) + dev->waiting = 1; + } break; case 3: /* Set */ ncr53c810_log("Set%s%s%s%s\n", insn & (1 << 3) ? " ATN" : "", @@ -1462,7 +1465,7 @@ ncr53c810_reg_writeb(ncr53c810_t *dev, uint32_t offset, uint8_t val) ncr53c810_update_irq(dev); } - if (dev->waiting == 1 && val & NCR_ISTAT_SIGP) { + if ((dev->waiting == 1) && (val & NCR_ISTAT_SIGP)) { ncr53c810_log("Woken by SIGP\n"); dev->waiting = 0; dev->dsp = dev->dnad; @@ -1668,7 +1671,8 @@ ncr53c810_reg_readb(ncr53c810_t *dev, uint32_t offset) CASE_GET_REG32(dsa, 0x10) case 0x14: /* ISTAT */ ncr53c810_log("NCR 810: Read ISTAT %02X\n", dev->istat); - return dev->istat; + tmp = dev->istat; + return tmp; case 0x16: /* MBOX0 */ ncr53c810_log("NCR 810: Read MBOX0 %02X\n", dev->mbox0); return dev->mbox0; @@ -2170,7 +2174,7 @@ ncr53c810_init(const device_t *info) /* Enable our BIOS space in PCI, if needed. */ if (dev->has_bios) - rom_init(&dev->bios, NCR53C810_ROM, 0xd8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&dev->bios, NCR53C810_ROM, 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); return(dev); } diff --git a/src/scsi/scsi_x54x.c b/src/scsi/scsi_x54x.c index 13f8e37f4..e8c334eab 100644 --- a/src/scsi/scsi_x54x.c +++ b/src/scsi/scsi_x54x.c @@ -11,7 +11,7 @@ * series of SCSI Host Adapters made by Mylex. * These controllers were designed for various buses. * - * Version: @(#)scsi_x54x.c 1.0.21 2018/03/28 + * Version: @(#)scsi_x54x.c 1.0.21 2018/06/12 * * Authors: TheCollector1995, * Miran Grca, @@ -90,24 +90,21 @@ x54x_irq(x54x_t *dev, int set) if (dev->bus & DEVICE_PCI) { x54x_log("PCI IRQ: %02X, PCI_INTA\n", dev->pci_slot); - if (set) { + if (set) pci_set_irq(dev->pci_slot, PCI_INTA); - } else { + else pci_clear_irq(dev->pci_slot, PCI_INTA); - } } else { if (set) { if (dev->interrupt_type) int_type = dev->interrupt_type(dev); - if (int_type) { + if (int_type) picintlevel(1 << irq); - } else { + else picint(1 << irq); - } - } else { + } else picintc(1 << irq); - } } } @@ -157,10 +154,10 @@ clear_irq(x54x_t *dev) static void -target_check(uint8_t id, uint8_t lun) +target_check(uint8_t id) { - if (! scsi_device_valid(id, lun)) { - fatal("BIOS INT13 device on %02i:%02i has disappeared\n", id, lun); + if (! scsi_device_valid(id)) { + fatal("BIOS INT13 device on ID %02i has disappeared\n", id); } } @@ -235,15 +232,15 @@ completion_code(uint8_t *sense) static uint8_t -x54x_bios_command_08(uint8_t id, uint8_t lun, uint8_t *buffer) +x54x_bios_command_08(uint8_t id, uint8_t *buffer) { uint8_t cdb[12] = { GPCMD_READ_CDROM_CAPACITY, 0,0,0,0,0,0,0,0,0,0,0 }; uint8_t rcbuf[8] = { 0,0,0,0,0,0,0,0 }; uint32_t len = 0; int i, ret, sc; - ret = scsi_device_read_capacity(id, lun, cdb, rcbuf, &len); - sc = completion_code(scsi_device_sense(id, lun)); + ret = scsi_device_read_capacity(id, cdb, rcbuf, &len); + sc = completion_code(scsi_device_sense(id)); if (ret == 0) return(sc); memset(buffer, 0x00, 6); @@ -259,21 +256,21 @@ x54x_bios_command_08(uint8_t id, uint8_t lun, uint8_t *buffer) static int -x54x_bios_command_15(uint8_t id, uint8_t lun, uint8_t *buffer) +x54x_bios_command_15(uint8_t id, uint8_t *buffer) { uint8_t cdb[12] = { GPCMD_READ_CDROM_CAPACITY, 0,0,0,0,0,0,0,0,0,0,0 }; uint8_t rcbuf[8] = { 0,0,0,0,0,0,0,0 }; uint32_t len = 0; int i, ret, sc; - ret = scsi_device_read_capacity(id, lun, cdb, rcbuf, &len); - sc = completion_code(scsi_device_sense(id, lun)); + ret = scsi_device_read_capacity(id, cdb, rcbuf, &len); + sc = completion_code(scsi_device_sense(id)); memset(buffer, 0x00, 6); for (i=0; i<4; i++) buffer[i] = (ret == 0) ? 0 : rcbuf[i]; - scsi_device_type_data(id, lun, &(buffer[4]), &(buffer[5])); + scsi_device_type_data(id, &(buffer[4]), &(buffer[5])); x54x_log("BIOS Command 0x15: %02X %02X %02X %02X %02X %02X\n", buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5]); @@ -306,19 +303,22 @@ x54x_bios_command(x54x_t *x54x, uint8_t max_id, BIOSCMD *cmd, int8_t islba) return(0x80); } + if (cmd->lun) { + x54x_log("BIOS Target LUN is not 0\n"); + return(0x80); + } + /* Get pointer to selected device. */ - dev = &SCSIDevices[cmd->id][cmd->lun]; + dev = &SCSIDevices[cmd->id]; dev->BufferLength = 0; - if (! scsi_device_present(cmd->id, cmd->lun)) { - x54x_log("BIOS Target ID %i and LUN %i have no device attached\n", - cmd->id, cmd->lun); + if (! scsi_device_present(cmd->id)) { + x54x_log("BIOS Target ID %i has no device attached\n", cmd->id); return(0x80); } if ((dev->LunType == SCSI_CDROM) && !x54x->cdrom_boot) { - x54x_log("BIOS Target ID %i and LUN %i is CD-ROM on unsupported BIOS\n", - cmd->id, cmd->lun); + x54x_log("BIOS Target ID %i is CD-ROM on unsupported BIOS\n", cmd->id); return(0x80); } @@ -337,7 +337,7 @@ x54x_bios_command(x54x_t *x54x, uint8_t max_id, BIOSCMD *cmd, int8_t islba) return(0); case 0x01: /* Read Status of Last Operation */ - target_check(cmd->id, cmd->lun); + target_check(cmd->id); /* * Assuming 14 bytes because that is the default @@ -352,7 +352,7 @@ x54x_bios_command(x54x_t *x54x, uint8_t max_id, BIOSCMD *cmd, int8_t islba) x54x_log("BIOS DMA: Reading 14 bytes at %08X\n", dma_address); DMAPageWrite(dma_address, - scsi_device_sense(cmd->id, cmd->lun), 14); + scsi_device_sense(cmd->id), 14); } if (dev->CmdBuffer != NULL) { @@ -363,7 +363,7 @@ x54x_bios_command(x54x_t *x54x, uint8_t max_id, BIOSCMD *cmd, int8_t islba) return(0); case 0x02: /* Read Desired Sectors to Memory */ - target_check(cmd->id, cmd->lun); + target_check(cmd->id); dev->BufferLength = -1; @@ -379,14 +379,14 @@ x54x_bios_command(x54x_t *x54x, uint8_t max_id, BIOSCMD *cmd, int8_t islba) x54x_log("BIOS CMD(READ, %08lx, %d)\n", lba, cmd->secount); #endif - scsi_device_command_phase0(cmd->id, cmd->lun, 12, cdb); + scsi_device_command_phase0(cmd->id, cdb); if (dev->Phase == SCSI_PHASE_STATUS) goto skip_read_phase1; dev->CmdBuffer = (uint8_t *)malloc(dev->BufferLength); - scsi_device_command_phase1(cmd->id, cmd->lun); + scsi_device_command_phase1(cmd->id); if (sector_len > 0) { x54x_log("BIOS DMA: Reading %i bytes at %08X\n", dev->BufferLength, dma_address); @@ -400,10 +400,10 @@ skip_read_phase1: dev->CmdBuffer = NULL; } - return(completion_code(scsi_device_sense(cmd->id, cmd->lun))); + return(completion_code(scsi_device_sense(cmd->id))); case 0x03: /* Write Desired Sectors from Memory */ - target_check(cmd->id, cmd->lun); + target_check(cmd->id); dev->BufferLength = -1; @@ -419,7 +419,7 @@ skip_read_phase1: x54x_log("BIOS CMD(WRITE, %08lx, %d)\n", lba, cmd->secount); #endif - scsi_device_command_phase0(cmd->id, cmd->lun, 12, cdb); + scsi_device_command_phase0(cmd->id, cdb); if (dev->Phase == SCSI_PHASE_STATUS) goto skip_write_phase1; @@ -433,7 +433,7 @@ skip_read_phase1: dev->CmdBuffer, dev->BufferLength); } - scsi_device_command_phase1(cmd->id, cmd->lun); + scsi_device_command_phase1(cmd->id); skip_write_phase1: if (dev->CmdBuffer != NULL) { @@ -441,10 +441,10 @@ skip_write_phase1: dev->CmdBuffer = NULL; } - return(completion_code(scsi_device_sense(cmd->id, cmd->lun))); + return(completion_code(scsi_device_sense(cmd->id))); case 0x04: /* Verify Desired Sectors */ - target_check(cmd->id, cmd->lun); + target_check(cmd->id); cdb[0] = GPCMD_VERIFY_10; cdb[1] = (cmd->lun & 7) << 5; @@ -455,9 +455,9 @@ skip_write_phase1: cdb[7] = 0; cdb[8] = sector_len; - scsi_device_command_phase0(cmd->id, cmd->lun, 12, cdb); + scsi_device_command_phase0(cmd->id, cdb); - return(completion_code(scsi_device_sense(cmd->id, cmd->lun))); + return(completion_code(scsi_device_sense(cmd->id))); case 0x05: /* Format Track, invalid since SCSI has no tracks */ //FIXME: add a longer delay here --FvK @@ -468,23 +468,23 @@ skip_write_phase1: return(0); case 0x07: /* Format Unit */ - target_check(cmd->id, cmd->lun); + target_check(cmd->id); cdb[0] = GPCMD_FORMAT_UNIT; cdb[1] = (cmd->lun & 7) << 5; - scsi_device_command_phase0(cmd->id, cmd->lun, 12, cdb); + scsi_device_command_phase0(cmd->id, cdb); - return(completion_code(scsi_device_sense(cmd->id, cmd->lun))); + return(completion_code(scsi_device_sense(cmd->id))); case 0x08: /* Read Drive Parameters */ - target_check(cmd->id, cmd->lun); + target_check(cmd->id); dev->BufferLength = 6; dev->CmdBuffer = (uint8_t *)malloc(dev->BufferLength); memset(dev->CmdBuffer, 0x00, dev->BufferLength); - ret = x54x_bios_command_08(cmd->id, cmd->lun, dev->CmdBuffer); + ret = x54x_bios_command_08(cmd->id, dev->CmdBuffer); x54x_log("BIOS DMA: Reading 6 bytes at %08X\n", dma_address); DMAPageWrite(dma_address, @@ -502,7 +502,7 @@ skip_write_phase1: return(0); case 0x0c: /* Seek */ - target_check(cmd->id, cmd->lun); + target_check(cmd->id); cdb[0] = GPCMD_SEEK_10; cdb[1] = (cmd->lun & 7) << 5; @@ -511,7 +511,7 @@ skip_write_phase1: cdb[4] = (lba >> 8) & 0xff; cdb[5] = lba & 0xff; - scsi_device_command_phase0(cmd->id, cmd->lun, 12, cdb); + scsi_device_command_phase0(cmd->id, cdb); return((dev->Status == SCSI_STATUS_OK) ? 1 : 0); @@ -520,37 +520,37 @@ skip_write_phase1: return(0); case 0x10: /* Test Drive Ready */ - target_check(cmd->id, cmd->lun); + target_check(cmd->id); cdb[0] = GPCMD_TEST_UNIT_READY; cdb[1] = (cmd->lun & 7) << 5; - scsi_device_command_phase0(cmd->id, cmd->lun, 12, cdb); + scsi_device_command_phase0(cmd->id, cdb); - return(completion_code(scsi_device_sense(cmd->id, cmd->lun))); + return(completion_code(scsi_device_sense(cmd->id))); case 0x11: /* Recalibrate */ - target_check(cmd->id, cmd->lun); + target_check(cmd->id); cdb[0] = GPCMD_REZERO_UNIT; cdb[1] = (cmd->lun & 7) << 5; - scsi_device_command_phase0(cmd->id, cmd->lun, 12, cdb); + scsi_device_command_phase0(cmd->id, cdb); - return(completion_code(scsi_device_sense(cmd->id, cmd->lun))); + return(completion_code(scsi_device_sense(cmd->id))); case 0x14: /* Controller Diagnostic */ //FIXME: add a longer delay here --FvK return(0); case 0x15: /* Read DASD Type */ - target_check(cmd->id, cmd->lun); + target_check(cmd->id); dev->BufferLength = 6; dev->CmdBuffer = (uint8_t *)malloc(dev->BufferLength); memset(dev->CmdBuffer, 0x00, dev->BufferLength); - ret = x54x_bios_command_15(cmd->id, cmd->lun, dev->CmdBuffer); + ret = x54x_bios_command_15(cmd->id, dev->CmdBuffer); x54x_log("BIOS DMA: Reading 6 bytes at %08X\n", dma_address); DMAPageWrite(dma_address, @@ -762,7 +762,7 @@ x54x_set_residue(Req_t *req, int32_t TransferLength) { uint32_t Residue = 0; addr24 Residue24; - int32_t BufLen = SCSIDevices[req->TargetID][req->LUN].BufferLength; + int32_t BufLen = SCSIDevices[req->TargetID].BufferLength; if ((req->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND_RES) || (req->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND_RES)) { @@ -793,7 +793,7 @@ x54x_buf_dma_transfer(Req_t *req, int Is24bit, int TransferLength, int dir) uint32_t DataPointer, DataLength; uint32_t SGEntryLength = (Is24bit ? sizeof(SGE) : sizeof(SGE32)); uint32_t Address, i; - int32_t BufLen = SCSIDevices[req->TargetID][req->LUN].BufferLength; + int32_t BufLen = SCSIDevices[req->TargetID].BufferLength; uint8_t read_from_host = (dir && ((req->CmdBlock.common.ControlByte == CCB_DATA_XFER_OUT) || (req->CmdBlock.common.ControlByte == 0x00))); uint8_t write_to_host = (!dir && ((req->CmdBlock.common.ControlByte == CCB_DATA_XFER_IN) || (req->CmdBlock.common.ControlByte == 0x00))); int sg_pos = 0; @@ -807,8 +807,8 @@ x54x_buf_dma_transfer(Req_t *req, int Is24bit, int TransferLength, int dir) DataPointer = req->CmdBlock.new.DataPointer; DataLength = req->CmdBlock.new.DataLength; } - x54x_log("Data Buffer %s: length %d, pointer 0x%04X\n", - dir ? "write" : "read", BufLen, DataPointer); + x54x_log("Data Buffer %s: length %d (%u), pointer 0x%04X\n", + dir ? "write" : "read", BufLen, DataLength, DataPointer); if ((req->CmdBlock.common.ControlByte != 0x03) && TransferLength && BufLen) { if ((req->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND) || @@ -825,11 +825,11 @@ x54x_buf_dma_transfer(Req_t *req, int Is24bit, int TransferLength, int dir) if (read_from_host && DataToTransfer) { x54x_log("Reading S/G segment %i: length %i, pointer %08X\n", i, DataToTransfer, Address); - DMAPageRead(Address, &(SCSIDevices[req->TargetID][req->LUN].CmdBuffer[sg_pos]), DataToTransfer); + DMAPageRead(Address, &(SCSIDevices[req->TargetID].CmdBuffer[sg_pos]), DataToTransfer); } else if (write_to_host && DataToTransfer) { x54x_log("Writing S/G segment %i: length %i, pointer %08X\n", i, DataToTransfer, Address); - DMAPageWrite(Address, &(SCSIDevices[req->TargetID][req->LUN].CmdBuffer[sg_pos]), DataToTransfer); + DMAPageWrite(Address, &(SCSIDevices[req->TargetID].CmdBuffer[sg_pos]), DataToTransfer); } else x54x_log("No action on S/G segment %i: length %i, pointer %08X\n", i, DataToTransfer, Address); @@ -849,9 +849,9 @@ x54x_buf_dma_transfer(Req_t *req, int Is24bit, int TransferLength, int dir) if ((DataLength > 0) && (BufLen > 0) && (req->CmdBlock.common.ControlByte < 0x03)) { if (read_from_host) - DMAPageRead(Address, SCSIDevices[req->TargetID][req->LUN].CmdBuffer, MIN(BufLen, (int) DataLength)); + DMAPageRead(Address, SCSIDevices[req->TargetID].CmdBuffer, MIN(BufLen, (int) DataLength)); else if (write_to_host) - DMAPageWrite(Address, SCSIDevices[req->TargetID][req->LUN].CmdBuffer, MIN(BufLen, (int) DataLength)); + DMAPageWrite(Address, SCSIDevices[req->TargetID].CmdBuffer, MIN(BufLen, (int) DataLength)); } } } @@ -859,25 +859,25 @@ x54x_buf_dma_transfer(Req_t *req, int Is24bit, int TransferLength, int dir) void -x54x_buf_alloc(uint8_t id, uint8_t lun, int length) +x54x_buf_alloc(uint8_t id, int length) { - if (SCSIDevices[id][lun].CmdBuffer != NULL) { - free(SCSIDevices[id][lun].CmdBuffer); - SCSIDevices[id][lun].CmdBuffer = NULL; + if (SCSIDevices[id].CmdBuffer != NULL) { + free(SCSIDevices[id].CmdBuffer); + SCSIDevices[id].CmdBuffer = NULL; } x54x_log("Allocating data buffer (%i bytes)\n", length); - SCSIDevices[id][lun].CmdBuffer = (uint8_t *) malloc(length); - memset(SCSIDevices[id][lun].CmdBuffer, 0, length); + SCSIDevices[id].CmdBuffer = (uint8_t *) malloc(length); + memset(SCSIDevices[id].CmdBuffer, 0, length); } void -x54x_buf_free(uint8_t id, uint8_t lun) +x54x_buf_free(uint8_t id) { - if (SCSIDevices[id][lun].CmdBuffer != NULL) { - free(SCSIDevices[id][lun].CmdBuffer); - SCSIDevices[id][lun].CmdBuffer = NULL; + if (SCSIDevices[id].CmdBuffer != NULL) { + free(SCSIDevices[id].CmdBuffer); + SCSIDevices[id].CmdBuffer = NULL; } } @@ -921,7 +921,7 @@ SenseBufferFree(Req_t *req, int Copy) uint8_t temp_sense[256]; if (SenseLength && Copy) { - scsi_device_request_sense(req->TargetID, req->LUN, temp_sense, SenseLength); + scsi_device_request_sense(req->TargetID, temp_sense, SenseLength); /* * The sense address, in 32-bit mode, is located in the @@ -960,11 +960,11 @@ x54x_scsi_cmd(x54x_t *dev) id = req->TargetID; lun = req->LUN; - target_cdb_len = scsi_device_cdb_length(id, lun); + target_cdb_len = 12; target_data_len = x54x_get_length(req, bit24); - if (!scsi_device_valid(id, lun)) - fatal("SCSI target on %02i:%02i has disappeared\n", id, lun); + if (!scsi_device_valid(id)) + fatal("SCSI target on %02i has disappeared\n", id); x54x_log("target_data_len = %i\n", target_data_len); @@ -986,14 +986,14 @@ x54x_scsi_cmd(x54x_t *dev) dev->Residue = 0; - BufLen = scsi_device_get_buf_len(id, lun); + BufLen = scsi_device_get_buf_len(id); *BufLen = target_data_len; - x54x_log("Command buffer: %08X\n", SCSIDevices[id][lun].CmdBuffer); + x54x_log("Command buffer: %08X\n", SCSIDevices[id].CmdBuffer); - scsi_device_command_phase0(id, lun, req->CmdBlock.common.CdbLength, temp_cdb); + scsi_device_command_phase0(id, temp_cdb); - phase = SCSIDevices[id][lun].Phase; + phase = SCSIDevices[id].Phase; x54x_log("Control byte: %02X\n", (req->CmdBlock.common.ControlByte == 0x03)); @@ -1001,46 +1001,46 @@ x54x_scsi_cmd(x54x_t *dev) if ((temp_cdb[0] == 0x03) && (req->CmdBlock.common.ControlByte == 0x03)) { /* Request sense in non-data mode - sense goes to sense buffer. */ *BufLen = ConvertSenseLength(req->CmdBlock.common.RequestSenseLength); - x54x_buf_alloc(id, lun, *BufLen); - scsi_device_command_phase1(id, lun); - if ((SCSIDevices[id][lun].Status != SCSI_STATUS_OK) && (*BufLen > 0)) { + x54x_buf_alloc(id, *BufLen); + scsi_device_command_phase1(id); + if ((SCSIDevices[id].Status != SCSI_STATUS_OK) && (*BufLen > 0)) { SenseBufferAddress = SenseBufferPointer(req); - DMAPageWrite(SenseBufferAddress, SCSIDevices[id][lun].CmdBuffer, *BufLen); + DMAPageWrite(SenseBufferAddress, SCSIDevices[id].CmdBuffer, *BufLen); x54x_add_to_period(*BufLen); } } else { - p = scsi_device_get_callback(id, lun); + p = scsi_device_get_callback(id); if (p <= 0LL) x54x_add_to_period(*BufLen); else dev->media_period += p; - x54x_buf_alloc(id, lun, MIN(target_data_len, *BufLen)); + x54x_buf_alloc(id, MIN(target_data_len, *BufLen)); if (phase == SCSI_PHASE_DATA_OUT) x54x_buf_dma_transfer(req, bit24, target_data_len, 1); - scsi_device_command_phase1(id, lun); + scsi_device_command_phase1(id); if (phase == SCSI_PHASE_DATA_IN) x54x_buf_dma_transfer(req, bit24, target_data_len, 0); - SenseBufferFree(req, (SCSIDevices[id][lun].Status != SCSI_STATUS_OK)); + SenseBufferFree(req, (SCSIDevices[id].Status != SCSI_STATUS_OK)); } } else - SenseBufferFree(req, (SCSIDevices[id][lun].Status != SCSI_STATUS_OK)); + SenseBufferFree(req, (SCSIDevices[id].Status != SCSI_STATUS_OK)); x54x_set_residue(req, target_data_len); - x54x_buf_free(id, lun); + x54x_buf_free(id); x54x_log("Request complete\n"); - if (SCSIDevices[id][lun].Status == SCSI_STATUS_OK) { + if (SCSIDevices[id].Status == SCSI_STATUS_OK) { x54x_mbi_setup(dev, req->CCBPointer, &req->CmdBlock, CCB_COMPLETE, SCSI_STATUS_OK, MBI_SUCCESS); - } else if (SCSIDevices[id][lun].Status == SCSI_STATUS_CHECK_CONDITION) { + } else if (SCSIDevices[id].Status == SCSI_STATUS_CHECK_CONDITION) { x54x_mbi_setup(dev, req->CCBPointer, &req->CmdBlock, CCB_COMPLETE, SCSI_STATUS_CHECK_CONDITION, MBI_ERROR); } - x54x_log("SCSIDevices[%02i][%02i].Status = %02X\n", id, lun, SCSIDevices[id][lun].Status); + x54x_log("SCSIDevices[%02i].Status = %02X\n", id, SCSIDevices[id].Status); } @@ -1082,10 +1082,10 @@ x54x_req_setup(x54x_t *dev, uint32_t CCBPointer, Mailbox32_t *Mailbox32) x54x_log("Scanning SCSI Target ID %i\n", id); - SCSIDevices[id][lun].Status = SCSI_STATUS_OK; + SCSIDevices[id].Status = SCSI_STATUS_OK; /* If there is no device at ID:0, timeout the selection - the LUN is then checked later. */ - if (! scsi_device_present(id, 0)) { + if (! scsi_device_present(id)) { x54x_log("SCSI Target ID %i and LUN %i have no device attached\n",id,lun); x54x_mbi_setup(dev, CCBPointer, &req->CmdBlock, CCB_SELECTION_TIMEOUT, SCSI_STATUS_OK, MBI_ERROR); @@ -1107,7 +1107,7 @@ x54x_req_setup(x54x_t *dev, uint32_t CCBPointer, Mailbox32_t *Mailbox32) } if (req->CmdBlock.common.Opcode == 0x81) { x54x_log("Bus reset opcode\n"); - scsi_device_reset(id, lun); + scsi_device_reset(id); x54x_mbi_setup(dev, req->CCBPointer, &req->CmdBlock, CCB_COMPLETE, SCSI_STATUS_OK, MBI_SUCCESS); x54x_log("%s: Callback: Send incoming mailbox\n", dev->name); @@ -1423,7 +1423,7 @@ x54x_reset_poll(void *priv) static void x54x_reset(x54x_t *dev) { - int i, j; + int i; clear_irq(dev); if (dev->int_geom_writable) @@ -1443,10 +1443,8 @@ x54x_reset(x54x_t *dev) dev->MailboxOutPosCur = 0; /* Reset all devices on controller reset. */ - for (i = 0; i < 16; i++) { - for (j = 0; j < 8; j++) - scsi_device_reset(i, j); - } + for (i = 0; i < 16; i++) + scsi_device_reset(i); if (dev->ven_reset) dev->ven_reset(dev); @@ -1479,7 +1477,6 @@ x54x_out(uint16_t port, uint8_t val, void *priv) x54x_t *dev = (x54x_t *)priv; MailboxInit_t *mbi; int i = 0; - uint8_t j = 0; BIOSCMD *cmd; uint16_t cyl = 0; int suppress = 0; @@ -1503,10 +1500,8 @@ x54x_out(uint16_t port, uint8_t val, void *priv) if (val & CTRL_SCRST) { /* Reset all devices on SCSI bus reset. */ - for (i = 0; i < 16; i++) { - for (j = 0; j < 8; j++) - scsi_device_reset(i, j); - } + for (i = 0; i < 16; i++) + scsi_device_reset(i); } if (val & CTRL_IRST) { @@ -1682,10 +1677,9 @@ x54x_out(uint16_t port, uint8_t val, void *priv) /* Skip the HA .. */ if (i == host_id) continue; - for (j=0; jDataBuf[i] |= (1<DataBuf[i] |= 1; } dev->DataReplyLeft = i; break; diff --git a/src/scsi/scsi_x54x.h b/src/scsi/scsi_x54x.h index d2e7cb60b..13699a181 100644 --- a/src/scsi/scsi_x54x.h +++ b/src/scsi/scsi_x54x.h @@ -492,8 +492,8 @@ typedef struct extern void x54x_reset_ctrl(x54x_t *dev, uint8_t Reset); -extern void x54x_buf_alloc(uint8_t id, uint8_t lun, int length); -extern void x54x_buf_free(uint8_t id, uint8_t lun); +extern void x54x_buf_alloc(uint8_t id, int length); +extern void x54x_buf_free(uint8_t id); extern uint8_t x54x_mbo_process(x54x_t *dev); extern void x54x_wait_for_poll(void); extern void x54x_io_set(x54x_t *dev, uint32_t base, uint8_t len); diff --git a/src/sound/midi_fluidsynth.c b/src/sound/midi_fluidsynth.c index 057a1f160..22d318fbf 100644 --- a/src/sound/midi_fluidsynth.c +++ b/src/sound/midi_fluidsynth.c @@ -247,7 +247,7 @@ void* fluidsynth_init(const device_t *info) #endif if (fluidsynth_handle == NULL) { - ui_msgbox(MBX_ERROR, (wchar_t *)IDS_2171); + ui_msgbox(MBX_ERROR, (wchar_t *)IDS_2081); return NULL; } diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index 894ab57f3..cfb5e6d99 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -11,7 +11,7 @@ * This is intended to be used by another SVGA driver, * and not as a card in it's own right. * - * Version: @(#)vid_svga.c 1.0.30 2018/04/26 + * Version: @(#)vid_svga.c 1.0.31 2018/05/26 * * Authors: Sarah Walker, * Miran Grca, @@ -966,7 +966,7 @@ uint8_t svga_read_common(uint32_t addr, uint8_t linear, void *p) { svga_t *svga = (svga_t *)p; - uint32_t latch_addr, ret; + uint32_t latch_addr = 0, ret; int readplane = svga->readplane; uint8_t ret8; @@ -1104,7 +1104,7 @@ svga_doblit(int y1, int y2, int wx, int wy, svga_t *svga) p = &((uint32_t *)buffer32->line[i & 0x7ff])[32]; for (j = 0; j < (xsize + x_add); j++) - p[j] = svga_color_transform(svga->overscan_color); + p[j] = svga->overscan_color; } /* Draw (overscan_size + scroll size) lines of overscan on the bottom. */ @@ -1112,7 +1112,7 @@ svga_doblit(int y1, int y2, int wx, int wy, svga_t *svga) p = &((uint32_t *)buffer32->line[(ysize + (y_add >> 1) + i) & 0x7ff])[32]; for (j = 0; j < (xsize + x_add); j++) - p[j] = svga_color_transform(svga->overscan_color); + p[j] = svga->overscan_color; } for (i = (y_add >> 1); i < (ysize + (y_add >> 1)); i ++) { @@ -1120,7 +1120,7 @@ svga_doblit(int y1, int y2, int wx, int wy, svga_t *svga) for (j = 0; j < 8; j++) { p[j] = svga->pallook[svga->overscan_color]; - p[xsize + (x_add >> 1) + j] = svga_color_transform(svga->overscan_color); + p[xsize + (x_add >> 1) + j] = svga->overscan_color; } } } diff --git a/src/video/vid_svga.h b/src/video/vid_svga.h index 1711af4cc..214e62a13 100644 --- a/src/video/vid_svga.h +++ b/src/video/vid_svga.h @@ -8,7 +8,7 @@ * * Generic SVGA handling. * - * Version: @(#)vid_svga.h 1.0.11 2018/04/01 + * Version: @(#)vid_svga.h 1.0.12 2018/05/26 * * Authors: Sarah Walker, * Miran Grca, @@ -170,36 +170,3 @@ enum { RAMDAC_6BIT = 0, RAMDAC_8BIT }; - -extern uint32_t shade[5][256]; - - -static __inline__ uint32_t -svga_color_transform(uint32_t color) -{ - uint8_t *clr8 = (uint8_t *) &color; - if (!video_grayscale && !invert_display) - return color; - if (video_grayscale) { - if (video_graytype) { - if (video_graytype == 1) - color = ((54 * (uint32_t)clr8[2]) + (183 * (uint32_t)clr8[1]) + (18 * (uint32_t)clr8[0])) / 255; - else - color = ((uint32_t)clr8[2] + (uint32_t)clr8[1] + (uint32_t)clr8[0]) / 3; - } else - color = ((76 * (uint32_t)clr8[2]) + (150 * (uint32_t)clr8[1]) + (29 * (uint32_t)clr8[0])) / 255; - switch (video_grayscale) { - case 2: case 3: case 4: - color = shade[video_grayscale][color]; - break; - default: - clr8[3] = 0; - clr8[0] = color; - clr8[1] = clr8[2] = clr8[0]; - break; - } - } - if (invert_display) - color ^= 0x00ffffff; - return color; -} diff --git a/src/video/vid_svga_render.c b/src/video/vid_svga_render.c index 1a6912782..3e920bd1e 100644 --- a/src/video/vid_svga_render.c +++ b/src/video/vid_svga_render.c @@ -8,7 +8,7 @@ * * SVGA renderers. * - * Version: @(#)vid_svga_render.c 1.0.10 2018/03/19 + * Version: @(#)vid_svga_render.c 1.0.11 2018/05/26 * * Authors: Sarah Walker, * Miran Grca, @@ -27,71 +27,6 @@ #include "vid_svga_render.h" -int invert_display = 0; -int video_grayscale = 0; -int video_graytype = 0; - - -uint32_t shade[5][256] = -{ - {0}, // RGB Color (unused) - {0}, // RGB Grayscale (unused) - { // Amber monitor - 0x000000, 0x060000, 0x090000, 0x0d0000, 0x100000, 0x120100, 0x150100, 0x170100, 0x1a0100, 0x1c0100, 0x1e0200, 0x210200, 0x230200, 0x250300, 0x270300, 0x290300, - 0x2b0400, 0x2d0400, 0x2f0400, 0x300500, 0x320500, 0x340500, 0x360600, 0x380600, 0x390700, 0x3b0700, 0x3d0700, 0x3f0800, 0x400800, 0x420900, 0x440900, 0x450a00, - 0x470a00, 0x480b00, 0x4a0b00, 0x4c0c00, 0x4d0c00, 0x4f0d00, 0x500d00, 0x520e00, 0x530e00, 0x550f00, 0x560f00, 0x581000, 0x591000, 0x5b1100, 0x5c1200, 0x5e1200, - 0x5f1300, 0x601300, 0x621400, 0x631500, 0x651500, 0x661600, 0x671600, 0x691700, 0x6a1800, 0x6c1800, 0x6d1900, 0x6e1a00, 0x701a00, 0x711b00, 0x721c00, 0x741c00, - 0x751d00, 0x761e00, 0x781e00, 0x791f00, 0x7a2000, 0x7c2000, 0x7d2100, 0x7e2200, 0x7f2300, 0x812300, 0x822400, 0x832500, 0x842600, 0x862600, 0x872700, 0x882800, - 0x8a2900, 0x8b2900, 0x8c2a00, 0x8d2b00, 0x8e2c00, 0x902c00, 0x912d00, 0x922e00, 0x932f00, 0x953000, 0x963000, 0x973100, 0x983200, 0x993300, 0x9b3400, 0x9c3400, - 0x9d3500, 0x9e3600, 0x9f3700, 0xa03800, 0xa23900, 0xa33a00, 0xa43a00, 0xa53b00, 0xa63c00, 0xa73d00, 0xa93e00, 0xaa3f00, 0xab4000, 0xac4000, 0xad4100, 0xae4200, - 0xaf4300, 0xb14400, 0xb24500, 0xb34600, 0xb44700, 0xb54800, 0xb64900, 0xb74a00, 0xb94a00, 0xba4b00, 0xbb4c00, 0xbc4d00, 0xbd4e00, 0xbe4f00, 0xbf5000, 0xc05100, - 0xc15200, 0xc25300, 0xc45400, 0xc55500, 0xc65600, 0xc75700, 0xc85800, 0xc95900, 0xca5a00, 0xcb5b00, 0xcc5c00, 0xcd5d00, 0xce5e00, 0xcf5f00, 0xd06000, 0xd26101, - 0xd36201, 0xd46301, 0xd56401, 0xd66501, 0xd76601, 0xd86701, 0xd96801, 0xda6901, 0xdb6a01, 0xdc6b01, 0xdd6c01, 0xde6d01, 0xdf6e01, 0xe06f01, 0xe17001, 0xe27201, - 0xe37301, 0xe47401, 0xe57501, 0xe67602, 0xe77702, 0xe87802, 0xe97902, 0xeb7a02, 0xec7b02, 0xed7c02, 0xee7e02, 0xef7f02, 0xf08002, 0xf18103, 0xf28203, 0xf38303, - 0xf48403, 0xf58503, 0xf68703, 0xf78803, 0xf88903, 0xf98a04, 0xfa8b04, 0xfb8c04, 0xfc8d04, 0xfd8f04, 0xfe9005, 0xff9105, 0xff9205, 0xff9305, 0xff9405, 0xff9606, - 0xff9706, 0xff9806, 0xff9906, 0xff9a07, 0xff9b07, 0xff9d07, 0xff9e08, 0xff9f08, 0xffa008, 0xffa109, 0xffa309, 0xffa409, 0xffa50a, 0xffa60a, 0xffa80a, 0xffa90b, - 0xffaa0b, 0xffab0c, 0xffac0c, 0xffae0d, 0xffaf0d, 0xffb00e, 0xffb10e, 0xffb30f, 0xffb40f, 0xffb510, 0xffb610, 0xffb811, 0xffb912, 0xffba12, 0xffbb13, 0xffbd14, - 0xffbe14, 0xffbf15, 0xffc016, 0xffc217, 0xffc317, 0xffc418, 0xffc619, 0xffc71a, 0xffc81b, 0xffca1c, 0xffcb1d, 0xffcc1e, 0xffcd1f, 0xffcf20, 0xffd021, 0xffd122, - 0xffd323, 0xffd424, 0xffd526, 0xffd727, 0xffd828, 0xffd92a, 0xffdb2b, 0xffdc2c, 0xffdd2e, 0xffdf2f, 0xffe031, 0xffe133, 0xffe334, 0xffe436, 0xffe538, 0xffe739 - }, - { // Green monitor - 0x000000, 0x000400, 0x000700, 0x000900, 0x000b00, 0x000d00, 0x000f00, 0x001100, 0x001300, 0x001500, 0x001600, 0x001800, 0x001a00, 0x001b00, 0x001d00, 0x001e00, - 0x002000, 0x002100, 0x002300, 0x002400, 0x002601, 0x002701, 0x002901, 0x002a01, 0x002b01, 0x002d01, 0x002e01, 0x002f01, 0x003101, 0x003201, 0x003301, 0x003401, - 0x003601, 0x003702, 0x003802, 0x003902, 0x003b02, 0x003c02, 0x003d02, 0x003e02, 0x004002, 0x004102, 0x004203, 0x004303, 0x004403, 0x004503, 0x004703, 0x004803, - 0x004903, 0x004a03, 0x004b04, 0x004c04, 0x004d04, 0x004e04, 0x005004, 0x005104, 0x005205, 0x005305, 0x005405, 0x005505, 0x005605, 0x005705, 0x005806, 0x005906, - 0x005a06, 0x005b06, 0x005d06, 0x005e07, 0x005f07, 0x006007, 0x006107, 0x006207, 0x006308, 0x006408, 0x006508, 0x006608, 0x006708, 0x006809, 0x006909, 0x006a09, - 0x006b09, 0x016c0a, 0x016d0a, 0x016e0a, 0x016f0a, 0x01700b, 0x01710b, 0x01720b, 0x01730b, 0x01740c, 0x01750c, 0x01760c, 0x01770c, 0x01780d, 0x01790d, 0x017a0d, - 0x017b0d, 0x017b0e, 0x017c0e, 0x017d0e, 0x017e0f, 0x017f0f, 0x01800f, 0x018110, 0x028210, 0x028310, 0x028410, 0x028511, 0x028611, 0x028711, 0x028812, 0x028912, - 0x028a12, 0x028a13, 0x028b13, 0x028c13, 0x028d14, 0x028e14, 0x038f14, 0x039015, 0x039115, 0x039215, 0x039316, 0x039416, 0x039417, 0x039517, 0x039617, 0x039718, - 0x049818, 0x049918, 0x049a19, 0x049b19, 0x049c19, 0x049c1a, 0x049d1a, 0x049e1b, 0x059f1b, 0x05a01b, 0x05a11c, 0x05a21c, 0x05a31c, 0x05a31d, 0x05a41d, 0x06a51e, - 0x06a61e, 0x06a71f, 0x06a81f, 0x06a920, 0x06aa20, 0x07aa21, 0x07ab21, 0x07ac21, 0x07ad22, 0x07ae22, 0x08af23, 0x08b023, 0x08b024, 0x08b124, 0x08b225, 0x09b325, - 0x09b426, 0x09b526, 0x09b527, 0x0ab627, 0x0ab728, 0x0ab828, 0x0ab929, 0x0bba29, 0x0bba2a, 0x0bbb2a, 0x0bbc2b, 0x0cbd2b, 0x0cbe2c, 0x0cbf2c, 0x0dbf2d, 0x0dc02d, - 0x0dc12e, 0x0ec22e, 0x0ec32f, 0x0ec42f, 0x0fc430, 0x0fc530, 0x0fc631, 0x10c731, 0x10c832, 0x10c932, 0x11c933, 0x11ca33, 0x11cb34, 0x12cc35, 0x12cd35, 0x12cd36, - 0x13ce36, 0x13cf37, 0x13d037, 0x14d138, 0x14d139, 0x14d239, 0x15d33a, 0x15d43a, 0x16d43b, 0x16d53b, 0x17d63c, 0x17d73d, 0x17d83d, 0x18d83e, 0x18d93e, 0x19da3f, - 0x19db40, 0x1adc40, 0x1adc41, 0x1bdd41, 0x1bde42, 0x1cdf43, 0x1ce043, 0x1de044, 0x1ee145, 0x1ee245, 0x1fe346, 0x1fe446, 0x20e447, 0x20e548, 0x21e648, 0x22e749, - 0x22e74a, 0x23e84a, 0x23e94b, 0x24ea4c, 0x25ea4c, 0x25eb4d, 0x26ec4e, 0x27ed4e, 0x27ee4f, 0x28ee50, 0x29ef50, 0x29f051, 0x2af152, 0x2bf153, 0x2cf253, 0x2cf354, - 0x2df455, 0x2ef455, 0x2ff556, 0x2ff657, 0x30f758, 0x31f758, 0x32f859, 0x32f95a, 0x33fa5a, 0x34fa5b, 0x35fb5c, 0x36fc5d, 0x37fd5d, 0x38fd5e, 0x38fe5f, 0x39ff60 - }, - { // White monitor - 0x000000, 0x010102, 0x020203, 0x020304, 0x030406, 0x040507, 0x050608, 0x060709, 0x07080a, 0x08090c, 0x080a0d, 0x090b0e, 0x0a0c0f, 0x0b0d10, 0x0c0e11, 0x0d0f12, - 0x0e1013, 0x0f1115, 0x101216, 0x111317, 0x121418, 0x121519, 0x13161a, 0x14171b, 0x15181c, 0x16191d, 0x171a1e, 0x181b1f, 0x191c20, 0x1a1d21, 0x1b1e22, 0x1c1f23, - 0x1d2024, 0x1e2125, 0x1f2226, 0x202327, 0x212428, 0x222529, 0x22262b, 0x23272c, 0x24282d, 0x25292e, 0x262a2f, 0x272b30, 0x282c30, 0x292d31, 0x2a2e32, 0x2b2f33, - 0x2c3034, 0x2d3035, 0x2e3136, 0x2f3237, 0x303338, 0x313439, 0x32353a, 0x33363b, 0x34373c, 0x35383d, 0x36393e, 0x373a3f, 0x383b40, 0x393c41, 0x3a3d42, 0x3b3e43, - 0x3c3f44, 0x3d4045, 0x3e4146, 0x3f4247, 0x404348, 0x414449, 0x42454a, 0x43464b, 0x44474c, 0x45484d, 0x46494d, 0x474a4e, 0x484b4f, 0x484c50, 0x494d51, 0x4a4e52, - 0x4b4f53, 0x4c5054, 0x4d5155, 0x4e5256, 0x4f5357, 0x505458, 0x515559, 0x52565a, 0x53575b, 0x54585b, 0x55595c, 0x565a5d, 0x575b5e, 0x585c5f, 0x595d60, 0x5a5e61, - 0x5b5f62, 0x5c6063, 0x5d6164, 0x5e6265, 0x5f6366, 0x606466, 0x616567, 0x626668, 0x636769, 0x64686a, 0x65696b, 0x666a6c, 0x676b6d, 0x686c6e, 0x696d6f, 0x6a6e70, - 0x6b6f70, 0x6c7071, 0x6d7172, 0x6f7273, 0x707374, 0x707475, 0x717576, 0x727677, 0x747778, 0x757879, 0x767979, 0x777a7a, 0x787b7b, 0x797c7c, 0x7a7d7d, 0x7b7e7e, - 0x7c7f7f, 0x7d8080, 0x7e8181, 0x7f8281, 0x808382, 0x818483, 0x828584, 0x838685, 0x848786, 0x858887, 0x868988, 0x878a89, 0x888b89, 0x898c8a, 0x8a8d8b, 0x8b8e8c, - 0x8c8f8d, 0x8d8f8e, 0x8e908f, 0x8f9190, 0x909290, 0x919391, 0x929492, 0x939593, 0x949694, 0x959795, 0x969896, 0x979997, 0x989a98, 0x999b98, 0x9a9c99, 0x9b9d9a, - 0x9c9e9b, 0x9d9f9c, 0x9ea09d, 0x9fa19e, 0xa0a29f, 0xa1a39f, 0xa2a4a0, 0xa3a5a1, 0xa4a6a2, 0xa6a7a3, 0xa7a8a4, 0xa8a9a5, 0xa9aaa5, 0xaaaba6, 0xabaca7, 0xacada8, - 0xadaea9, 0xaeafaa, 0xafb0ab, 0xb0b1ac, 0xb1b2ac, 0xb2b3ad, 0xb3b4ae, 0xb4b5af, 0xb5b6b0, 0xb6b7b1, 0xb7b8b2, 0xb8b9b2, 0xb9bab3, 0xbabbb4, 0xbbbcb5, 0xbcbdb6, - 0xbdbeb7, 0xbebfb8, 0xbfc0b8, 0xc0c1b9, 0xc1c2ba, 0xc2c3bb, 0xc3c4bc, 0xc5c5bd, 0xc6c6be, 0xc7c7be, 0xc8c8bf, 0xc9c9c0, 0xcacac1, 0xcbcbc2, 0xccccc3, 0xcdcdc3, - 0xcecec4, 0xcfcfc5, 0xd0d0c6, 0xd1d1c7, 0xd2d2c8, 0xd3d3c9, 0xd4d4c9, 0xd5d5ca, 0xd6d6cb, 0xd7d7cc, 0xd8d8cd, 0xd9d9ce, 0xdadacf, 0xdbdbcf, 0xdcdcd0, 0xdeddd1, - 0xdfded2, 0xe0dfd3, 0xe1e0d4, 0xe2e1d4, 0xe3e2d5, 0xe4e3d6, 0xe5e4d7, 0xe6e5d8, 0xe7e6d9, 0xe8e7d9, 0xe9e8da, 0xeae9db, 0xebeadc, 0xecebdd, 0xedecde, 0xeeeddf, - 0xefeedf, 0xf0efe0, 0xf1f0e1, 0xf2f1e2, 0xf3f2e3, 0xf4f3e3, 0xf6f3e4, 0xf7f4e5, 0xf8f5e6, 0xf9f6e7, 0xfaf7e8, 0xfbf8e9, 0xfcf9e9, 0xfdfaea, 0xfefbeb, 0xfffcec - } -}; - void svga_render_blank(svga_t *svga) { int x, xx; @@ -107,16 +42,16 @@ void svga_render_blank(svga_t *svga) switch (svga->seqregs[1] & 9) { case 0: - for (xx = 0; xx < 9; xx++) ((uint32_t *)buffer32->line[svga->displine + y_add])[(x * 9) + xx + 32 + x_add] = svga_color_transform(0); + for (xx = 0; xx < 9; xx++) ((uint32_t *)buffer32->line[svga->displine + y_add])[(x * 9) + xx + 32 + x_add] = 0; break; case 1: - for (xx = 0; xx < 8; xx++) ((uint32_t *)buffer32->line[svga->displine + y_add])[(x * 8) + xx + 32 + x_add] = svga_color_transform(0); + for (xx = 0; xx < 8; xx++) ((uint32_t *)buffer32->line[svga->displine + y_add])[(x * 8) + xx + 32 + x_add] = 0; break; case 8: - for (xx = 0; xx < 18; xx++) ((uint32_t *)buffer32->line[svga->displine + y_add])[(x * 18) + xx + 32 + x_add] = svga_color_transform(0); + for (xx = 0; xx < 18; xx++) ((uint32_t *)buffer32->line[svga->displine + y_add])[(x * 18) + xx + 32 + x_add] = 0; break; case 9: - for (xx = 0; xx < 16; xx++) ((uint32_t *)buffer32->line[svga->displine + y_add])[(x * 16) + xx + 32 + x_add] = svga_color_transform(0); + for (xx = 0; xx < 16; xx++) ((uint32_t *)buffer32->line[svga->displine + y_add])[(x * 16) + xx + 32 + x_add] = 0; break; } } @@ -166,9 +101,6 @@ void svga_render_text_40(svga_t *svga) } } - fg = svga_color_transform(fg); - bg = svga_color_transform(bg); - dat = svga->vram[charaddr + (svga->sc << 2)]; if (svga->seqregs[1] & 1) { @@ -237,9 +169,6 @@ void svga_render_text_80(svga_t *svga) } } - fg = svga_color_transform(fg); - bg = svga_color_transform(bg); - dat = svga->vram[charaddr + (svga->sc << 2)]; if (svga->seqregs[1] & 1) { @@ -306,9 +235,6 @@ void svga_render_text_80_ksc5601(svga_t *svga) } } - fg = svga_color_transform(fg); - bg = svga_color_transform(bg); - if(x + xinc < svga->hdisp && (chr & nextchr & 0x80)) { if((chr == 0xc9 || chr == 0xfe) && (nextchr > 0xa0 && nextchr < 0xff)) @@ -417,14 +343,14 @@ void svga_render_2bpp_lowres(svga_t *svga) svga->ma += 4; svga->ma &= svga->vram_display_mask; - p[0] = p[1] = svga_color_transform(svga->pallook[svga->egapal[(dat[0] >> 6) & 3]]); - p[2] = p[3] = svga_color_transform(svga->pallook[svga->egapal[(dat[0] >> 4) & 3]]); - p[4] = p[5] = svga_color_transform(svga->pallook[svga->egapal[(dat[0] >> 2) & 3]]); - p[6] = p[7] = svga_color_transform(svga->pallook[svga->egapal[dat[0] & 3]]); - p[8] = p[9] = svga_color_transform(svga->pallook[svga->egapal[(dat[1] >> 6) & 3]]); - p[10] = p[11] = svga_color_transform(svga->pallook[svga->egapal[(dat[1] >> 4) & 3]]); - p[12] = p[13] = svga_color_transform(svga->pallook[svga->egapal[(dat[1] >> 2) & 3]]); - p[14] = p[15] = svga_color_transform(svga->pallook[svga->egapal[dat[1] & 3]]); + p[0] = p[1] = svga->pallook[svga->egapal[(dat[0] >> 6) & 3]]; + p[2] = p[3] = svga->pallook[svga->egapal[(dat[0] >> 4) & 3]]; + p[4] = p[5] = svga->pallook[svga->egapal[(dat[0] >> 2) & 3]]; + p[6] = p[7] = svga->pallook[svga->egapal[dat[0] & 3]]; + p[8] = p[9] = svga->pallook[svga->egapal[(dat[1] >> 6) & 3]]; + p[10] = p[11] = svga->pallook[svga->egapal[(dat[1] >> 4) & 3]]; + p[12] = p[13] = svga->pallook[svga->egapal[(dat[1] >> 2) & 3]]; + p[14] = p[15] = svga->pallook[svga->egapal[dat[1] & 3]]; p += 16; } @@ -459,14 +385,14 @@ void svga_render_2bpp_highres(svga_t *svga) svga->ma += 4; svga->ma &= svga->vram_display_mask; - p[0] = svga_color_transform(svga->pallook[svga->egapal[(dat[0] >> 6) & 3]]); - p[1] = svga_color_transform(svga->pallook[svga->egapal[(dat[0] >> 4) & 3]]); - p[2] = svga_color_transform(svga->pallook[svga->egapal[(dat[0] >> 2) & 3]]); - p[3] = svga_color_transform(svga->pallook[svga->egapal[dat[0] & 3]]); - p[4] = svga_color_transform(svga->pallook[svga->egapal[(dat[1] >> 6) & 3]]); - p[5] = svga_color_transform(svga->pallook[svga->egapal[(dat[1] >> 4) & 3]]); - p[6] = svga_color_transform(svga->pallook[svga->egapal[(dat[1] >> 2) & 3]]); - p[7] = svga_color_transform(svga->pallook[svga->egapal[dat[1] & 3]]); + p[0] = svga->pallook[svga->egapal[(dat[0] >> 6) & 3]]; + p[1] = svga->pallook[svga->egapal[(dat[0] >> 4) & 3]]; + p[2] = svga->pallook[svga->egapal[(dat[0] >> 2) & 3]]; + p[3] = svga->pallook[svga->egapal[dat[0] & 3]]; + p[4] = svga->pallook[svga->egapal[(dat[1] >> 6) & 3]]; + p[5] = svga->pallook[svga->egapal[(dat[1] >> 4) & 3]]; + p[6] = svga->pallook[svga->egapal[(dat[1] >> 2) & 3]]; + p[7] = svga->pallook[svga->egapal[dat[1] & 3]]; p += 8; } @@ -498,17 +424,17 @@ void svga_render_4bpp_lowres(svga_t *svga) svga->ma &= svga->vram_display_mask; dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); - p[0] = p[1] = svga_color_transform(svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]); - p[2] = p[3] = svga_color_transform(svga->pallook[svga->egapal[dat & svga->plane_mask]]); + p[0] = p[1] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; + p[2] = p[3] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2); - p[4] = p[5] = svga_color_transform(svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]); - p[6] = p[7] = svga_color_transform(svga->pallook[svga->egapal[dat & svga->plane_mask]]); + p[4] = p[5] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; + p[6] = p[7] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2); - p[8] = p[9] = svga_color_transform(svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]); - p[10] = p[11] = svga_color_transform(svga->pallook[svga->egapal[dat & svga->plane_mask]]); + p[8] = p[9] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; + p[10] = p[11] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); - p[12] = p[13] = svga_color_transform(svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]); - p[14] = p[15] = svga_color_transform(svga->pallook[svga->egapal[dat & svga->plane_mask]]); + p[12] = p[13] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; + p[14] = p[15] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; p += 16; } @@ -544,17 +470,17 @@ void svga_render_4bpp_highres(svga_t *svga) svga->ma &= svga->vram_display_mask; dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); - p[0] = svga_color_transform(svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]); - p[1] = svga_color_transform(svga->pallook[svga->egapal[dat & svga->plane_mask]]); + p[0] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; + p[1] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2); - p[2] = svga_color_transform(svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]); - p[3] = svga_color_transform(svga->pallook[svga->egapal[dat & svga->plane_mask]]); + p[2] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; + p[3] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2); - p[4] = svga_color_transform(svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]); - p[5] = svga_color_transform(svga->pallook[svga->egapal[dat & svga->plane_mask]]); + p[4] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; + p[5] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); - p[6] = svga_color_transform(svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]); - p[7] = svga_color_transform(svga->pallook[svga->egapal[dat & svga->plane_mask]]); + p[6] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; + p[7] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; p += 8; } @@ -580,10 +506,10 @@ void svga_render_8bpp_lowres(svga_t *svga) { uint32_t dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); - p[0] = p[1] = svga_color_transform(svga->pallook[dat & 0xff]); - p[2] = p[3] = svga_color_transform(svga->pallook[(dat >> 8) & 0xff]); - p[4] = p[5] = svga_color_transform(svga->pallook[(dat >> 16) & 0xff]); - p[6] = p[7] = svga_color_transform(svga->pallook[(dat >> 24) & 0xff]); + p[0] = p[1] = svga->pallook[dat & 0xff]; + p[2] = p[3] = svga->pallook[(dat >> 8) & 0xff]; + p[4] = p[5] = svga->pallook[(dat >> 16) & 0xff]; + p[6] = p[7] = svga->pallook[(dat >> 24) & 0xff]; svga->ma += 4; p += 8; @@ -611,16 +537,16 @@ void svga_render_8bpp_highres(svga_t *svga) { uint32_t dat; dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); - p[0] = svga_color_transform(svga->pallook[dat & 0xff]); - p[1] = svga_color_transform(svga->pallook[(dat >> 8) & 0xff]); - p[2] = svga_color_transform(svga->pallook[(dat >> 16) & 0xff]); - p[3] = svga_color_transform(svga->pallook[(dat >> 24) & 0xff]); + p[0] = svga->pallook[dat & 0xff]; + p[1] = svga->pallook[(dat >> 8) & 0xff]; + p[2] = svga->pallook[(dat >> 16) & 0xff]; + p[3] = svga->pallook[(dat >> 24) & 0xff]; dat = *(uint32_t *)(&svga->vram[(svga->ma + 4) & svga->vram_display_mask]); - p[4] = svga_color_transform(svga->pallook[dat & 0xff]); - p[5] = svga_color_transform(svga->pallook[(dat >> 8) & 0xff]); - p[6] = svga_color_transform(svga->pallook[(dat >> 16) & 0xff]); - p[7] = svga_color_transform(svga->pallook[(dat >> 24) & 0xff]); + p[4] = svga->pallook[dat & 0xff]; + p[5] = svga->pallook[(dat >> 8) & 0xff]; + p[6] = svga->pallook[(dat >> 16) & 0xff]; + p[7] = svga->pallook[(dat >> 24) & 0xff]; svga->ma += 8; p += 8; @@ -648,13 +574,13 @@ void svga_render_15bpp_lowres(svga_t *svga) { uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - p[x] = svga_color_transform(video_15to32[dat & 0xffff]); - p[x + 1] = svga_color_transform(video_15to32[dat >> 16]); + p[x] = video_15to32[dat & 0xffff]; + p[x + 1] = video_15to32[dat >> 16]; dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - p[x] = svga_color_transform(video_15to32[dat & 0xffff]); - p[x + 1] = svga_color_transform(video_15to32[dat >> 16]); + p[x] = video_15to32[dat & 0xffff]; + p[x + 1] = video_15to32[dat >> 16]; } svga->ma += x << 1; svga->ma &= svga->vram_display_mask; @@ -679,20 +605,20 @@ void svga_render_15bpp_highres(svga_t *svga) for (x = 0; x <= svga->hdisp; x += 8) { uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - p[x] = svga_color_transform(video_15to32[dat & 0xffff]); - p[x + 1] = svga_color_transform(video_15to32[dat >> 16]); + p[x] = video_15to32[dat & 0xffff]; + p[x + 1] = video_15to32[dat >> 16]; dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - p[x + 2] = svga_color_transform(video_15to32[dat & 0xffff]); - p[x + 3] = svga_color_transform(video_15to32[dat >> 16]); + p[x + 2] = video_15to32[dat & 0xffff]; + p[x + 3] = video_15to32[dat >> 16]; dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]); - p[x + 4] = svga_color_transform(video_15to32[dat & 0xffff]); - p[x + 5] = svga_color_transform(video_15to32[dat >> 16]); + p[x + 4] = video_15to32[dat & 0xffff]; + p[x + 5] = video_15to32[dat >> 16]; dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]); - p[x + 6] = svga_color_transform(video_15to32[dat & 0xffff]); - p[x + 7] = svga_color_transform(video_15to32[dat >> 16]); + p[x + 6] = video_15to32[dat & 0xffff]; + p[x + 7] = video_15to32[dat >> 16]; } svga->ma += x << 1; svga->ma &= svga->vram_display_mask; @@ -718,13 +644,13 @@ void svga_render_16bpp_lowres(svga_t *svga) { uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - p[x] = svga_color_transform(video_16to32[dat & 0xffff]); - p[x + 1] = svga_color_transform(video_16to32[dat >> 16]); + p[x] = video_16to32[dat & 0xffff]; + p[x + 1] = video_16to32[dat >> 16]; dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - p[x] = svga_color_transform(video_16to32[dat & 0xffff]); - p[x + 1] = svga_color_transform(video_16to32[dat >> 16]); + p[x] = video_16to32[dat & 0xffff]; + p[x + 1] = video_16to32[dat >> 16]; } svga->ma += x << 1; svga->ma &= svga->vram_display_mask; @@ -749,20 +675,20 @@ void svga_render_16bpp_highres(svga_t *svga) for (x = 0; x <= svga->hdisp; x += 8) { uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - p[x] = svga_color_transform(video_16to32[dat & 0xffff]); - p[x + 1] = svga_color_transform(video_16to32[dat >> 16]); + p[x] = video_16to32[dat & 0xffff]; + p[x + 1] = video_16to32[dat >> 16]; dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - p[x + 2] = svga_color_transform(video_16to32[dat & 0xffff]); - p[x + 3] = svga_color_transform(video_16to32[dat >> 16]); + p[x + 2] = video_16to32[dat & 0xffff]; + p[x + 3] = video_16to32[dat >> 16]; dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]); - p[x + 4] = svga_color_transform(video_16to32[dat & 0xffff]); - p[x + 5] = svga_color_transform(video_16to32[dat >> 16]); + p[x + 4] = video_16to32[dat & 0xffff]; + p[x + 5] = video_16to32[dat >> 16]; dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]); - p[x + 6] = svga_color_transform(video_16to32[dat & 0xffff]); - p[x + 7] = svga_color_transform(video_16to32[dat >> 16]); + p[x + 6] = video_16to32[dat & 0xffff]; + p[x + 7] = video_16to32[dat >> 16]; } svga->ma += x << 1; svga->ma &= svga->vram_display_mask; @@ -790,7 +716,7 @@ void svga_render_24bpp_lowres(svga_t *svga) fg = svga->vram[svga->ma] | (svga->vram[svga->ma + 1] << 8) | (svga->vram[svga->ma + 2] << 16); svga->ma += 3; svga->ma &= svga->vram_display_mask; - ((uint32_t *)buffer32->line[svga->displine + y_add])[(x << 1) + offset + x_add] = ((uint32_t *)buffer32->line[svga->displine + y_add])[(x << 1) + 1 + offset + x_add] = svga_color_transform(fg); + ((uint32_t *)buffer32->line[svga->displine + y_add])[(x << 1) + offset + x_add] = ((uint32_t *)buffer32->line[svga->displine + y_add])[(x << 1) + 1 + offset + x_add] = fg; } } } @@ -813,16 +739,16 @@ void svga_render_24bpp_highres(svga_t *svga) for (x = 0; x <= svga->hdisp; x += 4) { uint32_t dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); - p[x] = svga_color_transform(dat & 0xffffff); + p[x] = dat & 0xffffff; dat = *(uint32_t *)(&svga->vram[(svga->ma + 3) & svga->vram_display_mask]); - p[x + 1] = svga_color_transform(dat & 0xffffff); + p[x + 1] = dat & 0xffffff; dat = *(uint32_t *)(&svga->vram[(svga->ma + 6) & svga->vram_display_mask]); - p[x + 2] = svga_color_transform(dat & 0xffffff); + p[x + 2] = dat & 0xffffff; dat = *(uint32_t *)(&svga->vram[(svga->ma + 9) & svga->vram_display_mask]); - p[x + 3] = svga_color_transform(dat & 0xffffff); + p[x + 3] = dat & 0xffffff; svga->ma += 12; } @@ -851,7 +777,7 @@ void svga_render_32bpp_lowres(svga_t *svga) fg = svga->vram[svga->ma] | (svga->vram[svga->ma + 1] << 8) | (svga->vram[svga->ma + 2] << 16); svga->ma += 4; svga->ma &= svga->vram_display_mask; - ((uint32_t *)buffer32->line[svga->displine + y_add])[(x << 1) + offset + x_add] = ((uint32_t *)buffer32->line[svga->displine + y_add])[(x << 1) + 1 + offset + x_add] = svga_color_transform(fg); + ((uint32_t *)buffer32->line[svga->displine + y_add])[(x << 1) + offset + x_add] = ((uint32_t *)buffer32->line[svga->displine + y_add])[(x << 1) + 1 + offset + x_add] = fg; } } } @@ -876,7 +802,7 @@ void svga_render_32bpp_highres(svga_t *svga) for (x = 0; x <= svga->hdisp; x++) { uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); - p[x] = svga_color_transform(dat & 0xffffff); + p[x] = dat & 0xffffff; } svga->ma += 4; svga->ma &= svga->vram_display_mask; @@ -901,7 +827,7 @@ void svga_render_ABGR8888_highres(svga_t *svga) for (x = 0; x <= svga->hdisp; x++) { uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); - p[x] = svga_color_transform((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16); + p[x] = ((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16); } svga->ma += 4; svga->ma &= svga->vram_display_mask; @@ -926,7 +852,7 @@ void svga_render_RGBA8888_highres(svga_t *svga) for (x = 0; x <= svga->hdisp; x++) { uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); - p[x] = svga_color_transform(dat >> 8); + p[x] = dat >> 8; } svga->ma += 4; svga->ma &= svga->vram_display_mask; diff --git a/src/video/video.c b/src/video/video.c index 4fae30a43..ae7085e96 100644 --- a/src/video/video.c +++ b/src/video/video.c @@ -40,7 +40,7 @@ * W = 3 bus clocks * L = 4 bus clocks * - * Version: @(#)video.c 1.0.22 2018/04/29 + * Version: @(#)video.c 1.0.23 2018/05/25 * * Authors: Sarah Walker, * Miran Grca, @@ -106,15 +106,12 @@ int video_timing_write_b = 0, int video_res_x = 0, video_res_y = 0, video_bpp = 0; -int video_timing[6][4] = { - { VIDEO_ISA, 8, 16, 32 }, - { VIDEO_ISA, 6, 8, 16 }, - { VIDEO_ISA, 3, 3, 6 }, - { VIDEO_BUS, 4, 8, 16 }, - { VIDEO_BUS, 4, 5, 10 }, - { VIDEO_BUS, 3, 3, 4 } -}; static int video_force_resize; +int invert_display = 0; +int video_grayscale = 0; +int video_graytype = 0; + + PALETTE cgapal = { {0,0,0}, {0,42,0}, {42,0,0}, {42,21,0}, {0,0,0}, {0,42,42}, {42,0,42}, {42,42,42}, @@ -182,6 +179,67 @@ PALETTE cgapal_mono[6] = { }; +const uint32_t shade[5][256] = +{ + {0}, // RGB Color (unused) + {0}, // RGB Grayscale (unused) + { // Amber monitor + 0x000000, 0x060000, 0x090000, 0x0d0000, 0x100000, 0x120100, 0x150100, 0x170100, 0x1a0100, 0x1c0100, 0x1e0200, 0x210200, 0x230200, 0x250300, 0x270300, 0x290300, + 0x2b0400, 0x2d0400, 0x2f0400, 0x300500, 0x320500, 0x340500, 0x360600, 0x380600, 0x390700, 0x3b0700, 0x3d0700, 0x3f0800, 0x400800, 0x420900, 0x440900, 0x450a00, + 0x470a00, 0x480b00, 0x4a0b00, 0x4c0c00, 0x4d0c00, 0x4f0d00, 0x500d00, 0x520e00, 0x530e00, 0x550f00, 0x560f00, 0x581000, 0x591000, 0x5b1100, 0x5c1200, 0x5e1200, + 0x5f1300, 0x601300, 0x621400, 0x631500, 0x651500, 0x661600, 0x671600, 0x691700, 0x6a1800, 0x6c1800, 0x6d1900, 0x6e1a00, 0x701a00, 0x711b00, 0x721c00, 0x741c00, + 0x751d00, 0x761e00, 0x781e00, 0x791f00, 0x7a2000, 0x7c2000, 0x7d2100, 0x7e2200, 0x7f2300, 0x812300, 0x822400, 0x832500, 0x842600, 0x862600, 0x872700, 0x882800, + 0x8a2900, 0x8b2900, 0x8c2a00, 0x8d2b00, 0x8e2c00, 0x902c00, 0x912d00, 0x922e00, 0x932f00, 0x953000, 0x963000, 0x973100, 0x983200, 0x993300, 0x9b3400, 0x9c3400, + 0x9d3500, 0x9e3600, 0x9f3700, 0xa03800, 0xa23900, 0xa33a00, 0xa43a00, 0xa53b00, 0xa63c00, 0xa73d00, 0xa93e00, 0xaa3f00, 0xab4000, 0xac4000, 0xad4100, 0xae4200, + 0xaf4300, 0xb14400, 0xb24500, 0xb34600, 0xb44700, 0xb54800, 0xb64900, 0xb74a00, 0xb94a00, 0xba4b00, 0xbb4c00, 0xbc4d00, 0xbd4e00, 0xbe4f00, 0xbf5000, 0xc05100, + 0xc15200, 0xc25300, 0xc45400, 0xc55500, 0xc65600, 0xc75700, 0xc85800, 0xc95900, 0xca5a00, 0xcb5b00, 0xcc5c00, 0xcd5d00, 0xce5e00, 0xcf5f00, 0xd06000, 0xd26101, + 0xd36201, 0xd46301, 0xd56401, 0xd66501, 0xd76601, 0xd86701, 0xd96801, 0xda6901, 0xdb6a01, 0xdc6b01, 0xdd6c01, 0xde6d01, 0xdf6e01, 0xe06f01, 0xe17001, 0xe27201, + 0xe37301, 0xe47401, 0xe57501, 0xe67602, 0xe77702, 0xe87802, 0xe97902, 0xeb7a02, 0xec7b02, 0xed7c02, 0xee7e02, 0xef7f02, 0xf08002, 0xf18103, 0xf28203, 0xf38303, + 0xf48403, 0xf58503, 0xf68703, 0xf78803, 0xf88903, 0xf98a04, 0xfa8b04, 0xfb8c04, 0xfc8d04, 0xfd8f04, 0xfe9005, 0xff9105, 0xff9205, 0xff9305, 0xff9405, 0xff9606, + 0xff9706, 0xff9806, 0xff9906, 0xff9a07, 0xff9b07, 0xff9d07, 0xff9e08, 0xff9f08, 0xffa008, 0xffa109, 0xffa309, 0xffa409, 0xffa50a, 0xffa60a, 0xffa80a, 0xffa90b, + 0xffaa0b, 0xffab0c, 0xffac0c, 0xffae0d, 0xffaf0d, 0xffb00e, 0xffb10e, 0xffb30f, 0xffb40f, 0xffb510, 0xffb610, 0xffb811, 0xffb912, 0xffba12, 0xffbb13, 0xffbd14, + 0xffbe14, 0xffbf15, 0xffc016, 0xffc217, 0xffc317, 0xffc418, 0xffc619, 0xffc71a, 0xffc81b, 0xffca1c, 0xffcb1d, 0xffcc1e, 0xffcd1f, 0xffcf20, 0xffd021, 0xffd122, + 0xffd323, 0xffd424, 0xffd526, 0xffd727, 0xffd828, 0xffd92a, 0xffdb2b, 0xffdc2c, 0xffdd2e, 0xffdf2f, 0xffe031, 0xffe133, 0xffe334, 0xffe436, 0xffe538, 0xffe739 + }, + { // Green monitor + 0x000000, 0x000400, 0x000700, 0x000900, 0x000b00, 0x000d00, 0x000f00, 0x001100, 0x001300, 0x001500, 0x001600, 0x001800, 0x001a00, 0x001b00, 0x001d00, 0x001e00, + 0x002000, 0x002100, 0x002300, 0x002400, 0x002601, 0x002701, 0x002901, 0x002a01, 0x002b01, 0x002d01, 0x002e01, 0x002f01, 0x003101, 0x003201, 0x003301, 0x003401, + 0x003601, 0x003702, 0x003802, 0x003902, 0x003b02, 0x003c02, 0x003d02, 0x003e02, 0x004002, 0x004102, 0x004203, 0x004303, 0x004403, 0x004503, 0x004703, 0x004803, + 0x004903, 0x004a03, 0x004b04, 0x004c04, 0x004d04, 0x004e04, 0x005004, 0x005104, 0x005205, 0x005305, 0x005405, 0x005505, 0x005605, 0x005705, 0x005806, 0x005906, + 0x005a06, 0x005b06, 0x005d06, 0x005e07, 0x005f07, 0x006007, 0x006107, 0x006207, 0x006308, 0x006408, 0x006508, 0x006608, 0x006708, 0x006809, 0x006909, 0x006a09, + 0x006b09, 0x016c0a, 0x016d0a, 0x016e0a, 0x016f0a, 0x01700b, 0x01710b, 0x01720b, 0x01730b, 0x01740c, 0x01750c, 0x01760c, 0x01770c, 0x01780d, 0x01790d, 0x017a0d, + 0x017b0d, 0x017b0e, 0x017c0e, 0x017d0e, 0x017e0f, 0x017f0f, 0x01800f, 0x018110, 0x028210, 0x028310, 0x028410, 0x028511, 0x028611, 0x028711, 0x028812, 0x028912, + 0x028a12, 0x028a13, 0x028b13, 0x028c13, 0x028d14, 0x028e14, 0x038f14, 0x039015, 0x039115, 0x039215, 0x039316, 0x039416, 0x039417, 0x039517, 0x039617, 0x039718, + 0x049818, 0x049918, 0x049a19, 0x049b19, 0x049c19, 0x049c1a, 0x049d1a, 0x049e1b, 0x059f1b, 0x05a01b, 0x05a11c, 0x05a21c, 0x05a31c, 0x05a31d, 0x05a41d, 0x06a51e, + 0x06a61e, 0x06a71f, 0x06a81f, 0x06a920, 0x06aa20, 0x07aa21, 0x07ab21, 0x07ac21, 0x07ad22, 0x07ae22, 0x08af23, 0x08b023, 0x08b024, 0x08b124, 0x08b225, 0x09b325, + 0x09b426, 0x09b526, 0x09b527, 0x0ab627, 0x0ab728, 0x0ab828, 0x0ab929, 0x0bba29, 0x0bba2a, 0x0bbb2a, 0x0bbc2b, 0x0cbd2b, 0x0cbe2c, 0x0cbf2c, 0x0dbf2d, 0x0dc02d, + 0x0dc12e, 0x0ec22e, 0x0ec32f, 0x0ec42f, 0x0fc430, 0x0fc530, 0x0fc631, 0x10c731, 0x10c832, 0x10c932, 0x11c933, 0x11ca33, 0x11cb34, 0x12cc35, 0x12cd35, 0x12cd36, + 0x13ce36, 0x13cf37, 0x13d037, 0x14d138, 0x14d139, 0x14d239, 0x15d33a, 0x15d43a, 0x16d43b, 0x16d53b, 0x17d63c, 0x17d73d, 0x17d83d, 0x18d83e, 0x18d93e, 0x19da3f, + 0x19db40, 0x1adc40, 0x1adc41, 0x1bdd41, 0x1bde42, 0x1cdf43, 0x1ce043, 0x1de044, 0x1ee145, 0x1ee245, 0x1fe346, 0x1fe446, 0x20e447, 0x20e548, 0x21e648, 0x22e749, + 0x22e74a, 0x23e84a, 0x23e94b, 0x24ea4c, 0x25ea4c, 0x25eb4d, 0x26ec4e, 0x27ed4e, 0x27ee4f, 0x28ee50, 0x29ef50, 0x29f051, 0x2af152, 0x2bf153, 0x2cf253, 0x2cf354, + 0x2df455, 0x2ef455, 0x2ff556, 0x2ff657, 0x30f758, 0x31f758, 0x32f859, 0x32f95a, 0x33fa5a, 0x34fa5b, 0x35fb5c, 0x36fc5d, 0x37fd5d, 0x38fd5e, 0x38fe5f, 0x39ff60 + }, + { // White monitor + 0x000000, 0x010102, 0x020203, 0x020304, 0x030406, 0x040507, 0x050608, 0x060709, 0x07080a, 0x08090c, 0x080a0d, 0x090b0e, 0x0a0c0f, 0x0b0d10, 0x0c0e11, 0x0d0f12, + 0x0e1013, 0x0f1115, 0x101216, 0x111317, 0x121418, 0x121519, 0x13161a, 0x14171b, 0x15181c, 0x16191d, 0x171a1e, 0x181b1f, 0x191c20, 0x1a1d21, 0x1b1e22, 0x1c1f23, + 0x1d2024, 0x1e2125, 0x1f2226, 0x202327, 0x212428, 0x222529, 0x22262b, 0x23272c, 0x24282d, 0x25292e, 0x262a2f, 0x272b30, 0x282c30, 0x292d31, 0x2a2e32, 0x2b2f33, + 0x2c3034, 0x2d3035, 0x2e3136, 0x2f3237, 0x303338, 0x313439, 0x32353a, 0x33363b, 0x34373c, 0x35383d, 0x36393e, 0x373a3f, 0x383b40, 0x393c41, 0x3a3d42, 0x3b3e43, + 0x3c3f44, 0x3d4045, 0x3e4146, 0x3f4247, 0x404348, 0x414449, 0x42454a, 0x43464b, 0x44474c, 0x45484d, 0x46494d, 0x474a4e, 0x484b4f, 0x484c50, 0x494d51, 0x4a4e52, + 0x4b4f53, 0x4c5054, 0x4d5155, 0x4e5256, 0x4f5357, 0x505458, 0x515559, 0x52565a, 0x53575b, 0x54585b, 0x55595c, 0x565a5d, 0x575b5e, 0x585c5f, 0x595d60, 0x5a5e61, + 0x5b5f62, 0x5c6063, 0x5d6164, 0x5e6265, 0x5f6366, 0x606466, 0x616567, 0x626668, 0x636769, 0x64686a, 0x65696b, 0x666a6c, 0x676b6d, 0x686c6e, 0x696d6f, 0x6a6e70, + 0x6b6f70, 0x6c7071, 0x6d7172, 0x6f7273, 0x707374, 0x707475, 0x717576, 0x727677, 0x747778, 0x757879, 0x767979, 0x777a7a, 0x787b7b, 0x797c7c, 0x7a7d7d, 0x7b7e7e, + 0x7c7f7f, 0x7d8080, 0x7e8181, 0x7f8281, 0x808382, 0x818483, 0x828584, 0x838685, 0x848786, 0x858887, 0x868988, 0x878a89, 0x888b89, 0x898c8a, 0x8a8d8b, 0x8b8e8c, + 0x8c8f8d, 0x8d8f8e, 0x8e908f, 0x8f9190, 0x909290, 0x919391, 0x929492, 0x939593, 0x949694, 0x959795, 0x969896, 0x979997, 0x989a98, 0x999b98, 0x9a9c99, 0x9b9d9a, + 0x9c9e9b, 0x9d9f9c, 0x9ea09d, 0x9fa19e, 0xa0a29f, 0xa1a39f, 0xa2a4a0, 0xa3a5a1, 0xa4a6a2, 0xa6a7a3, 0xa7a8a4, 0xa8a9a5, 0xa9aaa5, 0xaaaba6, 0xabaca7, 0xacada8, + 0xadaea9, 0xaeafaa, 0xafb0ab, 0xb0b1ac, 0xb1b2ac, 0xb2b3ad, 0xb3b4ae, 0xb4b5af, 0xb5b6b0, 0xb6b7b1, 0xb7b8b2, 0xb8b9b2, 0xb9bab3, 0xbabbb4, 0xbbbcb5, 0xbcbdb6, + 0xbdbeb7, 0xbebfb8, 0xbfc0b8, 0xc0c1b9, 0xc1c2ba, 0xc2c3bb, 0xc3c4bc, 0xc5c5bd, 0xc6c6be, 0xc7c7be, 0xc8c8bf, 0xc9c9c0, 0xcacac1, 0xcbcbc2, 0xccccc3, 0xcdcdc3, + 0xcecec4, 0xcfcfc5, 0xd0d0c6, 0xd1d1c7, 0xd2d2c8, 0xd3d3c9, 0xd4d4c9, 0xd5d5ca, 0xd6d6cb, 0xd7d7cc, 0xd8d8cd, 0xd9d9ce, 0xdadacf, 0xdbdbcf, 0xdcdcd0, 0xdeddd1, + 0xdfded2, 0xe0dfd3, 0xe1e0d4, 0xe2e1d4, 0xe3e2d5, 0xe4e3d6, 0xe5e4d7, 0xe6e5d8, 0xe7e6d9, 0xe8e7d9, 0xe9e8da, 0xeae9db, 0xebeadc, 0xecebdd, 0xedecde, 0xeeeddf, + 0xefeedf, 0xf0efe0, 0xf1f0e1, 0xf2f1e2, 0xf3f2e3, 0xf4f3e3, 0xf6f3e4, 0xf7f4e5, 0xf8f5e6, 0xf9f6e7, 0xfaf7e8, 0xfbf8e9, 0xfcf9e9, 0xfdfaea, 0xfefbeb, 0xfffcec + } +}; + + static struct { int x, y, y1, y2, w, h; int busy; @@ -361,94 +419,76 @@ video_update_timing(void) video_timings_t *timing; int new_gfxcard; - if (video_speed == -1) { - new_gfxcard = 0; + new_gfxcard = 0; - switch(romset) { - case ROM_IBMPCJR: - case ROM_TANDY: - case ROM_TANDY1000HX: - case ROM_TANDY1000SL2: - timing = &timing_dram; - break; - case ROM_PC1512: - timing = &timing_pc1512; - break; - case ROM_PC1640: - timing = &timing_pc1640; - break; - case ROM_PC200: - timing = &timing_pc200; - break; - case ROM_OLIM24: - timing = &timing_m24; - break; - case ROM_PC2086: - case ROM_PC3086: - timing = &timing_pvga1a; - break; - case ROM_T1000: - case ROM_T1200: - timing = &timing_t1000; - break; - case ROM_MEGAPC: - case ROM_MEGAPCDX: - timing = &timing_wd90c11; - break; - case ROM_IBMPS1_2011: - case ROM_IBMPS2_M30_286: - case ROM_IBMPS2_M50: - case ROM_IBMPS2_M55SX: - case ROM_IBMPS2_M80: - timing = &timing_vga; - break; - case ROM_IBMPS1_2121: - case ROM_IBMPS1_2133: - timing = &timing_ps1_svga; - break; - case ROM_T3100E: - timing = &timing_t3100e; - break; - case ROM_ENDEAVOR: - timing = &timing_endeavor; - break; - default: - new_gfxcard = video_old_to_new(gfxcard); - timing = video_card_gettiming(new_gfxcard); - break; - } + switch(romset) { + case ROM_IBMPCJR: + case ROM_TANDY: + case ROM_TANDY1000HX: + case ROM_TANDY1000SL2: + timing = &timing_dram; + break; + case ROM_PC1512: + timing = &timing_pc1512; + break; + case ROM_PC1640: + timing = &timing_pc1640; + break; + case ROM_PC200: + timing = &timing_pc200; + break; + case ROM_OLIM24: + timing = &timing_m24; + break; + case ROM_PC2086: + case ROM_PC3086: + timing = &timing_pvga1a; + break; + case ROM_T1000: + case ROM_T1200: + timing = &timing_t1000; + break; + case ROM_MEGAPC: + case ROM_MEGAPCDX: + timing = &timing_wd90c11; + break; + case ROM_IBMPS1_2011: + case ROM_IBMPS2_M30_286: + case ROM_IBMPS2_M50: + case ROM_IBMPS2_M55SX: + case ROM_IBMPS2_M80: + timing = &timing_vga; + break; + case ROM_IBMPS1_2121: + case ROM_IBMPS1_2133: + timing = &timing_ps1_svga; + break; + case ROM_T3100E: + timing = &timing_t3100e; + break; + case ROM_ENDEAVOR: + timing = &timing_endeavor; + break; + default: + new_gfxcard = video_old_to_new(gfxcard); + timing = video_card_gettiming(new_gfxcard); + break; + } - if (timing->type == VIDEO_ISA) { - video_timing_read_b = ISA_CYCLES(timing->read_b); - video_timing_read_w = ISA_CYCLES(timing->read_w); - video_timing_read_l = ISA_CYCLES(timing->read_l); - video_timing_write_b = ISA_CYCLES(timing->write_b); - video_timing_write_w = ISA_CYCLES(timing->write_w); - video_timing_write_l = ISA_CYCLES(timing->write_l); - } else { - video_timing_read_b = (int)(bus_timing * timing->read_b); - video_timing_read_w = (int)(bus_timing * timing->read_w); - video_timing_read_l = (int)(bus_timing * timing->read_l); - video_timing_write_b = (int)(bus_timing * timing->write_b); - video_timing_write_w = (int)(bus_timing * timing->write_w); - video_timing_write_l = (int)(bus_timing * timing->write_l); - } - } else { - if (video_timing[video_speed][0] == VIDEO_ISA) { - video_timing_read_b = ISA_CYCLES(video_timing[video_speed][1]); - video_timing_read_w = ISA_CYCLES(video_timing[video_speed][2]); - video_timing_read_l = ISA_CYCLES(video_timing[video_speed][3]); - video_timing_write_b = ISA_CYCLES(video_timing[video_speed][1]); - video_timing_write_w = ISA_CYCLES(video_timing[video_speed][2]); - video_timing_write_l = ISA_CYCLES(video_timing[video_speed][3]); - } else { - video_timing_read_b = (int)(bus_timing * video_timing[video_speed][1]); - video_timing_read_w = (int)(bus_timing * video_timing[video_speed][2]); - video_timing_read_l = (int)(bus_timing * video_timing[video_speed][3]); - video_timing_write_b = (int)(bus_timing * video_timing[video_speed][1]); - video_timing_write_w = (int)(bus_timing * video_timing[video_speed][2]); - video_timing_write_l = (int)(bus_timing * video_timing[video_speed][3]); - } + if (timing->type == VIDEO_ISA) { + video_timing_read_b = ISA_CYCLES(timing->read_b); + video_timing_read_w = ISA_CYCLES(timing->read_w); + video_timing_read_l = ISA_CYCLES(timing->read_l); + video_timing_write_b = ISA_CYCLES(timing->write_b); + video_timing_write_w = ISA_CYCLES(timing->write_w); + video_timing_write_l = ISA_CYCLES(timing->write_l); + } else { + video_timing_read_b = (int)(bus_timing * timing->read_b); + video_timing_read_w = (int)(bus_timing * timing->read_w); + video_timing_read_l = (int)(bus_timing * timing->read_l); + video_timing_write_b = (int)(bus_timing * timing->write_b); + video_timing_write_w = (int)(bus_timing * timing->write_w); + video_timing_write_l = (int)(bus_timing * timing->write_l); } if (cpu_16bitbus) { @@ -790,3 +830,46 @@ loadfont(wchar_t *s, int format) (void)fclose(f); } + + +uint32_t +video_color_transform(uint32_t color) +{ + uint8_t *clr8 = (uint8_t *) &color; + /* if (!video_grayscale && !invert_display) + return color; */ + if (video_grayscale) { + if (video_graytype) { + if (video_graytype == 1) + color = ((54 * (uint32_t)clr8[2]) + (183 * (uint32_t)clr8[1]) + (18 * (uint32_t)clr8[0])) / 255; + else + color = ((uint32_t)clr8[2] + (uint32_t)clr8[1] + (uint32_t)clr8[0]) / 3; + } else + color = ((76 * (uint32_t)clr8[2]) + (150 * (uint32_t)clr8[1]) + (29 * (uint32_t)clr8[0])) / 255; + switch (video_grayscale) { + case 2: case 3: case 4: + color = (uint32_t) shade[video_grayscale][color]; + break; + default: + clr8[3] = 0; + clr8[0] = color; + clr8[1] = clr8[2] = clr8[0]; + break; + } + } + if (invert_display) + color ^= 0x00ffffff; + return color; +} + +void +video_transform_copy(uint32_t *dst, uint32_t *src, int len) +{ + int i; + + for (i = 0; i < len; i++) { + *dst = video_color_transform(*src); + dst++; + src++; + } +} diff --git a/src/video/video.h b/src/video/video.h index 2e9e7edff..fcbe160e0 100644 --- a/src/video/video.h +++ b/src/video/video.h @@ -8,7 +8,7 @@ * * Definitions for the video controller module. * - * Version: @(#)video.h 1.0.27 2018/05/20 + * Version: @(#)video.h 1.0.28 2018/05/25 * * Authors: Sarah Walker, * Miran Grca, @@ -194,7 +194,6 @@ extern int video_timing_read_b, extern int video_timing_write_b, video_timing_write_w, video_timing_write_l; -extern int video_speed; extern int video_res_x, video_res_y, video_bpp; @@ -261,6 +260,9 @@ extern int get_actual_size_y(void); extern void svga_dump_vram(void); #endif +extern uint32_t video_color_transform(uint32_t color); +extern void video_transform_copy(uint32_t *dst, uint32_t *src, int len); + #ifdef __cplusplus } #endif diff --git a/src/vnc.c b/src/vnc.c index 5c5d996e4..8ee76bea6 100644 --- a/src/vnc.c +++ b/src/vnc.c @@ -8,7 +8,7 @@ * * Implement the VNC remote renderer with LibVNCServer. * - * Version: @(#)vnc.c 1.0.11 2018/04/29 + * Version: @(#)vnc.c 1.0.12 2018/05/26 * * Authors: Fred N. van Kempen, * Based on raw code by RichardG, @@ -169,14 +169,18 @@ vnc_display(rfbClientPtr cl) static void vnc_blit(int x, int y, int y1, int y2, int w, int h) { - uint32_t *p; + uint32_t *p, *q; int yy; for (yy=y1; yyframeBuffer)[yy*VNC_MAX_X]); - if ((y+yy) >= 0 && (y+yy) < VNC_MAX_Y) - memcpy(p, &(((uint32_t *)buffer32->line[y+yy])[x]), w*4); + if ((y+yy) >= 0 && (y+yy) < VNC_MAX_Y) { + if (video_grayscale || invert_display) + video_transform_copy(p, &(((uint32_t *)buffer32->line[y+yy])[x]), w); + else + memcpy(p, &(((uint32_t *)buffer32->line[y+yy])[x]), w*4); + } } video_blit_complete(); diff --git a/src/win/86Box.rc b/src/win/86Box.rc index 8555f607e..4312bb3d8 100644 --- a/src/win/86Box.rc +++ b/src/win/86Box.rc @@ -8,7 +8,7 @@ * * Application resource script for Windows. * - * Version: @(#)86Box.rc 1.0.36 2018/05/01 + * Version: @(#)86Box.rc 1.0.37 2018/05/25 * * Authors: Miran Grca, * Fred N. van Kempen, @@ -34,7 +34,7 @@ #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) #ifdef _WIN32 LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -#pragma code_page(1252) +#pragma code_page(65001) #endif //_WIN32 ///////////////////////////////////////////////////////////////////////////// @@ -66,11 +66,9 @@ BEGIN BEGIN MENUITEM "&DirectDraw", IDM_VID_DDRAW MENUITEM "Direct&3D 9", IDM_VID_D3D + MENUITEM "&SDL", IDM_VID_SDL #ifdef USE_VNC MENUITEM "&VNC", IDM_VID_VNC -#endif -#ifdef USE_RDP - MENUITEM "&RDP", IDM_VID_RDP #endif END MENUITEM SEPARATOR @@ -325,7 +323,7 @@ BEGIN #endif END -DLG_CFG_VIDEO DIALOG DISCARDABLE 97, 0, 267, 63 +DLG_CFG_VIDEO DIALOG DISCARDABLE 97, 0, 267, 45 STYLE DS_CONTROL | WS_CHILD FONT 9, "Segoe UI" BEGIN @@ -333,12 +331,9 @@ BEGIN COMBOBOX IDC_COMBO_VIDEO,71,7,140,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP PUSHBUTTON "Configure",IDC_CONFIGURE_VID,214,7,46,12 - COMBOBOX IDC_COMBO_VIDEO_SPEED,71,25,189,120,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - LTEXT "Video speed:",IDT_1708,7,26,58,10 CONTROL "Voodoo Graphics",IDC_CHECK_VOODOO,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,7,45,199,10 - PUSHBUTTON "Configure",IDC_BUTTON_VOODOO,214,44,46,12 + BS_AUTOCHECKBOX | WS_TABSTOP,7,27,199,10 + PUSHBUTTON "Configure",IDC_BUTTON_VOODOO,214,26,46,12 END DLG_CFG_INPUT DIALOG DISCARDABLE 97, 0, 267, 65 @@ -476,12 +471,9 @@ BEGIN COMBOBOX IDC_COMBO_HD_CHANNEL,170,117,90,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "Channel:",IDT_1722,131,119,38,8 - COMBOBOX IDC_COMBO_HD_ID,170,117,22,12,CBS_DROPDOWNLIST | + COMBOBOX IDC_COMBO_HD_ID,170,117,90,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "ID:",IDT_1723,131,119,38,8 - COMBOBOX IDC_COMBO_HD_LUN,239,117,22,12,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - LTEXT "LUN:",IDT_1724,200,119,38,8 COMBOBOX IDC_COMBO_HD_CHANNEL_IDE,170,117,90,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP END @@ -513,12 +505,9 @@ BEGIN COMBOBOX IDC_COMBO_HD_CHANNEL,134,71,77,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "Channel:",IDT_1722,99,73,34,8 - COMBOBOX IDC_COMBO_HD_ID,133,71,26,12,CBS_DROPDOWNLIST | + COMBOBOX IDC_COMBO_HD_ID,134,71,77,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "ID:",IDT_1723,117,73,15,8 - COMBOBOX IDC_COMBO_HD_LUN,185,71,26,12,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - LTEXT "LUN:",IDT_1724,168,73,15,8 + LTEXT "ID:",IDT_1723,99,73,34,8 COMBOBOX IDC_COMBO_HD_CHANNEL_IDE,134,71,77,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "Progress:",IDT_1752,7,7,204,9 @@ -554,15 +543,12 @@ BEGIN COMBOBOX IDC_COMBO_CD_BUS,33,85,90,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "Bus:",IDT_1740,7,87,24,8 - COMBOBOX IDC_COMBO_CD_ID,170,85,22,12,CBS_DROPDOWNLIST | + COMBOBOX IDC_COMBO_CD_ID,170,85,90,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "ID:",IDT_1741,131,87,38,8 - COMBOBOX IDC_COMBO_CD_LUN,239,85,22,12,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - LTEXT "LUN:",IDT_1742,200,87,38,8 COMBOBOX IDC_COMBO_CD_CHANNEL_IDE,170,85,90,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Channel:",IDT_1743,131,87,38,8 + LTEXT "Channel:",IDT_1742,131,87,38,8 COMBOBOX IDC_COMBO_CD_SPEED,33,105,90,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "Speed:",IDT_1758,7,107,24,8 @@ -570,20 +556,17 @@ BEGIN LVS_SHOWSELALWAYS | LVS_SINGLESEL | WS_BORDER | WS_TABSTOP,7,137,253,60 LTEXT "ZIP drives:",IDT_1759,7,127,50,8 - COMBOBOX IDC_COMBO_ZIP_BUS,73,204,90,12,CBS_DROPDOWNLIST | + COMBOBOX IDC_COMBO_ZIP_BUS,23,204,90,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Bus:",IDT_1753,57,206,14,8 - COMBOBOX IDC_COMBO_ZIP_ID,190,204,22,12,CBS_DROPDOWNLIST | + LTEXT "Bus:",IDT_1753,7,206,14,8 + COMBOBOX IDC_COMBO_ZIP_ID,139,204,61,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "ID:",IDT_1754,171,206,18,8 - COMBOBOX IDC_COMBO_ZIP_LUN,239,204,22,12,CBS_DROPDOWNLIST | + LTEXT "ID:",IDT_1754,120,206,28,8 + COMBOBOX IDC_COMBO_ZIP_CHANNEL_IDE,149,204,61,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "LUN:",IDT_1755,220,206,18,8 - COMBOBOX IDC_COMBO_ZIP_CHANNEL_IDE,200,204,60,12,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - LTEXT "Channel:",IDT_1756,171,206,28,8 + LTEXT "Channel:",IDT_1755,120,206,28,8 CONTROL "ZIP 250",IDC_CHECK250,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,7,204,44,10 + BS_AUTOCHECKBOX | WS_TABSTOP,218,204,44,10 END @@ -603,42 +586,42 @@ END // remains consistent on all systems. #ifdef RELEASE_BUILD /* Icon by Devcore - https://commons.wikimedia.org/wiki/File:Icon_PC_256x256.png */ -100 ICON DISCARDABLE "win/icons/86Box-RB.ico" + 10 ICON DISCARDABLE "win/icons/86Box-RB.ico" #else /* Icon by Devcore - https://commons.wikimedia.org/wiki/File:Icon_PC2_256x256.png */ -100 ICON DISCARDABLE "win/icons/86Box.ico" + 10 ICON DISCARDABLE "win/icons/86Box.ico" #endif -128 ICON DISCARDABLE "win/icons/floppy_525.ico" -129 ICON DISCARDABLE "win/icons/floppy_525_active.ico" -144 ICON DISCARDABLE "win/icons/floppy_35.ico" -145 ICON DISCARDABLE "win/icons/floppy_35_active.ico" -160 ICON DISCARDABLE "win/icons/cdrom.ico" -161 ICON DISCARDABLE "win/icons/cdrom_active.ico" -176 ICON DISCARDABLE "win/icons/zip.ico" -177 ICON DISCARDABLE "win/icons/zip_active.ico" -192 ICON DISCARDABLE "win/icons/hard_disk.ico" -193 ICON DISCARDABLE "win/icons/hard_disk_active.ico" -208 ICON DISCARDABLE "win/icons/network.ico" -209 ICON DISCARDABLE "win/icons/network_active.ico" -256 ICON DISCARDABLE "win/icons/machine.ico" -257 ICON DISCARDABLE "win/icons/display.ico" -258 ICON DISCARDABLE "win/icons/input_devices.ico" -259 ICON DISCARDABLE "win/icons/sound.ico" -261 ICON DISCARDABLE "win/icons/ports.ico" -262 ICON DISCARDABLE "win/icons/other_peripherals.ico" -264 ICON DISCARDABLE "win/icons/floppy_drives.ico" -265 ICON DISCARDABLE "win/icons/other_removable_devices.ico" -384 ICON DISCARDABLE "win/icons/floppy_525_empty.ico" -385 ICON DISCARDABLE "win/icons/floppy_525_empty_active.ico" -400 ICON DISCARDABLE "win/icons/floppy_35_empty.ico" -401 ICON DISCARDABLE "win/icons/floppy_35_empty_active.ico" -416 ICON DISCARDABLE "win/icons/cdrom_empty.ico" -417 ICON DISCARDABLE "win/icons/cdrom_empty_active.ico" -432 ICON DISCARDABLE "win/icons/zip_empty.ico" -433 ICON DISCARDABLE "win/icons/zip_empty_active.ico" -512 ICON DISCARDABLE "win/icons/floppy_disabled.ico" -514 ICON DISCARDABLE "win/icons/cdrom_disabled.ico" -515 ICON DISCARDABLE "win/icons/zip_disabled.ico" + 16 ICON DISCARDABLE "win/icons/floppy_525.ico" + 17 ICON DISCARDABLE "win/icons/floppy_525_active.ico" + 24 ICON DISCARDABLE "win/icons/floppy_35.ico" + 25 ICON DISCARDABLE "win/icons/floppy_35_active.ico" + 32 ICON DISCARDABLE "win/icons/cdrom.ico" + 33 ICON DISCARDABLE "win/icons/cdrom_active.ico" + 48 ICON DISCARDABLE "win/icons/zip.ico" + 49 ICON DISCARDABLE "win/icons/zip_active.ico" + 64 ICON DISCARDABLE "win/icons/hard_disk.ico" + 65 ICON DISCARDABLE "win/icons/hard_disk_active.ico" + 80 ICON DISCARDABLE "win/icons/network.ico" + 81 ICON DISCARDABLE "win/icons/network_active.ico" +144 ICON DISCARDABLE "win/icons/floppy_525_empty.ico" +145 ICON DISCARDABLE "win/icons/floppy_525_empty_active.ico" +152 ICON DISCARDABLE "win/icons/floppy_35_empty.ico" +153 ICON DISCARDABLE "win/icons/floppy_35_empty_active.ico" +160 ICON DISCARDABLE "win/icons/cdrom_empty.ico" +161 ICON DISCARDABLE "win/icons/cdrom_empty_active.ico" +176 ICON DISCARDABLE "win/icons/zip_empty.ico" +177 ICON DISCARDABLE "win/icons/zip_empty_active.ico" +240 ICON DISCARDABLE "win/icons/machine.ico" +241 ICON DISCARDABLE "win/icons/display.ico" +242 ICON DISCARDABLE "win/icons/input_devices.ico" +243 ICON DISCARDABLE "win/icons/sound.ico" +244 ICON DISCARDABLE "win/icons/ports.ico" +245 ICON DISCARDABLE "win/icons/other_peripherals.ico" +246 ICON DISCARDABLE "win/icons/floppy_drives.ico" +247 ICON DISCARDABLE "win/icons/other_removable_devices.ico" +248 ICON DISCARDABLE "win/icons/floppy_disabled.ico" +249 ICON DISCARDABLE "win/icons/cdrom_disabled.ico" +250 ICON DISCARDABLE "win/icons/zip_disabled.ico" #ifdef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// @@ -720,7 +703,7 @@ BEGIN LEFTMARGIN, 7 RIGHTMARGIN, 260 TOPMARGIN, 7 - BOTTOMMARGIN, 56 + BOTTOMMARGIN, 38 END DLG_CFG_INPUT, DIALOG @@ -801,17 +784,17 @@ BEGIN IDS_2049 "86Box Error" IDS_2050 "86Box Fatal Error" IDS_2051 "This will reset 86Box.\nAre you sure you want to save the settings?" - IDS_2052 "DirectDraw Screenshot Error" - IDS_2053 "Invalid number of sectors (valid values are between 1 and 63)" - IDS_2054 "Invalid number of heads (valid values are between 1 and 16)" - IDS_2055 "Invalid number of cylinders (valid values are between 1 and 266305)" + IDS_2052 "Use CTRL+ALT+PAGE DOWN to return to windowed mode" + IDS_2053 "Speed" + IDS_2054 "ZIP %03i %i (%s): %ls" + IDS_2055 "ZIP images (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0" IDS_2056 "No usable ROM images found!" IDS_2057 "(empty)" - IDS_2058 "(host drive %c:)" + IDS_2058 "ZIP images (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0All files (*.*)\0*.*\0" IDS_2059 "Turbo" IDS_2060 "On" IDS_2061 "Off" - IDS_2062 "86Box was unable to find any ROMs.\nAt least one ROM set is required to use 86Box." + IDS_2062 "All images (*.86F;*.DSK;*.FLP;*.IM?;*.*FD?)\0*.86F;*.DSK;*.FLP;*.IM?;*.*FD?\0Basic sector images (*.DSK;*.FLP;*.IM?;*.*FD?)\0*.DSK;*.FLP;*.IM?;*.IMG;*.*FD?\0Surface images (*.86F)\0*.86F\0" IDS_2063 "Configured ROM set not available.\nDefaulting to an available ROM set." END @@ -829,7 +812,7 @@ BEGIN IDS_2073 "Floppy drives" IDS_2074 "Other removable devices" IDS_2075 "CD-ROM images (*.ISO;*.CUE)\0*.ISO;*.CUE\0All files (*.*)\0*.*\0" - IDS_2076 "Host CD/DVD Drive (%c:)" + IDS_2076 "Surface images (*.86F)\0*.86F\0" IDS_2077 "Click to capture mouse" IDS_2078 "Press F8+F12 to release mouse" IDS_2079 "Press F8+F12 or middle button to release mouse" @@ -837,141 +820,67 @@ END STRINGTABLE DISCARDABLE BEGIN - IDS_2080 "Drive" - IDS_2081 "Location" + IDS_2080 "E&xport to 86F..." + IDS_2081 "Unable to initialize FluidSynth, make sure you have the following libraries\nin your 86Box folder:\n\nlibfluidsynth.dll\nlibglib-2.0-0.dll\nlibiconv-2.dll\nlibintl-8.dll\nlibpcre-1.dll" IDS_2082 "Bus" IDS_2083 "File" IDS_2084 "C" IDS_2085 "H" IDS_2086 "S" IDS_2087 "MB" - IDS_2088 "Unable to create bitmap file: %s" - IDS_2089 "Enabled" - IDS_2090 "Mute" - IDS_2091 "Type" - IDS_2092 "Bus" - IDS_2093 "DMA" + IDS_2088 "Check BPB" + IDS_2089 "&Image..." + IDS_2090 "&Reload previous image" + IDS_2091 "E&mpty" + IDS_2092 "&Mute" + IDS_2093 "E&ject" IDS_2094 "KB" IDS_2095 "Neither DirectDraw nor Direct3D available !" + IDS_2096 "&New image..." + IDS_2097 "&Existing image..." + IDS_2098 "Existing image (&Write-protected)..." + IDS_2099 "Default" + IDS_2100 "%i Wait state(s)" + IDS_2101 "Type" + IDS_2102 "PCap failed to set up because it may not be initialized" + IDS_2103 "No PCap devices found" + IDS_2104 "Invalid PCap device" + IDS_2105 "Standard 2-button joystick(s)" + IDS_2106 "Standard 4-button joystick" + IDS_2107 "Standard 6-button joystick" + IDS_2108 "Standard 8-button joystick" + IDS_2109 "CH Flightstick Pro" + IDS_2110 "Microsoft SideWinder Pad" + IDS_2111 "Thrustmaster Flight Control System" + IDS_2112 "None" + IDS_2113 "Unable to load Keyboard Accelerators!" + IDS_2114 "Unable to register Raw Input!" + IDS_2115 "%u" + IDS_2116 "%u MB (CHS: %i, %i, %i)" + IDS_2117 "Floppy %i (%s): %ls" + IDS_2118 "All images (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.DDI;*.DSK;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.DDI;*.DSK;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.XDF\0Advanced sector images (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Basic sector images (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.DDI;*.DSK;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.DDI;*.DSK;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Flux images (*.FDI)\0*.FDI\0Surface images (*.86F)\0*.86F\0All files (*.*)\0*.*\0" END STRINGTABLE DISCARDABLE BEGIN - IDS_2096 "Slave" - IDS_2097 "SCSI (ID %s, LUN %s)" - IDS_2098 "Adapter Type" - IDS_2099 "Base Address" - IDS_2100 "IRQ" - IDS_2101 "8-bit DMA" - IDS_2102 "16-bit DMA" - IDS_2103 "BIOS" - IDS_2104 "Network Type" - IDS_2105 "Surround Module" - IDS_2106 "MPU-401 Base Address" - IDS_2107 "Use CTRL+ALT+PAGE DOWN to return to windowed mode" - IDS_2108 "On-board RAM" - IDS_2109 "Memory Size" - IDS_2110 "Display Type" - IDS_2111 "RGB" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2112 "Composite" - IDS_2113 "Composite Type" - IDS_2114 "Old" - IDS_2115 "New" - IDS_2116 "RGB Type" - IDS_2117 "Color" - IDS_2118 "Monochrome (Green)" - IDS_2119 "Monochrome (Amber)" - IDS_2120 "Monochrome (Gray)" - IDS_2121 "Color (no brown)" - IDS_2122 "Monochrome (Default)" - IDS_2123 "Snow Emulation" - IDS_2124 "Bilinear Filtering" - IDS_2125 "Dithering" - IDS_2126 "Framebuffer Memory Size" - IDS_2127 "Texture Memory Size" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2128 "Screen Filter" - IDS_2129 "Render Threads" - IDS_2130 "Recompiler" - IDS_2131 "Default" - IDS_2132 "%i Wait state(s)" - IDS_2133 "8-bit" - IDS_2134 "Slow 16-bit" - IDS_2135 "Fast 16-bit" - IDS_2136 "Slow VLB/PCI" - IDS_2137 "Mid VLB/PCI" - IDS_2138 "Fast VLB/PCI" -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_2139 "PCap failed to set up because it may not be initialized" - IDS_2140 "No PCap devices found" - IDS_2141 "Invalid PCap device" - IDS_2142 "&Notify disk change" - IDS_2143 "Type" - IDS_2144 "Standard 2-button joystick(s)" - IDS_2145 "Standard 4-button joystick" - IDS_2146 "Standard 6-button joystick" - IDS_2147 "Standard 8-button joystick" - IDS_2148 "CH Flightstick Pro" - IDS_2149 "Microsoft SideWinder Pad" - IDS_2150 "Thrustmaster Flight Control System" - IDS_2151 "Disabled" - IDS_2152 "None" - IDS_2153 "Unable to load Keyboard Accelerators!" - IDS_2154 "Unable to register Raw Input!" - IDS_2155 "IRQ %i" - IDS_2156 "%u" - IDS_2157 "%u MB (CHS: %i, %i, %i)" - IDS_2158 "Floppy %i (%s): %ls" - IDS_2159 "All images (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.DDI;*.DSK;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.DDI;*.DSK;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.XDF\0Advanced sector images (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Basic sector images (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.DDI;*.DSK;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.DDI;*.DSK;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Flux images (*.FDI)\0*.FDI\0Surface images (*.86F)\0*.86F\0All files (*.*)\0*.*\0" - IDS_2160 "Configuration files (*.CFG)\0*.CFG\0All files (*.*)\0*.*\0" - IDS_2161 "&New image..." - IDS_2162 "&Existing image..." - IDS_2163 "Existing image (&Write-protected)..." - IDS_2164 "E&ject" - IDS_2165 "&Mute" - IDS_2166 "E&mpty" - IDS_2167 "&Reload previous image" - IDS_2168 "&Image..." - IDS_2169 "Image (&Write-protected)..." - IDS_2170 "Check BPB" - IDS_2171 "Unable to initialize FluidSynth, make sure you have the following libraries\nin your 86Box folder:\n\nlibfluidsynth.dll\nlibglib-2.0-0.dll\nlibiconv-2.dll\nlibintl-8.dll\nlibpcre-1.dll" - IDS_2172 "E&xport to 86F..." - IDS_2173 "Surface images (*.86F)\0*.86F\0" - IDS_2174 "All images (*.86F;*.DSK;*.FLP;*.IM?;*.*FD?)\0*.86F;*.DSK;*.FLP;*.IM?;*.*FD?\0Basic sector images (*.DSK;*.FLP;*.IM?;*.*FD?)\0*.DSK;*.FLP;*.IM?;*.IMG;*.*FD?\0Surface images (*.86F)\0*.86F\0" - IDS_2175 "ZIP images (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0All files (*.*)\0*.*\0" - IDS_2176 "ZIP images (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0" - IDS_2177 "ZIP %03i %i (%s): %ls" - IDS_2178 "Speed" - IDS_4096 "Hard disk (%s)" IDS_4097 "%01i:%01i" IDS_4098 "%i" - IDS_4099 "Disabled" + IDS_4099 "MFM/RLL or ESDI CD-ROM drives never existed" IDS_4100 "Custom..." IDS_4101 "Custom (large)..." IDS_4102 "Add New Hard Disk" IDS_4103 "Add Existing Hard Disk" IDS_4104 "Attempting to create a HDI image larger than 4 GB" - IDS_4105 "Attempting to create a spuriously large hard disk image" + IDS_4105 "Attempting to create a hard disk image beyond the 28-bit LBA limit" IDS_4106 "Hard disk images (*.HD?;*.IM?;*.VHD)\0*.HD?;*.IM?;*.VHD\0All files (*.*)\0*.*\0" IDS_4107 "Unable to open the file for read" IDS_4108 "Unable to open the file for write" - IDS_4109 "HDI or HDX image with a sector size that is not 512 are not supported" + IDS_4109 "HDI or HDX images with a sector size that is not 512 are not supported" IDS_4110 "USB is not yet supported" IDS_4111 "This image exists and will be overwritten.\nAre you sure you want to use it?" IDS_4112 "Please enter a valid file name" IDS_4113 "Remember to partition and format the new drive" - IDS_4114 "MFM/RLL or ESDI CD-ROM drives never existed" IDS_4352 "MFM/RLL" IDS_4353 "XTA" @@ -983,23 +892,17 @@ BEGIN IDS_4609 "XTA (%01i:%01i)" IDS_4610 "ESDI (%01i:%01i)" IDS_4611 "IDE (%01i:%01i)" - IDS_4612 "SCSI (%02i:%02i)" + IDS_4612 "SCSI (ID %02i)" IDS_5120 "CD-ROM %i (%s): %s" IDS_5376 "Disabled" - IDS_5377 "" - IDS_5378 "" - IDS_5379 "" IDS_5380 "ATAPI" IDS_5381 "SCSI" IDS_5632 "Disabled" - IDS_5633 "" - IDS_5634 "" - IDS_5635 "" IDS_5636 "ATAPI (%01i:%01i)" - IDS_5637 "SCSI (%02i:%02i)" + IDS_5637 "SCSI (ID %02i)" IDS_5888 "160 kB" IDS_5889 "180 kB" @@ -1047,7 +950,7 @@ VS_VERSION_INFO VERSIONINFO BEGIN BLOCK "StringFileInfo" BEGIN - BLOCK "040904b0" + BLOCK "0409fde9" BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "IRC #SoftHistory\0" diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index b6164a547..04fffeff3 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -8,7 +8,7 @@ # # Makefile for Win32 (MinGW32) environment. # -# Version: @(#)Makefile.mingw 1.0.117 2018/05/21 +# Version: @(#)Makefile.mingw 1.0.118 2018/05/26 # # Authors: Miran Grca, # Fred N. van Kempen, @@ -291,7 +291,7 @@ ifneq ($(WX), n) UIOBJ := wx_main.o wx_ui.o wx_stbar.o wx_render.o else UIOBJ := win_ui.o win_stbar.o \ - win_ddraw.o win_d3d.o \ + win_ddraw.o win_d3d.o win_sdl.o \ win_dialog.o win_about.o \ win_settings.o win_devconf.o win_snd_gain.o \ win_new_floppy.o win_jsconf.o @@ -489,7 +489,8 @@ NETOBJ := network.o \ bootp.o ip_icmp.o misc.o socket.o tcp_timer.o cksum.o \ ip_input.o queue.o tcp_input.o debug.o ip_output.o \ sbuf.o tcp_output.o udp.o if.o mbuf.o slirp.o tcp_subr.o \ - net_ne2000.o + net_dp8390.o \ + net_3c503.o net_ne2000.o SNDOBJ := sound.o \ openal.o \ diff --git a/src/win/resource.h b/src/win/resource.h index 1abac6723..9579a055e 100644 --- a/src/win/resource.h +++ b/src/win/resource.h @@ -8,7 +8,7 @@ * * Windows resource defines. * - * Version: @(#)resource.h 1.0.24 2018/04/26 + * Version: @(#)resource.h 1.0.25 2018/05/25 * * Authors: Sarah Walker, * Miran Grca, @@ -48,7 +48,6 @@ #define IDT_1705 1705 /* MB == IDC_TEXT_MB */ #define IDT_1706 1706 /* Memory: */ #define IDT_1707 1707 /* Video: */ -#define IDT_1708 1708 /* Video speed: */ #define IDT_1709 1709 /* Mouse: */ #define IDT_1710 1710 /* Joystick: */ #define IDT_1711 1711 /* Sound card: */ @@ -121,9 +120,8 @@ #define IDC_VIDEO 1030 /* video config */ #define IDC_COMBO_VIDEO 1031 -#define IDC_COMBO_VIDEO_SPEED 1032 -#define IDC_CHECK_VOODOO 1033 -#define IDC_BUTTON_VOODOO 1034 +#define IDC_CHECK_VOODOO 1032 +#define IDC_BUTTON_VOODOO 1033 #define IDC_INPUT 1050 /* input config */ #define IDC_COMBO_MOUSE 1051 @@ -245,8 +243,8 @@ #define IDM_VID_REMEMBER 40041 #define IDM_VID_DDRAW 40050 #define IDM_VID_D3D 40051 -#define IDM_VID_VNC 40052 -#define IDM_VID_RDP 40053 +#define IDM_VID_SDL 40052 +#define IDM_VID_VNC 40053 #define IDM_VID_SCALE_1X 40054 #define IDM_VID_SCALE_2X 40055 #define IDM_VID_SCALE_3X 40056 diff --git a/src/win/win.c b/src/win/win.c index cc2b42385..1f87ccd52 100644 --- a/src/win/win.c +++ b/src/win/win.c @@ -8,7 +8,7 @@ * * Platform main support module for Windows. * - * Version: @(#)win.c 1.0.48 2018/04/29 + * Version: @(#)win.c 1.0.49 2018/05/25 * * Authors: Sarah Walker, * Miran Grca, @@ -41,15 +41,9 @@ #ifdef USE_VNC # include "../vnc.h" #endif -#ifdef USE_RDP -# include "../rdp.h" -#endif -#ifdef USE_WX -# include "../wx/wx_ui.h" -#else # include "win_ddraw.h" # include "win_d3d.h" -#endif +# include "win_sdl.h" #include "win.h" @@ -87,43 +81,25 @@ static struct { void (*close)(void); void (*resize)(int x, int y); int (*pause)(void); -} vid_apis[2][4] = { +} vid_apis[2][RENDERERS_NUM] = { { -#ifdef USE_WX - { "WxWidgets", 1, wx_init, wx_close, NULL, wx_pause }, - { "WxWidgets", 1, wx_init, wx_close, NULL, wx_pause }, -#else { "DDraw", 1, (int(*)(void*))ddraw_init, ddraw_close, NULL, ddraw_pause }, { "D3D", 1, (int(*)(void*))d3d_init, d3d_close, d3d_resize, d3d_pause }, -#endif #ifdef USE_VNC - { "VNC", 0, vnc_init, vnc_close, vnc_resize, vnc_pause }, + { "SDL", 1, (int(*)(void*))sdl_init, sdl_close, NULL, sdl_pause }, + { "VNC", 0, vnc_init, vnc_close, vnc_resize, vnc_pause } #else - { NULL, 0, NULL, NULL, NULL, NULL }, -#endif -#ifdef USE_RDP - { "RDP", 0, rdp_init, rdp_close, rdp_resize, rdp_pause } -#else - { NULL, 0, NULL, NULL, NULL, NULL } + { "SDL", 1, (int(*)(void*))sdl_init, sdl_close, NULL, sdl_pause } #endif }, { -#ifdef USE_WX - { "WxWidgets", 1, wx_init, wx_close, NULL, wx_pause }, - { "WxWidgets", 1, wx_init, wx_close, NULL, wx_pause }, -#else { "DDraw", 1, (int(*)(void*))ddraw_init_fs, ddraw_close, NULL, ddraw_pause }, { "D3D", 1, (int(*)(void*))d3d_init_fs, d3d_close, NULL, d3d_pause }, -#endif #ifdef USE_VNC - { "VNC", 0, vnc_init, vnc_close, vnc_resize, vnc_pause }, + { "SDL", 1, (int(*)(void*))sdl_init_fs, sdl_close, NULL, sdl_pause }, + { "VNC", 0, vnc_init, vnc_close, vnc_resize, vnc_pause } #else - { NULL, 0, NULL, NULL, NULL, NULL }, -#endif -#ifdef USE_RDP - { "RDP", 0, rdp_init, rdp_close, rdp_resize, rdp_pause } -#else - { NULL, 0, NULL, NULL, NULL, NULL } + { "SDL", 1, (int(*)(void*))sdl_init_fs, sdl_close, sdl_resize, sdl_pause } #endif }, }; @@ -180,11 +156,15 @@ LoadCommonStrings(void) for (i=0; i 3)) + LoadString(hinstance, 5376+i, lpRCstr5376[i].str, 512); + } - for (i=0; i 3)) + LoadString(hinstance, 5632+i, lpRCstr5632[i].str, 512); + } for (i=0; i 1)) return; + if ((vid_api < 0) || (vid_api > 2)) return; memset(fn, 0, sizeof(fn)); memset(path, 0, sizeof(path)); @@ -784,12 +747,6 @@ take_screenshot(void) wcscat(path, fn); switch(vid_api) { -#ifdef USE_WX - case 0: - case 1: - wx_screenshot(path); - break; -#else case 0: /* ddraw */ ddraw_take_screenshot(path); break; @@ -797,10 +754,13 @@ take_screenshot(void) case 1: /* d3d9 */ d3d_take_screenshot(path); break; -#endif + + case 2: /* sdl */ + sdl_take_screenshot(path); + break; #ifdef USE_VNC - case 2: /* vnc */ + case 3: /* vnc */ vnc_take_screenshot(path); break; #endif diff --git a/src/win/win.h b/src/win/win.h index ce1a481a2..eb62e8aea 100644 --- a/src/win/win.h +++ b/src/win/win.h @@ -8,7 +8,7 @@ * * Platform support defintions for Win32. * - * Version: @(#)win.h 1.0.17 2018/04/26 + * Version: @(#)win.h 1.0.18 2018/05/26 * * Authors: Sarah Walker, * Miran Grca, @@ -41,6 +41,7 @@ #define SUB_CLASS_NAME L"86BoxSubWnd" #define SB_CLASS_NAME L"86BoxStatusBar" #define SB_MENU_NAME L"StatusBarMenu" +#define FS_CLASS_NAME L"86BoxFullScreen" /* Application-specific window messages. */ #define WM_RESETD3D WM_USER @@ -50,13 +51,19 @@ #define WM_PAUSE 0x8890 #define WM_SENDHWND 0x8891 +#ifdef USE_VNC +#define RENDERERS_NUM 4 +#else +#define RENDERERS_NUM 3 +#endif + extern HINSTANCE hinstance; extern HWND hwndMain, hwndRender; extern HANDLE ghMutex; extern LCID lang_id; -extern HICON hIcon[512]; +extern HICON hIcon[256]; // extern int status_is_open; @@ -111,6 +118,7 @@ extern int hard_disk_was_added(void); /* Platform UI support functions. */ extern int ui_init(int nCmdShow); +extern void plat_set_input(HWND h); /* Functions in win_about.c: */ diff --git a/src/win/win_about.c b/src/win/win_about.c index 37389dfab..355dd313d 100644 --- a/src/win/win_about.c +++ b/src/win/win_about.c @@ -8,7 +8,7 @@ * * Handle the About dialog. * - * Version: @(#)win_about.c 1.0.6 2018/03/28 + * Version: @(#)win_about.c 1.0.7 2018/06/02 * * Authors: Miran Grca, * Fred N. van Kempen, @@ -45,7 +45,7 @@ AboutDialogProcedure(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) case WM_INITDIALOG: plat_pause(1); h = GetDlgItem(hdlg, IDC_ABOUT_ICON); - ih = LoadImage(hinstance,(PCTSTR)100,IMAGE_ICON,64,64,0); + ih = LoadImage(hinstance,(PCTSTR)10,IMAGE_ICON,64,64,0); SendMessage(h, STM_SETIMAGE, (WPARAM)IMAGE_ICON, (LPARAM)ih); break; diff --git a/src/win/win_cdrom.c b/src/win/win_cdrom.c index 666ac7ccf..012772655 100644 --- a/src/win/win_cdrom.c +++ b/src/win/win_cdrom.c @@ -8,7 +8,7 @@ * * Handle the platform-side of CDROM drives. * - * Version: @(#)win_cdrom.c 1.0.7 2018/03/26 + * Version: @(#)win_cdrom.c 1.0.8 2018/06/02 * * Authors: Sarah Walker, * Miran Grca, @@ -29,9 +29,9 @@ #include #include "../config.h" #include "../disk/hdd.h" -#include "../disk/zip.h" #include "../scsi/scsi.h" #include "../cdrom/cdrom.h" +#include "../disk/zip.h" #include "../cdrom/cdrom_image.h" #include "../cdrom/cdrom_null.h" #include "../scsi/scsi_disk.h" @@ -121,10 +121,10 @@ cdrom_reload(uint8_t id) void zip_eject(uint8_t id) { - zip_close(id); + zip_disk_close(zip[id]); if (zip_drives[id].bus_type) { /* Signal disk change to the emulated machine. */ - zip_insert(id); + zip_insert(zip[id]); } ui_sb_update_icon_state(SB_ZIP | id, 1); @@ -138,7 +138,7 @@ zip_eject(uint8_t id) void zip_reload(uint8_t id) { - zip_disk_reload(id); + zip_disk_reload(zip[id]); if (wcslen(zip_drives[id].image_path) == 0) { ui_sb_enable_menu_item(SB_ZIP|id, IDM_ZIP_EJECT | id, MF_BYCOMMAND | MF_GRAYED); ui_sb_update_icon_state(SB_ZIP|id, 1); diff --git a/src/win/win_d3d.cpp b/src/win/win_d3d.cpp index 209875414..fe18d587c 100644 --- a/src/win/win_d3d.cpp +++ b/src/win/win_d3d.cpp @@ -8,7 +8,7 @@ * * Rendering module for Microsoft Direct3D 9. * - * Version: @(#)win_d3d.cpp 1.0.10 2018/01/15 + * Version: @(#)win_d3d.cpp 1.0.11 2018/05/26 * * Authors: Sarah Walker, * Miran Grca, @@ -183,8 +183,14 @@ d3d_blit_fs(int x, int y, int y1, int y2, int w, int h) hr = d3dTexture->LockRect(0, &dr, &lock_rect, 0); if (hr == D3D_OK) { - for (yy = y1; yy < y2; yy++) - if (buffer32) memcpy((void *)((uintptr_t)dr.pBits + ((yy - y1) * dr.Pitch)), &(((uint32_t *)buffer32->line[yy + y])[x]), w * 4); + for (yy = y1; yy < y2; yy++) { + if (buffer32) { + if (video_grayscale || invert_display) + video_transform_copy((uint32_t *)((uintptr_t)dr.pBits + ((yy - y1) * dr.Pitch)), &(((uint32_t *)buffer32->line[yy + y])[x]), w); + else + memcpy((void *)((uintptr_t)dr.pBits + ((yy - y1) * dr.Pitch)), &(((uint32_t *)buffer32->line[yy + y])[x]), w * 4); + } + } video_blit_complete(); d3dTexture->UnlockRect(0); @@ -288,9 +294,14 @@ d3d_blit(int x, int y, int y1, int y2, int w, int h) hr = d3dTexture->LockRect(0, &dr, &r, 0); if (hr == D3D_OK) { for (yy = y1; yy < y2; yy++) { - if (buffer32) - if ((y + yy) >= 0 && (y + yy) < buffer32->h) - memcpy((void *)((uintptr_t)dr.pBits + ((yy - y1) * dr.Pitch)), &(((uint32_t *)buffer32->line[yy + y])[x]), w * 4); + if (buffer32) { + if ((y + yy) >= 0 && (y + yy) < buffer32->h) { + if (video_grayscale || invert_display) + video_transform_copy((uint32_t *)((uintptr_t)dr.pBits + ((yy - y1) * dr.Pitch)), &(((uint32_t *)buffer32->line[yy + y])[x]), w); + else + memcpy((void *)((uintptr_t)dr.pBits + ((yy - y1) * dr.Pitch)), &(((uint32_t *)buffer32->line[yy + y])[x]), w * 4); + } + } } video_blit_complete(); diff --git a/src/win/win_ddraw.cpp b/src/win/win_ddraw.cpp index 49feb5c19..b235bcf84 100644 --- a/src/win/win_ddraw.cpp +++ b/src/win/win_ddraw.cpp @@ -11,7 +11,7 @@ * NOTES: This code should be re-merged into a single init() with a * 'fullscreen' argument, indicating FS mode is requested. * - * Version: @(#)win_ddraw.cpp 1.0.8 2018/04/29 + * Version: @(#)win_ddraw.cpp 1.0.9 2018/05/26 * * Authors: Sarah Walker, * Miran Grca, @@ -104,6 +104,10 @@ bgra_to_rgb(png_bytep *b_rgb, uint8_t *bgra, int width, int height) { int i, j; uint8_t *r, *b; + uint32_t *rgb = (uint32_t *) bgra; + + if (video_grayscale || invert_display) + *bgra = video_color_transform(*bgra); for (i = 0; i < height; i++) { for (j = 0; j < width; j++) { @@ -237,7 +241,7 @@ SavePNG(wchar_t *szFilename, HBITMAP hBitmap) if (pBuf2) free(pBuf2); - if (pBuf) free(pBuf); + if (pBuf) free(pBuf); if (fp) fclose(fp); } @@ -374,8 +378,14 @@ ddraw_blit_fs(int x, int y, int y1, int y2, int w, int h) return; } - for (yy = y1; yy < y2; yy++) - if (buffer32) memcpy((void *)((uintptr_t)ddsd.lpSurface + (yy * ddsd.lPitch)), &(((uint32_t *)buffer32->line[y + yy])[x]), w * 4); + for (yy = y1; yy < y2; yy++) { + if (buffer32) { + if (video_grayscale || invert_display) + video_transform_copy((uint32_t *)((uintptr_t)ddsd.lpSurface + (yy * ddsd.lPitch)), &(((uint32_t *)buffer32->line[y + yy])[x]), w); + else + memcpy((void *)((uintptr_t)ddsd.lpSurface + (yy * ddsd.lPitch)), &(((uint32_t *)buffer32->line[y + yy])[x]), w * 4); + } + } video_blit_complete(); lpdds_back->Unlock(NULL); @@ -418,6 +428,7 @@ ddraw_blit(int x, int y, int y1, int y2, int w, int h) POINT po; HRESULT hr; int yy; + uint32_t *p, *q; if (lpdds_back == NULL) { video_blit_complete(); @@ -447,10 +458,16 @@ ddraw_blit(int x, int y, int y1, int y2, int w, int h) } for (yy = y1; yy < y2; yy++) { - if (buffer32) - if ((y + yy) >= 0 && (y + yy) < buffer32->h) - memcpy((uint32_t *) &(((uint8_t *) ddsd.lpSurface)[yy * ddsd.lPitch]), &(((uint32_t *)buffer32->line[y + yy])[x]), w * 4); + if (buffer32) { + if ((y + yy) >= 0 && (y + yy) < buffer32->h) { + if (video_grayscale || invert_display) + video_transform_copy((uint32_t *) &(((uint8_t *) ddsd.lpSurface)[yy * ddsd.lPitch]), &(((uint32_t *)buffer32->line[y + yy])[x]), w); + else + memcpy((uint32_t *) &(((uint8_t *) ddsd.lpSurface)[yy * ddsd.lPitch]), &(((uint32_t *)buffer32->line[y + yy])[x]), w * 4); + } + } } + video_blit_complete(); lpdds_back->Unlock(NULL); diff --git a/src/win/win_new_floppy.c b/src/win/win_new_floppy.c index 69ad33f1a..a7954672b 100644 --- a/src/win/win_new_floppy.c +++ b/src/win/win_new_floppy.c @@ -8,7 +8,7 @@ * * Handle the New Floppy Image dialog. * - * Version: @(#)win_new_floppy.c 1.0.7 2018/05/14 + * Version: @(#)win_new_floppy.c 1.0.8 2018/05/25 * * Authors: Miran Grca, * @@ -29,6 +29,7 @@ #include "../plat.h" #include "../random.h" #include "../ui.h" +#include "../scsi/scsi.h" #include "../disk/zip.h" #include "win.h" @@ -624,7 +625,7 @@ NewFloppyDialogProcedure(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) return TRUE; case IDC_CFILE: - if (!file_dlg_w(hdlg, plat_get_string(is_zip ? IDS_2176 : IDS_2174), L"", 1)) { + if (!file_dlg_w(hdlg, plat_get_string(is_zip ? IDS_2055 : IDS_2062), L"", 1)) { if (!wcschr(wopenfilestring, L'.')) { if (wcslen(wopenfilestring) && (wcslen(wopenfilestring) <= 256)) { twcs = &wopenfilestring[wcslen(wopenfilestring)]; diff --git a/src/win/win_sdl.c b/src/win/win_sdl.c new file mode 100644 index 000000000..8fafd7e54 --- /dev/null +++ b/src/win/win_sdl.c @@ -0,0 +1,625 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Rendering module for libSDL2 + * + * NOTE: Given all the problems reported with FULLSCREEN use of SDL, + * we will not use that, but, instead, use a new window which + * coverrs the entire desktop. + * + * Version: @(#)win_sdl.c 1.0.0 2018/05/26 + * + * Authors: Fred N. van Kempen, + * Michael Drüing, + * + * Copyright 2018 Fred N. van Kempen. + * Copyright 2018 Michael Drüing. + * + * Redistribution and use in source and binary forms, with + * or without modification, are permitted provided that the + * following conditions are met: + * + * 1. Redistributions of source code must retain the entire + * above notice, this list of conditions and the following + * disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names + * of its contributors may be used to endorse or promote + * products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#define UNICODE +#define WIN32_LEAN_AND_MEAN +#include +#include + +#define PNG_DEBUG 0 +#include + +#include +#include +#include +#include +#include "../86box.h" +#include "../device.h" +#include "../plat.h" +#include "../plat_dynld.h" +#include "../video/video.h" +#include "win.h" +#include "win_sdl.h" + + +#define PATH_SDL_DLL "sdl2.dll" + + +static void *sdl_handle = NULL; /* handle to libSDL2 DLL */ +static SDL_Window *sdl_win = NULL; +static SDL_Renderer *sdl_render = NULL; +static SDL_Texture *sdl_tex = NULL; +static HWND sdl_parent_hwnd = NULL; +static HWND sdl_hwnd = NULL; +static int sdl_w, sdl_h; +static int sdl_fs; +static int cur_w, cur_h; + +static png_structp png_ptr; +static png_infop info_ptr; + + +/* Pointers to the real functions. */ +static void (*sdl_GetVersion)(SDL_version *ver); +static char *const (*sdl_GetError)(void); +static int (*sdl_Init)(Uint32 flags); +static void (*sdl_Quit)(void); +static SDL_Window *(*sdl_CreateWindowFrom)(const void *data); +static void (*sdl_DestroyWindow)(SDL_Window *window); +static SDL_Renderer *(*sdl_CreateRenderer)(SDL_Window *window, + int index, Uint32 flags); +static void (*sdl_DestroyRenderer)(SDL_Renderer *renderer); +static SDL_Texture *(*sdl_CreateTexture)(SDL_Renderer *renderer, + Uint32 format, int access, + int w, int h); +static void (*sdl_DestroyTexture)(SDL_Texture *texture); +static int (*sdl_LockTexture)(SDL_Texture *texture, + const SDL_Rect *rect, + void **pixels, int *pitch); +static void (*sdl_UnlockTexture)(SDL_Texture *texture); +static int (*sdl_RenderCopy)(SDL_Renderer *renderer, + SDL_Texture *texture, + const SDL_Rect *srcrect, + const SDL_Rect *dstrect); +static void (*sdl_RenderPresent)(SDL_Renderer *renderer); +static void (*sdl_GetWindowSize)(SDL_Window* window, + int* w, + int* h); +static int (*sdl_RenderReadPixels)(SDL_Renderer* renderer, + const SDL_Rect* rect, + Uint32 format, + void* pixels, + int pitch); +static SDL_bool (*sdl_SetHint)(const char* name, + const char* value); + +static dllimp_t sdl_imports[] = { + { "SDL_GetVersion", &sdl_GetVersion }, + { "SDL_GetError", &sdl_GetError }, + { "SDL_Init", &sdl_Init }, + { "SDL_Quit", &sdl_Quit }, + { "SDL_CreateWindowFrom", &sdl_CreateWindowFrom }, + { "SDL_DestroyWindow", &sdl_DestroyWindow }, + { "SDL_CreateRenderer", &sdl_CreateRenderer }, + { "SDL_DestroyRenderer", &sdl_DestroyRenderer }, + { "SDL_CreateTexture", &sdl_CreateTexture }, + { "SDL_DestroyTexture", &sdl_DestroyTexture }, + { "SDL_LockTexture", &sdl_LockTexture }, + { "SDL_UnlockTexture", &sdl_UnlockTexture }, + { "SDL_RenderCopy", &sdl_RenderCopy }, + { "SDL_RenderPresent", &sdl_RenderPresent }, + { "SDL_GetWindowSize", &sdl_GetWindowSize }, + { "SDL_RenderReadPixels", &sdl_RenderReadPixels }, + { "SDL_SetHint", &sdl_SetHint }, + { NULL, NULL } +}; + + +#ifdef ENABLE_SDL_LOG +int sdl_do_log = ENABLE_SDL_LOG; +#endif + + +static void +sdl_log(const char *fmt, ...) +{ +#ifdef ENABLE_SDL_LOG + va_list ap; + + if (sdl_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +#endif +} + + +static void +sdl_stretch(int *w, int *h, int *x, int *y) +{ + double dw, dh, dx, dy, temp, temp2, ratio_w, ratio_h, gsr, hsr; + + switch (video_fullscreen_scale) { + case FULLSCR_SCALE_FULL: + *w = sdl_w; + *h = sdl_h; + *x = 0; + *y = 0; + break; + case FULLSCR_SCALE_43: + dw = (double) sdl_w; + dh = (double) sdl_h; + temp = (dh / 3.0) * 4.0; + dx = (dw - temp) / 2.0; + dw = temp; + *w = (int) dw; + *h = (int) dh; + *x = (int) dx; + *y = 0; + break; + case FULLSCR_SCALE_SQ: + dw = (double) sdl_w; + dh = (double) sdl_h; + temp = ((double) *w); + temp2 = ((double) *h); + dx = (dw / 2.0) - ((dh * temp) / (temp2 * 2.0)); + dy = 0.0; + if (dx < 0.0) { + dx = 0.0; + dy = (dw / 2.0) - ((dh * temp2) / (temp * 2.0)); + } + dw -= (dx * 2.0); + dh -= (dy * 2.0); + *w = (int) dw; + *h = (int) dh; + *x = (int) dx; + *y = (int) dy; + break; + case FULLSCR_SCALE_INT: + dw = (double) sdl_w; + dh = (double) sdl_h; + temp = ((double) *w); + temp2 = ((double) *h); + ratio_w = dw / ((double) *w); + ratio_h = dh / ((double) *h); + if (ratio_h < ratio_w) + ratio_w = ratio_h; + dx = (dw / 2.0) - ((temp * ratio_w) / 2.0); + dy = (dh / 2.0) - ((temp2 * ratio_h) / 2.0); + dw -= (dx * 2.0); + dh -= (dy * 2.0); + *w = (int) dw; + *h = (int) dh; + *x = (int) dx; + *y = (int) dy; + break; + case FULLSCR_SCALE_KEEPRATIO: + dw = (double) sdl_w; + dh = (double) sdl_h; + hsr = dw / dh; + gsr = ((double) *w) / ((double) *h); + if (gsr <= hsr) { + temp = dh * gsr; + dx = (dw - temp) / 2.0; + dw = temp; + *w = (int) dw; + *h = (int) dh; + *x = (int) dx; + *y = 0; + } else { + temp = dw / gsr; + dy = (dh - temp) / 2.0; + dh = temp; + *w = (int) dw; + *h = (int) dh; + *x = 0; + *y = (int) dy; + } + break; + } +} + + +static void +sdl_blit(int x, int y, int y1, int y2, int w, int h) +{ + SDL_Rect r_src; + void *pixeldata; + int pitch; + int yy, ret; + + if (y1 == y2) { + video_blit_complete(); + return; + } + + if (buffer32 == NULL) { + video_blit_complete(); + return; + } + + /* + * TODO: + * SDL_UpdateTexture() might be better here, as it is + * (reportedly) slightly faster. + */ + sdl_LockTexture(sdl_tex, 0, &pixeldata, &pitch); + + for (yy = y1; yy < y2; yy++) { + if ((y + yy) >= 0 && (y + yy) < buffer32->h) { + if (video_grayscale || invert_display) + video_transform_copy((uint32_t *) &(((uint8_t *)pixeldata)[yy * pitch]), &(((uint32_t *)buffer32->line[y + yy])[x]), w); + else + memcpy((uint32_t *) &(((uint8_t *)pixeldata)[yy * pitch]), &(((uint32_t *)buffer32->line[y + yy])[x]), w * 4); + } + } + + video_blit_complete(); + + sdl_UnlockTexture(sdl_tex); + + if (sdl_fs) { + pclog("sdl_blit(%i, %i, %i, %i, %i, %i) (%i, %i)\n", x, y, y1, y2, w, h, unscaled_size_x, efscrnsz_y); + if (w == unscaled_size_x) + sdl_resize(w, h); + pclog("(%08X, %08X, %08X)\n", sdl_win, sdl_render, sdl_tex); + } + + r_src.x = 0; + r_src.y = 0; + r_src.w = w; + r_src.h = h; + + ret = sdl_RenderCopy(sdl_render, sdl_tex, &r_src, 0); + if (ret) + sdl_log("SDL: unable to copy texture to renderer (%s)\n", sdl_GetError()); + + sdl_RenderPresent(sdl_render); +} + + +void +sdl_close(void) +{ + /* Unregister our renderer! */ + video_setblit(NULL); + + if (sdl_tex != NULL) { + sdl_DestroyTexture(sdl_tex); + sdl_tex = NULL; + } + + if (sdl_render != NULL) { + sdl_DestroyRenderer(sdl_render); + sdl_render = NULL; + } + + if (sdl_win != NULL) { + sdl_DestroyWindow(sdl_win); + sdl_win = NULL; + } + + if (sdl_hwnd != NULL) { + plat_set_input(hwndMain); + + ShowWindow(hwndRender, TRUE); + + SetFocus(hwndMain); + + DestroyWindow(sdl_hwnd); + sdl_hwnd = NULL; + } + + if (sdl_parent_hwnd != NULL) { + DestroyWindow(sdl_parent_hwnd); + sdl_parent_hwnd = NULL; + } + + /* Quit and unload the DLL if possible. */ + if (sdl_handle != NULL) { + sdl_Quit(); + + dynld_close(sdl_handle); + sdl_handle = NULL; + } +} + + +static int old_capture = 0; + + +static int +sdl_init_common(int fs) +{ + wchar_t temp[128]; + SDL_version ver; + int w, h, x, y; + RECT rect; + + sdl_log("SDL: init (fs=%d)\n", fs); + + cgapal_rebuild(); + + /* Try loading the DLL. */ + sdl_handle = dynld_module(PATH_SDL_DLL, sdl_imports); + if (sdl_handle == NULL) { + sdl_log("SDL: unable to load '%s', SDL not available.\n", PATH_SDL_DLL); + return(0); + } + + /* Get and log the version of the DLL we are using. */ + sdl_GetVersion(&ver); + sdl_log("SDL: version %d.%d.%d\n", ver.major, ver.minor, ver.patch); + + /* Initialize the SDL system. */ + if (sdl_Init(SDL_INIT_VIDEO) < 0) { + sdl_log("SDL: initialization failed (%s)\n", sdl_GetError()); + return(0); + } + + if (fs) { + /* Get the size of the (current) desktop. */ + sdl_w = GetSystemMetrics(SM_CXSCREEN); + sdl_h = GetSystemMetrics(SM_CYSCREEN); + + /* Create the desktop-covering window. */ + _swprintf(temp, L"%s v%s", EMU_NAME_W, EMU_VERSION_W); + sdl_parent_hwnd = CreateWindow(SUB_CLASS_NAME, + temp, + WS_POPUP, + 0, 0, sdl_w, sdl_h, + HWND_DESKTOP, + NULL, + hinstance, + NULL); + + SetWindowPos(sdl_parent_hwnd, HWND_TOPMOST, + 0, 0, sdl_w, sdl_h, SWP_SHOWWINDOW); + + /* Create the actual rendering window. */ + _swprintf(temp, L"%s v%s", EMU_NAME_W, EMU_VERSION_W); + sdl_hwnd = CreateWindow(SUB_CLASS_NAME, + temp, + WS_POPUP, + 0, 0, sdl_w, sdl_h, + sdl_parent_hwnd, + NULL, + hinstance, + NULL); + sdl_log("SDL: FS %dx%d window at %08lx\n", sdl_w, sdl_h, sdl_hwnd); + + /* Redirect RawInput to this new window. */ + plat_set_input(sdl_hwnd); + + SetFocus(sdl_hwnd); + + /* Show the window, make it topmost, and give it focus. */ + w = unscaled_size_x; + h = efscrnsz_y; + sdl_stretch(&w, &h, &x, &y); + SetWindowPos(sdl_hwnd, sdl_parent_hwnd, + x, y, w, h, SWP_SHOWWINDOW); + + /* Now create the SDL window from that. */ + sdl_win = sdl_CreateWindowFrom((void *)sdl_hwnd); + + old_capture = mouse_capture; + + GetWindowRect(sdl_hwnd, &rect); + + ClipCursor(&rect); + + mouse_capture = 1; + } else { + /* Create the SDL window from the render window. */ + sdl_win = sdl_CreateWindowFrom((void *)hwndRender); + + mouse_capture = old_capture; + + if (mouse_capture) { + GetWindowRect(hwndRender, &rect); + + ClipCursor(&rect); + } + } + if (sdl_win == NULL) { + sdl_log("SDL: unable to CreateWindowFrom (%s)\n", sdl_GetError()); + sdl_close(); + return(0); + } + + /* + * TODO: + * SDL_RENDERER_SOFTWARE, because SDL tries to do funky stuff + * otherwise (it turns off Win7 Aero and it looks like it's + * trying to switch to fullscreen even though the window is + * not a fullscreen window?) + */ + sdl_render = sdl_CreateRenderer(sdl_win, -1, SDL_RENDERER_SOFTWARE); + if (sdl_render == NULL) { + sdl_log("SDL: unable to create renderer (%s)\n", sdl_GetError()); + sdl_close(); + return(0); + } + + /* + * TODO: + * Actually the source is (apparently) XRGB8888, but the alpha + * channel seems to be set to 255 everywhere, so ARGB8888 works + * just as well. + */ + sdl_tex = sdl_CreateTexture(sdl_render, SDL_PIXELFORMAT_ARGB8888, + SDL_TEXTUREACCESS_STREAMING, 2048, 2048); + if (sdl_tex == NULL) { + sdl_log("SDL: unable to create texture (%s)\n", sdl_GetError()); + sdl_close(); + return(0); + } + + /* Make sure we get a clean exit. */ + atexit(sdl_close); + + /* Register our renderer! */ + video_setblit(sdl_blit); + + sdl_fs = fs; + + return(1); +} + + +int +sdl_init(HWND h) +{ + return sdl_init_common(0); +} + + +int +sdl_init_fs(HWND h) +{ + return sdl_init_common(1); +} + + +void +sdl_take_screenshot(const wchar_t *fn) +{ + int i, res, x, y, width = 0, height = 0; + unsigned char* rgba = NULL; + png_bytep *b_rgb = NULL; + FILE *fp = NULL; + + sdl_GetWindowSize(sdl_win, &width, &height); + + /* create file */ + fp = plat_fopen((wchar_t *) fn, (wchar_t *) L"wb"); + if (!fp) { + sdl_log("[sdl_take_screenshot] File %ls could not be opened for writing", fn); + return; + } + + /* initialize stuff */ + png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + + if (!png_ptr) { + sdl_log("[sdl_take_screenshot] png_create_write_struct failed"); + fclose(fp); + return; + } + + info_ptr = png_create_info_struct(png_ptr); + if (!info_ptr) { + sdl_log("[sdl_take_screenshot] png_create_info_struct failed"); + fclose(fp); + return; + } + + png_init_io(png_ptr, fp); + + png_set_IHDR(png_ptr, info_ptr, width, height, + 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, + PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); + + if ((rgba = (unsigned char *)malloc(width * height * 4)) == NULL) { + sdl_log("[sdl_take_screenshot] Unable to Allocate RGBA Bitmap Memory"); + fclose(fp); + return; + } + + res = sdl_RenderReadPixels(sdl_render, NULL, SDL_PIXELFORMAT_ABGR8888, rgba, width * 4); + if (res) { + sdl_log("[sdl_take_screenshot] Error reading render pixels\n"); + fclose(fp); + return; + } + + if ((b_rgb = (png_bytep *) malloc(sizeof(png_bytep) * height)) == NULL) { + sdl_log("[sdl_take_screenshot] Unable to Allocate RGB Bitmap Memory"); + free(rgba); + fclose(fp); + return; + } + + for (y = 0; y < height; ++y) { + b_rgb[y] = (png_byte *) malloc(png_get_rowbytes(png_ptr, info_ptr)); + for (x = 0; x < width; ++x) { + b_rgb[y][(x) * 3 + 0] = rgba[(y * width + x) * 4 + 0]; + b_rgb[y][(x) * 3 + 1] = rgba[(y * width + x) * 4 + 1]; + b_rgb[y][(x) * 3 + 2] = rgba[(y * width + x) * 4 + 2]; + } + } + + png_write_info(png_ptr, info_ptr); + + png_write_image(png_ptr, b_rgb); + + png_write_end(png_ptr, NULL); + + /* cleanup heap allocation */ + for (i = 0; i < height; i++) + if (b_rgb[i]) free(b_rgb[i]); + + if (b_rgb) free(b_rgb); + + if (rgba) free(rgba); + + if (fp) fclose(fp); +} + + +int +sdl_pause(void) +{ + return(0); +} + + +void +sdl_resize(int x, int y) +{ + int ww, wh, wx, wy; + + if ((x == cur_w) && (y == cur_h)) + return; + + pclog("sdl_resize(%i, %i)\n", x, y); + ww = x; + wh = y; + sdl_stretch(&ww, &wh, &wx, &wy); + + MoveWindow(sdl_hwnd, wx, wy, ww, wh, TRUE); + + cur_w = x; + cur_h = y; +} diff --git a/src/win/win_sdl.h b/src/win/win_sdl.h new file mode 100644 index 000000000..23ba344be --- /dev/null +++ b/src/win/win_sdl.h @@ -0,0 +1,62 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Definitions for the libSDL2 rendering module. + * + * Version: @(#)win_sdl.h 1.0.0 2018/05/26 + * + * Authors: Fred N. van Kempen, + * Michael Drüing, + * + * Copyright 2018 Fred N. van Kempen. + * Copyright 2018 Michael Drüing. + * + * Redistribution and use in source and binary forms, with + * or without modification, are permitted provided that the + * following conditions are met: + * + * 1. Redistributions of source code must retain the entire + * above notice, this list of conditions and the following + * disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names + * of its contributors may be used to endorse or promote + * products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef WIN_SDL_H +# define WIN_SDL_H + + +extern void sdl_close(void); +extern int sdl_init(HWND h); +extern int sdl_init_fs(HWND h); +extern int sdl_pause(void); +extern void sdl_resize(int x, int y); + +extern void sdl_take_screenshot(const wchar_t *fn); + + +#endif /*WIN_SDL_H*/ diff --git a/src/win/win_settings.c b/src/win/win_settings.c index 292a98899..16d8ea151 100644 --- a/src/win/win_settings.c +++ b/src/win/win_settings.c @@ -8,7 +8,7 @@ * * Windows 86Box Settings dialog handler. * - * Version: @(#)win_settings.c 1.0.50 2018/05/01 + * Version: @(#)win_settings.c 1.0.51 2018/05/25 * * Author: Miran Grca, * @@ -56,6 +56,21 @@ #include "win.h" +#define SETTINGS_PAGE_MACHINE 0 +#define SETTINGS_PAGE_VIDEO 1 +#define SETTINGS_PAGE_INPUT 2 +#define SETTINGS_PAGE_SOUND 3 +#define SETTINGS_PAGE_NETWORK 4 +#define SETTINGS_PAGE_PORTS 5 +#define SETTINGS_PAGE_PERIPHERALS 6 +#define SETTINGS_PAGE_HARD_DISKS 7 +#define SETTINGS_PAGE_FLOPPY_DRIVES 8 +#define SETTINGS_PAGE_OTHER_REMOVABLE_DEVICES 9 + +/* Icon, Bus, File, C, H, S, Size */ +#define C_COLUMNS_HARD_DISKS 6 + + /* Machine category */ static int temp_machine, temp_cpu_m, temp_cpu, temp_wait_states, temp_fpu, temp_sync; static uint32_t temp_mem_size; @@ -64,7 +79,7 @@ static int temp_dynarec; #endif /* Video category */ -static int temp_gfxcard, temp_video_speed, temp_voodoo; +static int temp_gfxcard, temp_voodoo; /* Input devices category */ static int temp_mouse, temp_joystick; @@ -107,14 +122,50 @@ static uint32_t displayed_category = 0; extern int is486; static int romstolist[ROM_MAX], listtomachine[ROM_MAX], romstomachine[ROM_MAX], machinetolist[ROM_MAX]; -static int settings_sound_to_list[20], settings_list_to_sound[20]; +static int settings_device_to_list[20], settings_list_to_device[20]; static int settings_midi_to_list[20], settings_list_to_midi[20]; -static int settings_mouse_to_list[20], settings_list_to_mouse[20]; -static int settings_scsi_to_list[20], settings_list_to_scsi[20]; -static int settings_network_to_list[20], settings_list_to_network[20]; -static uint64_t mfm_tracking, esdi_tracking, xta_tracking, ide_tracking, scsi_tracking[16]; +static int max_spt = 63, max_hpc = 255, max_tracks = 266305; +static uint64_t mfm_tracking, esdi_tracking, xta_tracking, ide_tracking, scsi_tracking[2]; +static uint64_t size; +static int hd_listview_items, hdc_id_to_listview_index[HDD_NUM]; +static int no_update = 0, existing = 0, chs_enabled = 0; +static int lv1_current_sel, lv2_current_sel; +static int hard_disk_added = 0, next_free_id = 0, selection = 127; +static int spt, hpc, tracks, ignore_change = 0; +static hard_disk_t new_hdd, *hdd_ptr; + +static wchar_t hd_file_name[512]; + + +static BOOL +image_list_init(HWND hwndList, const uint8_t *icon_ids) +{ + HICON hiconItem; + HIMAGELIST hSmall; + + int i = 0; + + hSmall = ImageList_Create(GetSystemMetrics(SM_CXSMICON), + GetSystemMetrics(SM_CYSMICON), + ILC_MASK | ILC_COLOR32, 1, 1); + + while(1) { + if (icon_ids[i] == 0) + break; + + hiconItem = LoadIcon(hinstance, (LPCWSTR) ((uint32_t) icon_ids[i])); + ImageList_AddIcon(hSmall, hiconItem); + DestroyIcon(hiconItem); + + i++; + } + + ListView_SetImageList(hwndList, hSmall, LVSIL_SMALL); + + return TRUE; +} /* Show a MessageBox dialog. This is nasty, I know. --FvK */ @@ -136,467 +187,420 @@ settings_msgbox(int type, void *arg) /* This does the initial read of global variables into the temporary ones. */ -static void win_settings_init(void) +static void +win_settings_init(void) { - int i = 0; + int i = 0; - /* Machine category */ - temp_machine = machine; - temp_cpu_m = cpu_manufacturer; - temp_wait_states = cpu_waitstates; - temp_cpu = cpu; - temp_mem_size = mem_size; + /* Machine category */ + temp_machine = machine; + temp_cpu_m = cpu_manufacturer; + temp_wait_states = cpu_waitstates; + temp_cpu = cpu; + temp_mem_size = mem_size; #ifdef USE_DYNAREC - temp_dynarec = cpu_use_dynarec; + temp_dynarec = cpu_use_dynarec; #endif - temp_fpu = enable_external_fpu; - temp_sync = enable_sync; + temp_fpu = enable_external_fpu; + temp_sync = enable_sync; - /* Video category */ - temp_gfxcard = gfxcard; - temp_video_speed = video_speed; - temp_voodoo = voodoo_enabled; + /* Video category */ + temp_gfxcard = gfxcard; + temp_voodoo = voodoo_enabled; - /* Input devices category */ - temp_mouse = mouse_type; - temp_joystick = joystick_type; + /* Input devices category */ + temp_mouse = mouse_type; + temp_joystick = joystick_type; - /* Sound category */ - temp_sound_card = sound_card_current; - temp_midi_device = midi_device_current; - temp_mpu401 = mpu401_standalone_enable; - temp_SSI2001 = SSI2001; - temp_GAMEBLASTER = GAMEBLASTER; - temp_GUS = GUS; - temp_opl_type = opl_type; - temp_float = sound_is_float; + /* Sound category */ + temp_sound_card = sound_card_current; + temp_midi_device = midi_device_current; + temp_mpu401 = mpu401_standalone_enable; + temp_SSI2001 = SSI2001; + temp_GAMEBLASTER = GAMEBLASTER; + temp_GUS = GUS; + temp_opl_type = opl_type; + temp_float = sound_is_float; - /* Network category */ - temp_net_type = network_type; - memset(temp_pcap_dev, 0, sizeof(temp_pcap_dev)); - strcpy(temp_pcap_dev, network_host); - temp_net_card = network_card; + /* Network category */ + temp_net_type = network_type; + memset(temp_pcap_dev, 0, sizeof(temp_pcap_dev)); + strcpy(temp_pcap_dev, network_host); + temp_net_card = network_card; - /* Ports category */ - for (i = 0; i < 3; i++) - strncpy(temp_lpt_device_names[i], lpt_device_names[i], sizeof(temp_lpt_device_names[i]) - 1); - temp_serial[0] = serial_enabled[0]; - temp_serial[1] = serial_enabled[1]; - temp_lpt = lpt_enabled; + /* Ports category */ + for (i = 0; i < 3; i++) + strncpy(temp_lpt_device_names[i], lpt_device_names[i], sizeof(temp_lpt_device_names[i]) - 1); + temp_serial[0] = serial_enabled[0]; + temp_serial[1] = serial_enabled[1]; + temp_lpt = lpt_enabled; - /* Other peripherals category */ - temp_scsi_card = scsi_card_current; - strncpy(temp_hdc_name, hdc_name, sizeof(temp_hdc_name) - 1); - temp_ide_ter = ide_ter_enabled; - temp_ide_qua = ide_qua_enabled; - temp_bugger = bugger_enabled; + /* Other peripherals category */ + temp_scsi_card = scsi_card_current; + strncpy(temp_hdc_name, hdc_name, sizeof(temp_hdc_name) - 1); + temp_ide_ter = ide_ter_enabled; + temp_ide_qua = ide_qua_enabled; + temp_bugger = bugger_enabled; - mfm_tracking = xta_tracking = esdi_tracking = ide_tracking = 0; - for (i = 0; i < 16; i++) - scsi_tracking[i] = 0; + mfm_tracking = xta_tracking = esdi_tracking = ide_tracking = 0; + for (i = 0; i < 2; i++) + scsi_tracking[i] = 0; - /* Hard disks category */ - memcpy(temp_hdd, hdd, HDD_NUM * sizeof(hard_disk_t)); - for (i = 0; i < HDD_NUM; i++) - { - if (hdd[i].bus == HDD_BUS_MFM) - mfm_tracking |= (1 << (hdd[i].mfm_channel << 3)); - else if (hdd[i].bus == HDD_BUS_XTA) - xta_tracking |= (1 << (hdd[i].xta_channel << 3)); - else if (hdd[i].bus == HDD_BUS_ESDI) - esdi_tracking |= (1 << (hdd[i].esdi_channel << 3)); - else if (hdd[i].bus == HDD_BUS_IDE) - ide_tracking |= (1 << (hdd[i].ide_channel << 3)); - else if (hdd[i].bus == HDD_BUS_SCSI) - scsi_tracking[hdd[i].scsi_id] |= (1 << (hdd[i].scsi_lun << 3)); - } + /* Hard disks category */ + memcpy(temp_hdd, hdd, HDD_NUM * sizeof(hard_disk_t)); + for (i = 0; i < HDD_NUM; i++) { + if (hdd[i].bus == HDD_BUS_MFM) + mfm_tracking |= (1 << (hdd[i].mfm_channel << 3)); + else if (hdd[i].bus == HDD_BUS_XTA) + xta_tracking |= (1 << (hdd[i].xta_channel << 3)); + else if (hdd[i].bus == HDD_BUS_ESDI) + esdi_tracking |= (1 << (hdd[i].esdi_channel << 3)); + else if (hdd[i].bus == HDD_BUS_IDE) + ide_tracking |= (1 << (hdd[i].ide_channel << 3)); + else if (hdd[i].bus == HDD_BUS_SCSI) + scsi_tracking[hdd[i].scsi_id >> 3] |= (1 << ((hdd[i].scsi_id & 0x07) << 3)); + } - /* Floppy drives category */ - for (i = 0; i < FDD_NUM; i++) - { - temp_fdd_types[i] = fdd_get_type(i); - temp_fdd_turbo[i] = fdd_get_turbo(i); - temp_fdd_check_bpb[i] = fdd_get_check_bpb(i); - } + /* Floppy drives category */ + for (i = 0; i < FDD_NUM; i++) { + temp_fdd_types[i] = fdd_get_type(i); + temp_fdd_turbo[i] = fdd_get_turbo(i); + temp_fdd_check_bpb[i] = fdd_get_check_bpb(i); + } - /* Other removable devices category */ - memcpy(temp_cdrom_drives, cdrom_drives, CDROM_NUM * sizeof(cdrom_drive_t)); - for (i = 0; i < CDROM_NUM; i++) - { - if (cdrom_drives[i].bus_type == CDROM_BUS_ATAPI) - ide_tracking |= (2 << (cdrom_drives[i].ide_channel << 3)); - else if (cdrom_drives[i].bus_type == CDROM_BUS_SCSI) - scsi_tracking[cdrom_drives[i].scsi_device_id] |= (2 << (cdrom_drives[i].scsi_device_lun << 3)); - } - memcpy(temp_zip_drives, zip_drives, ZIP_NUM * sizeof(zip_drive_t)); - for (i = 0; i < ZIP_NUM; i++) - { - if (zip_drives[i].bus_type == ZIP_BUS_ATAPI) - ide_tracking |= (4 << (zip_drives[i].ide_channel << 3)); - else if (zip_drives[i].bus_type == ZIP_BUS_SCSI) - scsi_tracking[zip_drives[i].scsi_device_id] |= (4 << (zip_drives[i].scsi_device_lun << 3)); - } + /* Other removable devices category */ + memcpy(temp_cdrom_drives, cdrom_drives, CDROM_NUM * sizeof(cdrom_drive_t)); + for (i = 0; i < CDROM_NUM; i++) { + if (cdrom_drives[i].bus_type == CDROM_BUS_ATAPI) + ide_tracking |= (2 << (cdrom_drives[i].ide_channel << 3)); + else if (cdrom_drives[i].bus_type == CDROM_BUS_SCSI) + scsi_tracking[cdrom_drives[i].scsi_device_id >> 3] |= (1 << ((cdrom_drives[i].scsi_device_id & 0x07) << 3)); + } + memcpy(temp_zip_drives, zip_drives, ZIP_NUM * sizeof(zip_drive_t)); + for (i = 0; i < ZIP_NUM; i++) { + if (zip_drives[i].bus_type == ZIP_BUS_ATAPI) + ide_tracking |= (4 << (zip_drives[i].ide_channel << 3)); + else if (zip_drives[i].bus_type == ZIP_BUS_SCSI) + scsi_tracking[zip_drives[i].scsi_device_id >> 3] |= (1 << ((zip_drives[i].scsi_device_id & 0x07) << 3)); + } - temp_deviceconfig = 0; + temp_deviceconfig = 0; } /* This returns 1 if any variable has changed, 0 if not. */ -static int win_settings_changed(void) +static int +win_settings_changed(void) { - int i = 0; - int j = 0; + int i = 0; + int j = 0; - /* Machine category */ - i = i || (machine != temp_machine); - i = i || (cpu_manufacturer != temp_cpu_m); - i = i || (cpu_waitstates != temp_wait_states); - i = i || (cpu != temp_cpu); - i = i || (mem_size != temp_mem_size); + /* Machine category */ + i = i || (machine != temp_machine); + i = i || (cpu_manufacturer != temp_cpu_m); + i = i || (cpu_waitstates != temp_wait_states); + i = i || (cpu != temp_cpu); + i = i || (mem_size != temp_mem_size); #ifdef USE_DYNAREC - i = i || (temp_dynarec != cpu_use_dynarec); + i = i || (temp_dynarec != cpu_use_dynarec); #endif - i = i || (temp_fpu != enable_external_fpu); - i = i || (temp_sync != enable_sync); + i = i || (temp_fpu != enable_external_fpu); + i = i || (temp_sync != enable_sync); - /* Video category */ - i = i || (gfxcard != temp_gfxcard); - i = i || (video_speed != temp_video_speed); - i = i || (voodoo_enabled != temp_voodoo); + /* Video category */ + i = i || (gfxcard != temp_gfxcard); + i = i || (voodoo_enabled != temp_voodoo); - /* Input devices category */ - i = i || (mouse_type != temp_mouse); - i = i || (joystick_type != temp_joystick); + /* Input devices category */ + i = i || (mouse_type != temp_mouse); + i = i || (joystick_type != temp_joystick); - /* Sound category */ - i = i || (sound_card_current != temp_sound_card); - i = i || (midi_device_current != temp_midi_device); - i = i || (mpu401_standalone_enable != temp_mpu401); - i = i || (SSI2001 != temp_SSI2001); - i = i || (GAMEBLASTER != temp_GAMEBLASTER); - i = i || (GUS != temp_GUS); - i = i || (opl_type != temp_opl_type); - i = i || (sound_is_float != temp_float); + /* Sound category */ + i = i || (sound_card_current != temp_sound_card); + i = i || (midi_device_current != temp_midi_device); + i = i || (mpu401_standalone_enable != temp_mpu401); + i = i || (SSI2001 != temp_SSI2001); + i = i || (GAMEBLASTER != temp_GAMEBLASTER); + i = i || (GUS != temp_GUS); + i = i || (opl_type != temp_opl_type); + i = i || (sound_is_float != temp_float); - /* Network category */ - i = i || (network_type != temp_net_type); - i = i || strcmp(temp_pcap_dev, network_host); - i = i || (network_card != temp_net_card); + /* Network category */ + i = i || (network_type != temp_net_type); + i = i || strcmp(temp_pcap_dev, network_host); + i = i || (network_card != temp_net_card); - /* Ports category */ - for (j = 0; j < 3; j++) - i = i || strncmp(temp_lpt_device_names[j], lpt_device_names[j], sizeof(temp_lpt_device_names[j]) - 1); - i = i || (temp_serial[0] != serial_enabled[0]); - i = i || (temp_serial[1] != serial_enabled[1]); - i = i || (temp_lpt != lpt_enabled); + /* Ports category */ + for (j = 0; j < 3; j++) + i = i || strncmp(temp_lpt_device_names[j], lpt_device_names[j], sizeof(temp_lpt_device_names[j]) - 1); + i = i || (temp_serial[0] != serial_enabled[0]); + i = i || (temp_serial[1] != serial_enabled[1]); + i = i || (temp_lpt != lpt_enabled); - /* Peripherals category */ - i = i || (scsi_card_current != temp_scsi_card); - i = i || strncmp(temp_hdc_name, hdc_name, sizeof(temp_hdc_name) - 1); - i = i || (temp_ide_ter != ide_ter_enabled); - i = i || (temp_ide_qua != ide_qua_enabled); - i = i || (temp_bugger != bugger_enabled); + /* Peripherals category */ + i = i || (scsi_card_current != temp_scsi_card); + i = i || strncmp(temp_hdc_name, hdc_name, sizeof(temp_hdc_name) - 1); + i = i || (temp_ide_ter != ide_ter_enabled); + i = i || (temp_ide_qua != ide_qua_enabled); + i = i || (temp_bugger != bugger_enabled); - /* Hard disks category */ - i = i || memcmp(hdd, temp_hdd, HDD_NUM * sizeof(hard_disk_t)); + /* Hard disks category */ + i = i || memcmp(hdd, temp_hdd, HDD_NUM * sizeof(hard_disk_t)); - /* Floppy drives category */ - for (j = 0; j < FDD_NUM; j++) - { - i = i || (temp_fdd_types[j] != fdd_get_type(j)); - i = i || (temp_fdd_turbo[j] != fdd_get_turbo(j)); - i = i || (temp_fdd_check_bpb[j] != fdd_get_check_bpb(j)); - } + /* Floppy drives category */ + for (j = 0; j < FDD_NUM; j++) { + i = i || (temp_fdd_types[j] != fdd_get_type(j)); + i = i || (temp_fdd_turbo[j] != fdd_get_turbo(j)); + i = i || (temp_fdd_check_bpb[j] != fdd_get_check_bpb(j)); + } - /* Other removable devices category */ - i = i || memcmp(cdrom_drives, temp_cdrom_drives, CDROM_NUM * sizeof(cdrom_drive_t)); - i = i || memcmp(zip_drives, temp_zip_drives, ZIP_NUM * sizeof(zip_drive_t)); + /* Other removable devices category */ + i = i || memcmp(cdrom_drives, temp_cdrom_drives, CDROM_NUM * sizeof(cdrom_drive_t)); + i = i || memcmp(zip_drives, temp_zip_drives, ZIP_NUM * sizeof(zip_drive_t)); - i = i || !!temp_deviceconfig; + i = i || !!temp_deviceconfig; - return i; + return i; } -static int settings_msgbox_reset(void) +static int +settings_msgbox_reset(void) { - int i = 0; - int changed = 0; + int changed, i = 0; - changed = win_settings_changed(); + changed = win_settings_changed(); - if (changed) - { - i = settings_msgbox(MBX_QUESTION, (wchar_t *)IDS_2051); + if (changed) { + i = settings_msgbox(MBX_QUESTION, (wchar_t *)IDS_2051); - if (i == 1) return(1); /* no */ + if (i == 1) return(1); /* no */ - if (i < 0) return(0); /* cancel */ + if (i < 0) return(0); /* cancel */ - return(2); /* yes */ - } else { - return(1); - } + return(2); /* yes */ + } else + return(1); } /* This saves the settings back to the global variables. */ -static void win_settings_save(void) +static void +win_settings_save(void) { - int i = 0; + int i = 0; - pc_reset_hard_close(); + pc_reset_hard_close(); - /* Machine category */ - machine = temp_machine; - romset = machine_getromset(); - cpu_manufacturer = temp_cpu_m; - cpu_waitstates = temp_wait_states; - cpu = temp_cpu; - mem_size = temp_mem_size; + /* Machine category */ + machine = temp_machine; + romset = machine_getromset(); + cpu_manufacturer = temp_cpu_m; + cpu_waitstates = temp_wait_states; + cpu = temp_cpu; + mem_size = temp_mem_size; #ifdef USE_DYNAREC - cpu_use_dynarec = temp_dynarec; + cpu_use_dynarec = temp_dynarec; #endif - enable_external_fpu = temp_fpu; - enable_sync = temp_sync; + enable_external_fpu = temp_fpu; + enable_sync = temp_sync; - /* Video category */ - gfxcard = temp_gfxcard; - video_speed = temp_video_speed; - voodoo_enabled = temp_voodoo; + /* Video category */ + gfxcard = temp_gfxcard; + voodoo_enabled = temp_voodoo; - /* Input devices category */ - mouse_type = temp_mouse; - joystick_type = temp_joystick; + /* Input devices category */ + mouse_type = temp_mouse; + joystick_type = temp_joystick; - /* Sound category */ - sound_card_current = temp_sound_card; - midi_device_current = temp_midi_device; - mpu401_standalone_enable = temp_mpu401; - SSI2001 = temp_SSI2001; - GAMEBLASTER = temp_GAMEBLASTER; - GUS = temp_GUS; - opl_type = temp_opl_type; - sound_is_float = temp_float; + /* Sound category */ + sound_card_current = temp_sound_card; + midi_device_current = temp_midi_device; + mpu401_standalone_enable = temp_mpu401; + SSI2001 = temp_SSI2001; + GAMEBLASTER = temp_GAMEBLASTER; + GUS = temp_GUS; + opl_type = temp_opl_type; + sound_is_float = temp_float; - /* Network category */ - network_type = temp_net_type; - memset(network_host, '\0', sizeof(network_host)); - strcpy(network_host, temp_pcap_dev); - network_card = temp_net_card; + /* Network category */ + network_type = temp_net_type; + memset(network_host, '\0', sizeof(network_host)); + strcpy(network_host, temp_pcap_dev); + network_card = temp_net_card; - /* Ports category */ - for (i = 0; i < 3; i++) - strncpy(lpt_device_names[i], temp_lpt_device_names[i], sizeof(temp_lpt_device_names[i]) - 1); - serial_enabled[0] = temp_serial[0]; - serial_enabled[1] = temp_serial[1]; - lpt_enabled = temp_lpt; + /* Ports category */ + for (i = 0; i < 3; i++) + strncpy(lpt_device_names[i], temp_lpt_device_names[i], sizeof(temp_lpt_device_names[i]) - 1); + serial_enabled[0] = temp_serial[0]; + serial_enabled[1] = temp_serial[1]; + lpt_enabled = temp_lpt; - /* Peripherals category */ - scsi_card_current = temp_scsi_card; - if (hdc_name) { - free(hdc_name); - hdc_name = NULL; - } - hdc_name = (char *) malloc(sizeof(temp_hdc_name)); - strncpy(hdc_name, temp_hdc_name, sizeof(temp_hdc_name) - 1); - hdc_init(hdc_name); - ide_ter_enabled = temp_ide_ter; - ide_qua_enabled = temp_ide_qua; - bugger_enabled = temp_bugger; + /* Peripherals category */ + scsi_card_current = temp_scsi_card; + if (hdc_name) { + free(hdc_name); + hdc_name = NULL; + } + hdc_name = (char *) malloc(sizeof(temp_hdc_name)); + strncpy(hdc_name, temp_hdc_name, sizeof(temp_hdc_name) - 1); + hdc_init(hdc_name); + ide_ter_enabled = temp_ide_ter; + ide_qua_enabled = temp_ide_qua; + bugger_enabled = temp_bugger; - /* Hard disks category */ - memcpy(hdd, temp_hdd, HDD_NUM * sizeof(hard_disk_t)); + /* Hard disks category */ + memcpy(hdd, temp_hdd, HDD_NUM * sizeof(hard_disk_t)); - /* Floppy drives category */ - for (i = 0; i < FDD_NUM; i++) - { - fdd_set_type(i, temp_fdd_types[i]); - fdd_set_turbo(i, temp_fdd_turbo[i]); - fdd_set_check_bpb(i, temp_fdd_check_bpb[i]); - } + /* Floppy drives category */ + for (i = 0; i < FDD_NUM; i++) { + fdd_set_type(i, temp_fdd_types[i]); + fdd_set_turbo(i, temp_fdd_turbo[i]); + fdd_set_check_bpb(i, temp_fdd_check_bpb[i]); + } - /* Removable devices category */ - memcpy(cdrom_drives, temp_cdrom_drives, CDROM_NUM * sizeof(cdrom_drive_t)); - memcpy(zip_drives, temp_zip_drives, ZIP_NUM * sizeof(zip_drive_t)); + /* Removable devices category */ + memcpy(cdrom_drives, temp_cdrom_drives, CDROM_NUM * sizeof(cdrom_drive_t)); + memcpy(zip_drives, temp_zip_drives, ZIP_NUM * sizeof(zip_drive_t)); - /* Mark configuration as changed. */ - config_changed = 1; + /* Mark configuration as changed. */ + config_changed = 1; - pc_reset_hard_init(); + pc_reset_hard_init(); } -static void win_settings_machine_recalc_cpu(HWND hdlg) +static void +win_settings_machine_recalc_cpu(HWND hdlg) { - HWND h; - int temp_romset = 0; + HWND h; + int cpu_type, temp_romset; #ifdef USE_DYNAREC - int cpu_flags; -#endif - int cpu_type; - - temp_romset = machine_getromset_ex(temp_machine); - - h = GetDlgItem(hdlg, IDC_COMBO_WS); - cpu_type = machines[romstomachine[temp_romset]].cpu[temp_cpu_m].cpus[temp_cpu].cpu_type; - if ((cpu_type >= CPU_286) && (cpu_type <= CPU_386DX)) - { - EnableWindow(h, TRUE); - } - else - { - EnableWindow(h, FALSE); - } - -#ifdef USE_DYNAREC - h=GetDlgItem(hdlg, IDC_CHECK_DYNAREC); - cpu_flags = machines[romstomachine[temp_romset]].cpu[temp_cpu_m].cpus[temp_cpu].cpu_flags; - if (!(cpu_flags & CPU_SUPPORTS_DYNAREC) && (cpu_flags & CPU_REQUIRES_DYNAREC)) - { - fatal("Attempting to select a CPU that requires the recompiler and does not support it at the same time\n"); - } - if (!(cpu_flags & CPU_SUPPORTS_DYNAREC) || (cpu_flags & CPU_REQUIRES_DYNAREC)) - { - if (!(cpu_flags & CPU_SUPPORTS_DYNAREC)) - { - temp_dynarec = 0; - } - if (cpu_flags & CPU_REQUIRES_DYNAREC) - { - temp_dynarec = 1; - } - SendMessage(h, BM_SETCHECK, temp_dynarec, 0); - EnableWindow(h, FALSE); - } - else - { - EnableWindow(h, TRUE); - } + int cpu_flags; #endif - h = GetDlgItem(hdlg, IDC_CHECK_FPU); - cpu_type = machines[romstomachine[temp_romset]].cpu[temp_cpu_m].cpus[temp_cpu].cpu_type; - if ((cpu_type < CPU_i486DX) && (cpu_type >= CPU_286)) - { - EnableWindow(h, TRUE); - } - else if (cpu_type < CPU_286) - { - temp_fpu = 0; - EnableWindow(h, FALSE); - } - else - { - temp_fpu = 1; - EnableWindow(h, FALSE); - } - SendMessage(h, BM_SETCHECK, temp_fpu, 0); -} + temp_romset = machine_getromset_ex(temp_machine); - -static void win_settings_machine_recalc_cpu_m(HWND hdlg) -{ - HWND h; - int c = 0; - int temp_romset = 0; - LPTSTR lptsTemp; - char *stransi; - - temp_romset = machine_getromset_ex(temp_machine); - lptsTemp = (LPTSTR) malloc(512); - - h = GetDlgItem(hdlg, IDC_COMBO_CPU); - SendMessage(h, CB_RESETCONTENT, 0, 0); - c = 0; - while (machines[romstomachine[temp_romset]].cpu[temp_cpu_m].cpus[c].cpu_type != -1) - { - stransi = (char *) machines[romstomachine[temp_romset]].cpu[temp_cpu_m].cpus[c].name; - mbstowcs(lptsTemp, stransi, strlen(stransi) + 1); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)lptsTemp); - c++; - } + h = GetDlgItem(hdlg, IDC_COMBO_WS); + cpu_type = machines[romstomachine[temp_romset]].cpu[temp_cpu_m].cpus[temp_cpu].cpu_type; + if ((cpu_type >= CPU_286) && (cpu_type <= CPU_386DX)) EnableWindow(h, TRUE); - if (temp_cpu >= c) - { - temp_cpu = (c - 1); - } - SendMessage(h, CB_SETCURSEL, temp_cpu, 0); + else + EnableWindow(h, FALSE); - win_settings_machine_recalc_cpu(hdlg); +#ifdef USE_DYNAREC + h=GetDlgItem(hdlg, IDC_CHECK_DYNAREC); + cpu_flags = machines[romstomachine[temp_romset]].cpu[temp_cpu_m].cpus[temp_cpu].cpu_flags; + if (!(cpu_flags & CPU_SUPPORTS_DYNAREC) && (cpu_flags & CPU_REQUIRES_DYNAREC)) + fatal("Attempting to select a CPU that requires the recompiler and does not support it at the same time\n"); + if (!(cpu_flags & CPU_SUPPORTS_DYNAREC) || (cpu_flags & CPU_REQUIRES_DYNAREC)) { + if (!(cpu_flags & CPU_SUPPORTS_DYNAREC)) + temp_dynarec = 0; + if (cpu_flags & CPU_REQUIRES_DYNAREC) + temp_dynarec = 1; + SendMessage(h, BM_SETCHECK, temp_dynarec, 0); + EnableWindow(h, FALSE); + } else + EnableWindow(h, TRUE); +#endif - free(lptsTemp); + h = GetDlgItem(hdlg, IDC_CHECK_FPU); + cpu_type = machines[romstomachine[temp_romset]].cpu[temp_cpu_m].cpus[temp_cpu].cpu_type; + if ((cpu_type < CPU_i486DX) && (cpu_type >= CPU_286)) + EnableWindow(h, TRUE); + else if (cpu_type < CPU_286) { + temp_fpu = 0; + EnableWindow(h, FALSE); + } else { + temp_fpu = 1; + EnableWindow(h, FALSE); + } + SendMessage(h, BM_SETCHECK, temp_fpu, 0); } -static void win_settings_machine_recalc_machine(HWND hdlg) +static void +win_settings_machine_recalc_cpu_m(HWND hdlg) { - HWND h; - int c = 0; - int temp_romset = 0; - LPTSTR lptsTemp; - const char *stransi; - UDACCEL accel; + HWND h; + int c, temp_romset; + LPTSTR lptsTemp; + char *stransi; - temp_romset = machine_getromset_ex(temp_machine); - lptsTemp = (LPTSTR) malloc(512); + temp_romset = machine_getromset_ex(temp_machine); + lptsTemp = (LPTSTR) malloc(512); - h = GetDlgItem(hdlg, IDC_CONFIGURE_MACHINE); - if (machine_getdevice(temp_machine)) - { - EnableWindow(h, TRUE); - } - else - { - EnableWindow(h, FALSE); - } + h = GetDlgItem(hdlg, IDC_COMBO_CPU); + SendMessage(h, CB_RESETCONTENT, 0, 0); + c = 0; + while (machines[romstomachine[temp_romset]].cpu[temp_cpu_m].cpus[c].cpu_type != -1) { + stransi = (char *) machines[romstomachine[temp_romset]].cpu[temp_cpu_m].cpus[c].name; + mbstowcs(lptsTemp, stransi, strlen(stransi) + 1); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)lptsTemp); + c++; + } + EnableWindow(h, TRUE); + if (temp_cpu >= c) + temp_cpu = (c - 1); + SendMessage(h, CB_SETCURSEL, temp_cpu, 0); - h = GetDlgItem(hdlg, IDC_COMBO_CPU_TYPE); - SendMessage(h, CB_RESETCONTENT, 0, 0); - c = 0; - while (machines[romstomachine[temp_romset]].cpu[c].cpus != NULL && c < 4) - { - stransi = machines[romstomachine[temp_romset]].cpu[c].name; - mbstowcs(lptsTemp, stransi, strlen(stransi) + 1); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)lptsTemp); - c++; - } + win_settings_machine_recalc_cpu(hdlg); + + free(lptsTemp); +} + + +static void +win_settings_machine_recalc_machine(HWND hdlg) +{ + HWND h; + int c, temp_romset; + LPTSTR lptsTemp; + const char *stransi; + UDACCEL accel; + + temp_romset = machine_getromset_ex(temp_machine); + lptsTemp = (LPTSTR) malloc(512); + + h = GetDlgItem(hdlg, IDC_CONFIGURE_MACHINE); + if (machine_getdevice(temp_machine)) EnableWindow(h, TRUE); - if (temp_cpu_m >= c) - { - temp_cpu_m = (c - 1); - } - SendMessage(h, CB_SETCURSEL, temp_cpu_m, 0); - if (c == 1) - { - EnableWindow(h, FALSE); - } - else - { - EnableWindow(h, TRUE); - } + else + EnableWindow(h, FALSE); - win_settings_machine_recalc_cpu_m(hdlg); + h = GetDlgItem(hdlg, IDC_COMBO_CPU_TYPE); + SendMessage(h, CB_RESETCONTENT, 0, 0); + c = 0; + while (machines[romstomachine[temp_romset]].cpu[c].cpus != NULL && c < 4) { + stransi = machines[romstomachine[temp_romset]].cpu[c].name; + mbstowcs(lptsTemp, stransi, strlen(stransi) + 1); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)lptsTemp); + c++; + } + EnableWindow(h, TRUE); + if (temp_cpu_m >= c) + temp_cpu_m = (c - 1); + SendMessage(h, CB_SETCURSEL, temp_cpu_m, 0); + EnableWindow(h, (c == 1) ? FALSE : TRUE); - h = GetDlgItem(hdlg, IDC_MEMSPIN); - SendMessage(h, UDM_SETRANGE, 0, (machines[romstomachine[temp_romset]].min_ram << 16) | machines[romstomachine[temp_romset]].max_ram); - accel.nSec = 0; - accel.nInc = machines[romstomachine[temp_romset]].ram_granularity; - SendMessage(h, UDM_SETACCEL, 1, (LPARAM)&accel); - if (!(machines[romstomachine[temp_romset]].flags & MACHINE_AT) || (machines[romstomachine[temp_romset]].ram_granularity >= 128)) - { - SendMessage(h, UDM_SETPOS, 0, temp_mem_size); - h = GetDlgItem(hdlg, IDC_TEXT_MB); - SendMessage(h, WM_SETTEXT, 0, win_get_string(IDS_2094)); - } - else - { - SendMessage(h, UDM_SETPOS, 0, temp_mem_size / 1024); - h = GetDlgItem(hdlg, IDC_TEXT_MB); - SendMessage(h, WM_SETTEXT, 0, win_get_string(IDS_2087)); - } + win_settings_machine_recalc_cpu_m(hdlg); - free(lptsTemp); + h = GetDlgItem(hdlg, IDC_MEMSPIN); + SendMessage(h, UDM_SETRANGE, 0, (machines[romstomachine[temp_romset]].min_ram << 16) | machines[romstomachine[temp_romset]].max_ram); + accel.nSec = 0; + accel.nInc = machines[romstomachine[temp_romset]].ram_granularity; + SendMessage(h, UDM_SETACCEL, 1, (LPARAM)&accel); + if (!(machines[romstomachine[temp_romset]].flags & MACHINE_AT) || (machines[romstomachine[temp_romset]].ram_granularity >= 128)) { + SendMessage(h, UDM_SETPOS, 0, temp_mem_size); + h = GetDlgItem(hdlg, IDC_TEXT_MB); + SendMessage(h, WM_SETTEXT, 0, win_get_string(IDS_2094)); + } else { + SendMessage(h, UDM_SETPOS, 0, temp_mem_size / 1024); + h = GetDlgItem(hdlg, IDC_TEXT_MB); + SendMessage(h, WM_SETTEXT, 0, win_get_string(IDS_2087)); + } + + free(lptsTemp); } @@ -607,209 +611,185 @@ static BOOL CALLBACK #endif win_settings_machine_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) { - HWND h, h2; - int c = 0; - int d = 0; - LPTSTR lptsTemp; - char *stransi; + HWND h, h2; + int c, d; + LPTSTR lptsTemp; + char *stransi; - switch (message) - { - case WM_INITDIALOG: - lptsTemp = (LPTSTR) malloc(512); + switch (message) { + case WM_INITDIALOG: + lptsTemp = (LPTSTR) malloc(512); - h = GetDlgItem(hdlg, IDC_COMBO_MACHINE); - for (c = 0; c < ROM_MAX; c++) - { - romstolist[c] = 0; + h = GetDlgItem(hdlg, IDC_COMBO_MACHINE); + for (c = 0; c < ROM_MAX; c++) + romstolist[c] = 0; + c = d = 0; + while (machines[c].id != -1) { + if (romspresent[machines[c].id]) { + stransi = (char *)machines[c].name; + mbstowcs(lptsTemp, stransi, strlen(stransi) + 1); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); + machinetolist[c] = d; + listtomachine[d] = c; + romstolist[machines[c].id] = d; + romstomachine[machines[c].id] = c; + d++; } - c = d = 0; - while (machines[c].id != -1) - { - if (romspresent[machines[c].id]) - { - stransi = (char *)machines[c].name; - mbstowcs(lptsTemp, stransi, strlen(stransi) + 1); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); - machinetolist[c] = d; - listtomachine[d] = c; - romstolist[machines[c].id] = d; - romstomachine[machines[c].id] = c; - d++; + c++; + } + SendMessage(h, CB_SETCURSEL, machinetolist[temp_machine], 0); + + h = GetDlgItem(hdlg, IDC_COMBO_WS); + SendMessage(h, CB_ADDSTRING, 0, win_get_string(IDS_2099)); + + for (c = 0; c < 8; c++) { + wsprintf(lptsTemp, plat_get_string(2100), c); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); + } + + SendMessage(h, CB_SETCURSEL, temp_wait_states, 0); + +#ifdef USE_DYNAREC + h=GetDlgItem(hdlg, IDC_CHECK_DYNAREC); + SendMessage(h, BM_SETCHECK, temp_dynarec, 0); +#endif + + h = GetDlgItem(hdlg, IDC_MEMSPIN); + h2 = GetDlgItem(hdlg, IDC_MEMTEXT); + SendMessage(h, UDM_SETBUDDY, (WPARAM)h2, 0); + + h=GetDlgItem(hdlg, IDC_CHECK_SYNC); + SendMessage(h, BM_SETCHECK, temp_sync, 0); + + win_settings_machine_recalc_machine(hdlg); + + free(lptsTemp); + + return TRUE; + + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDC_COMBO_MACHINE: + if (HIWORD(wParam) == CBN_SELCHANGE) { + h = GetDlgItem(hdlg, IDC_COMBO_MACHINE); + temp_machine = listtomachine[SendMessage(h,CB_GETCURSEL,0,0)]; + + win_settings_machine_recalc_machine(hdlg); } - c++; - } - SendMessage(h, CB_SETCURSEL, machinetolist[temp_machine], 0); + break; + case IDC_COMBO_CPU_TYPE: + if (HIWORD(wParam) == CBN_SELCHANGE) { + h = GetDlgItem(hdlg, IDC_COMBO_CPU_TYPE); + temp_cpu_m = SendMessage(h, CB_GETCURSEL, 0, 0); - h = GetDlgItem(hdlg, IDC_COMBO_WS); - SendMessage(h, CB_ADDSTRING, 0, win_get_string(IDS_2131)); + temp_cpu = 0; + win_settings_machine_recalc_cpu_m(hdlg); + } + break; + case IDC_COMBO_CPU: + if (HIWORD(wParam) == CBN_SELCHANGE) { + h = GetDlgItem(hdlg, IDC_COMBO_CPU); + temp_cpu = SendMessage(h, CB_GETCURSEL, 0, 0); - for (c = 0; c < 8; c++) - { - wsprintf(lptsTemp, plat_get_string(2132), c); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); - } + win_settings_machine_recalc_cpu(hdlg); + } + break; + case IDC_CONFIGURE_MACHINE: + h = GetDlgItem(hdlg, IDC_COMBO_MACHINE); + temp_machine = listtomachine[SendMessage(h, CB_GETCURSEL, 0, 0)]; - SendMessage(h, CB_SETCURSEL, temp_wait_states, 0); + temp_deviceconfig |= deviceconfig_open(hdlg, (void *)machine_getdevice(temp_machine)); + break; + } + + return FALSE; + + case WM_SAVESETTINGS: + lptsTemp = (LPTSTR) malloc(512); + stransi = (char *)malloc(512); #ifdef USE_DYNAREC - h=GetDlgItem(hdlg, IDC_CHECK_DYNAREC); - SendMessage(h, BM_SETCHECK, temp_dynarec, 0); + h=GetDlgItem(hdlg, IDC_CHECK_DYNAREC); + temp_dynarec = SendMessage(h, BM_GETCHECK, 0, 0); #endif - h = GetDlgItem(hdlg, IDC_MEMSPIN); - h2 = GetDlgItem(hdlg, IDC_MEMTEXT); - SendMessage(h, UDM_SETBUDDY, (WPARAM)h2, 0); + h=GetDlgItem(hdlg, IDC_CHECK_SYNC); + temp_sync = SendMessage(h, BM_GETCHECK, 0, 0); - h=GetDlgItem(hdlg, IDC_CHECK_SYNC); - SendMessage(h, BM_SETCHECK, temp_sync, 0); + h=GetDlgItem(hdlg, IDC_CHECK_FPU); + temp_fpu = SendMessage(h, BM_GETCHECK, 0, 0); - win_settings_machine_recalc_machine(hdlg); + h = GetDlgItem(hdlg, IDC_COMBO_WS); + temp_wait_states = SendMessage(h, CB_GETCURSEL, 0, 0); - free(lptsTemp); + h = GetDlgItem(hdlg, IDC_MEMTEXT); + SendMessage(h, WM_GETTEXT, 255, (LPARAM) lptsTemp); + wcstombs(stransi, lptsTemp, 512); + sscanf(stransi, "%u", &temp_mem_size); + temp_mem_size &= ~(machines[temp_machine].ram_granularity - 1); + if (temp_mem_size < machines[temp_machine].min_ram) + temp_mem_size = machines[temp_machine].min_ram; + else if (temp_mem_size > machines[temp_machine].max_ram) + temp_mem_size = machines[temp_machine].max_ram; + if ((machines[temp_machine].flags & MACHINE_AT) && (machines[temp_machine].ram_granularity < 128)) + temp_mem_size *= 1024; + free(stransi); + free(lptsTemp); - return TRUE; + default: + return FALSE; + } - case WM_COMMAND: - switch (LOWORD(wParam)) - { - case IDC_COMBO_MACHINE: - if (HIWORD(wParam) == CBN_SELCHANGE) - { - h = GetDlgItem(hdlg, IDC_COMBO_MACHINE); - temp_machine = listtomachine[SendMessage(h,CB_GETCURSEL,0,0)]; - - win_settings_machine_recalc_machine(hdlg); - } - break; - case IDC_COMBO_CPU_TYPE: - if (HIWORD(wParam) == CBN_SELCHANGE) - { - h = GetDlgItem(hdlg, IDC_COMBO_CPU_TYPE); - temp_cpu_m = SendMessage(h, CB_GETCURSEL, 0, 0); - - temp_cpu = 0; - win_settings_machine_recalc_cpu_m(hdlg); - } - break; - case IDC_COMBO_CPU: - if (HIWORD(wParam) == CBN_SELCHANGE) - { - h = GetDlgItem(hdlg, IDC_COMBO_CPU); - temp_cpu = SendMessage(h, CB_GETCURSEL, 0, 0); - - win_settings_machine_recalc_cpu(hdlg); - } - break; - case IDC_CONFIGURE_MACHINE: - h = GetDlgItem(hdlg, IDC_COMBO_MACHINE); - temp_machine = listtomachine[SendMessage(h, CB_GETCURSEL, 0, 0)]; - - temp_deviceconfig |= deviceconfig_open(hdlg, (void *)machine_getdevice(temp_machine)); - break; - } - - return FALSE; - - case WM_SAVESETTINGS: - lptsTemp = (LPTSTR) malloc(512); - stransi = (char *)malloc(512); - -#ifdef USE_DYNAREC - h=GetDlgItem(hdlg, IDC_CHECK_DYNAREC); - temp_dynarec = SendMessage(h, BM_GETCHECK, 0, 0); -#endif - - h=GetDlgItem(hdlg, IDC_CHECK_SYNC); - temp_sync = SendMessage(h, BM_GETCHECK, 0, 0); - - h=GetDlgItem(hdlg, IDC_CHECK_FPU); - temp_fpu = SendMessage(h, BM_GETCHECK, 0, 0); - - h = GetDlgItem(hdlg, IDC_COMBO_WS); - temp_wait_states = SendMessage(h, CB_GETCURSEL, 0, 0); - - h = GetDlgItem(hdlg, IDC_MEMTEXT); - SendMessage(h, WM_GETTEXT, 255, (LPARAM) lptsTemp); - wcstombs(stransi, lptsTemp, 512); - sscanf(stransi, "%u", &temp_mem_size); - temp_mem_size &= ~(machines[temp_machine].ram_granularity - 1); - if (temp_mem_size < machines[temp_machine].min_ram) - { - temp_mem_size = machines[temp_machine].min_ram; - } - else if (temp_mem_size > machines[temp_machine].max_ram) - { - temp_mem_size = machines[temp_machine].max_ram; - } - if ((machines[temp_machine].flags & MACHINE_AT) && (machines[temp_machine].ram_granularity < 128)) - { - temp_mem_size *= 1024; - } - if (machines[temp_machine].flags & MACHINE_VIDEO) - { - gfxcard = GFX_INTERNAL; - } - free(stransi); - free(lptsTemp); - - default: - return FALSE; - } - - return FALSE; + return FALSE; } -static void recalc_vid_list(HWND hdlg) +static void +recalc_vid_list(HWND hdlg) { - HWND h = GetDlgItem(hdlg, IDC_COMBO_VIDEO); - int c = 0, d = 0; - int found_card = 0; - WCHAR szText[512]; - - SendMessage(h, CB_RESETCONTENT, 0, 0); - SendMessage(h, CB_SETCURSEL, 0, 0); - - while (1) - { - /* Skip "internal" if machine doesn't have it. */ - if (c==1 && !(machines[temp_machine].flags&MACHINE_VIDEO)) { - c++; - continue; + HWND h = GetDlgItem(hdlg, IDC_COMBO_VIDEO); + int c = 0, d = 0; + int found_card = 0; + WCHAR szText[512]; + + SendMessage(h, CB_RESETCONTENT, 0, 0); + SendMessage(h, CB_SETCURSEL, 0, 0); + + while (1) { + /* Skip "internal" if machine doesn't have it. */ + if ((c == 1) && !(machines[temp_machine].flags&MACHINE_VIDEO)) { + c++; + continue; + } + + char *s = video_card_getname(c); + + if (!s[0]) + break; + + if (video_card_available(c) && gfx_present[video_new_to_old(c)] && + device_is_valid(video_card_getdevice(c), machines[temp_machine].flags)) { + mbstowcs(szText, s, strlen(s) + 1); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) szText); + if (video_new_to_old(c) == temp_gfxcard) { + SendMessage(h, CB_SETCURSEL, d, 0); + found_card = 1; } - char *s = video_card_getname(c); + d++; + } - if (!s[0]) - break; + c++; + } + if (!found_card) + SendMessage(h, CB_SETCURSEL, 0, 0); + EnableWindow(h, machines[temp_machine].fixed_gfxcard ? FALSE : TRUE); - if (video_card_available(c) && gfx_present[video_new_to_old(c)] && - device_is_valid(video_card_getdevice(c), machines[temp_machine].flags)) - { - mbstowcs(szText, s, strlen(s) + 1); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) szText); - if (video_new_to_old(c) == temp_gfxcard) - { + h = GetDlgItem(hdlg, IDC_CHECK_VOODOO); + EnableWindow(h, (machines[temp_machine].flags & MACHINE_PCI) ? TRUE : FALSE); - SendMessage(h, CB_SETCURSEL, d, 0); - found_card = 1; - } - - d++; - } - - c++; - } - if (!found_card) - SendMessage(h, CB_SETCURSEL, 0, 0); - EnableWindow(h, machines[temp_machine].fixed_gfxcard ? FALSE : TRUE); - - h = GetDlgItem(hdlg, IDC_CHECK_VOODOO); - EnableWindow(h, (machines[temp_machine].flags & MACHINE_PCI) ? TRUE : FALSE); - - h = GetDlgItem(hdlg, IDC_BUTTON_VOODOO); - EnableWindow(h, ((machines[temp_machine].flags & MACHINE_PCI) && temp_voodoo) ? TRUE : FALSE); + h = GetDlgItem(hdlg, IDC_BUTTON_VOODOO); + EnableWindow(h, ((machines[temp_machine].flags & MACHINE_PCI) && temp_voodoo) ? TRUE : FALSE); } @@ -820,140 +800,118 @@ static BOOL CALLBACK #endif win_settings_video_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) { - HWND h; - LPTSTR lptsTemp; - char *stransi; - int gfx = 0; + HWND h; + LPTSTR lptsTemp; + char *stransi; + int gfx; - switch (message) - { - case WM_INITDIALOG: - lptsTemp = (LPTSTR) malloc(512); - stransi = (char *) malloc(512); + switch (message) { + case WM_INITDIALOG: + lptsTemp = (LPTSTR) malloc(512); + stransi = (char *) malloc(512); - recalc_vid_list(hdlg); + recalc_vid_list(hdlg); - h = GetDlgItem(hdlg, IDC_COMBO_VIDEO_SPEED); - SendMessage(h, CB_ADDSTRING, 0, win_get_string(IDS_2131)); - SendMessage(h, CB_ADDSTRING, 0, win_get_string(IDS_2133)); - SendMessage(h, CB_ADDSTRING, 0, win_get_string(IDS_2134)); - SendMessage(h, CB_ADDSTRING, 0, win_get_string(IDS_2135)); - SendMessage(h, CB_ADDSTRING, 0, win_get_string(IDS_2136)); - SendMessage(h, CB_ADDSTRING, 0, win_get_string(IDS_2137)); - SendMessage(h, CB_ADDSTRING, 0, win_get_string(IDS_2138)); - SendMessage(h, CB_SETCURSEL, temp_video_speed + 1, 0); + h=GetDlgItem(hdlg, IDC_CHECK_VOODOO); + SendMessage(h, BM_SETCHECK, temp_voodoo, 0); - h=GetDlgItem(hdlg, IDC_CHECK_VOODOO); - SendMessage(h, BM_SETCHECK, temp_voodoo, 0); + h = GetDlgItem(hdlg, IDC_COMBO_VIDEO); + SendMessage(h, CB_GETLBTEXT, SendMessage(h, CB_GETCURSEL, 0, 0), (LPARAM) lptsTemp); + wcstombs(stransi, lptsTemp, 512); + gfx = video_card_getid(stransi); - h = GetDlgItem(hdlg, IDC_COMBO_VIDEO); - SendMessage(h, CB_GETLBTEXT, SendMessage(h, CB_GETCURSEL, 0, 0), (LPARAM) lptsTemp); - wcstombs(stransi, lptsTemp, 512); - gfx = video_card_getid(stransi); + h = GetDlgItem(hdlg, IDC_CONFIGURE_VID); + if (video_card_has_config(gfx)) + EnableWindow(h, TRUE); + else + EnableWindow(h, FALSE); - h = GetDlgItem(hdlg, IDC_CONFIGURE_VID); - if (video_card_has_config(gfx)) - { - EnableWindow(h, TRUE); - } - else - { - EnableWindow(h, FALSE); - } + free(stransi); + free(lptsTemp); - free(stransi); - free(lptsTemp); + return TRUE; - return TRUE; + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDC_COMBO_VIDEO: + lptsTemp = (LPTSTR) malloc(512); + stransi = (char *) malloc(512); - case WM_COMMAND: - switch (LOWORD(wParam)) - { - case IDC_COMBO_VIDEO: - lptsTemp = (LPTSTR) malloc(512); - stransi = (char *) malloc(512); + h = GetDlgItem(hdlg, IDC_COMBO_VIDEO); + SendMessage(h, CB_GETLBTEXT, SendMessage(h, CB_GETCURSEL, 0, 0), (LPARAM) lptsTemp); + wcstombs(stransi, lptsTemp, 512); + gfx = video_card_getid(stransi); + temp_gfxcard = video_new_to_old(gfx); - h = GetDlgItem(hdlg, IDC_COMBO_VIDEO); - SendMessage(h, CB_GETLBTEXT, SendMessage(h, CB_GETCURSEL, 0, 0), (LPARAM) lptsTemp); - wcstombs(stransi, lptsTemp, 512); - gfx = video_card_getid(stransi); - temp_gfxcard = video_new_to_old(gfx); + h = GetDlgItem(hdlg, IDC_CONFIGURE_VID); + if (video_card_has_config(gfx)) + EnableWindow(h, TRUE); + else + EnableWindow(h, FALSE); - h = GetDlgItem(hdlg, IDC_CONFIGURE_VID); - if (video_card_has_config(gfx)) - { - EnableWindow(h, TRUE); - } - else - { - EnableWindow(h, FALSE); - } + free(stransi); + free(lptsTemp); + break; - free(stransi); - free(lptsTemp); - break; + case IDC_CHECK_VOODOO: + h = GetDlgItem(hdlg, IDC_CHECK_VOODOO); + temp_voodoo = SendMessage(h, BM_GETCHECK, 0, 0); - case IDC_CHECK_VOODOO: - h = GetDlgItem(hdlg, IDC_CHECK_VOODOO); - temp_voodoo = SendMessage(h, BM_GETCHECK, 0, 0); + h = GetDlgItem(hdlg, IDC_BUTTON_VOODOO); + EnableWindow(h, temp_voodoo ? TRUE : FALSE); + break; - h = GetDlgItem(hdlg, IDC_BUTTON_VOODOO); - EnableWindow(h, temp_voodoo ? TRUE : FALSE); - break; + case IDC_BUTTON_VOODOO: + temp_deviceconfig |= deviceconfig_open(hdlg, (void *)&voodoo_device); + break; - case IDC_BUTTON_VOODOO: - temp_deviceconfig |= deviceconfig_open(hdlg, (void *)&voodoo_device); - break; + case IDC_CONFIGURE_VID: + lptsTemp = (LPTSTR) malloc(512); + stransi = (char *) malloc(512); - case IDC_CONFIGURE_VID: - lptsTemp = (LPTSTR) malloc(512); - stransi = (char *) malloc(512); + h = GetDlgItem(hdlg, IDC_COMBO_VIDEO); + SendMessage(h, CB_GETLBTEXT, SendMessage(h, CB_GETCURSEL, 0, 0), (LPARAM) lptsTemp); + wcstombs(stransi, lptsTemp, 512); + temp_deviceconfig |= deviceconfig_open(hdlg, (void *)video_card_getdevice(video_card_getid(stransi))); - h = GetDlgItem(hdlg, IDC_COMBO_VIDEO); - SendMessage(h, CB_GETLBTEXT, SendMessage(h, CB_GETCURSEL, 0, 0), (LPARAM) lptsTemp); - wcstombs(stransi, lptsTemp, 512); - temp_deviceconfig |= deviceconfig_open(hdlg, (void *)video_card_getdevice(video_card_getid(stransi))); + free(stransi); + free(lptsTemp); + break; + } + return FALSE; - free(stransi); - free(lptsTemp); - break; - } - return FALSE; + case WM_SAVESETTINGS: + lptsTemp = (LPTSTR) malloc(512); + stransi = (char *) malloc(512); - case WM_SAVESETTINGS: - lptsTemp = (LPTSTR) malloc(512); - stransi = (char *) malloc(512); + h = GetDlgItem(hdlg, IDC_COMBO_VIDEO); + SendMessage(h, CB_GETLBTEXT, SendMessage(h, CB_GETCURSEL, 0, 0), (LPARAM) lptsTemp); + wcstombs(stransi, lptsTemp, 512); + temp_gfxcard = video_new_to_old(video_card_getid(stransi)); - h = GetDlgItem(hdlg, IDC_COMBO_VIDEO); - SendMessage(h, CB_GETLBTEXT, SendMessage(h, CB_GETCURSEL, 0, 0), (LPARAM) lptsTemp); - wcstombs(stransi, lptsTemp, 512); - temp_gfxcard = video_new_to_old(video_card_getid(stransi)); + h = GetDlgItem(hdlg, IDC_CHECK_VOODOO); + temp_voodoo = SendMessage(h, BM_GETCHECK, 0, 0); - h = GetDlgItem(hdlg, IDC_COMBO_VIDEO_SPEED); - temp_video_speed = SendMessage(h, CB_GETCURSEL, 0, 0) - 1; + free(stransi); + free(lptsTemp); - h = GetDlgItem(hdlg, IDC_CHECK_VOODOO); - temp_voodoo = SendMessage(h, BM_GETCHECK, 0, 0); - - free(stransi); - free(lptsTemp); - - default: - return FALSE; - } - return FALSE; + default: + return FALSE; + } + return FALSE; } -static int mouse_valid(int num, int m) +static int +mouse_valid(int num, int m) { - const device_t *dev; + const device_t *dev; - if ((num == MOUSE_TYPE_INTERNAL) && - !(machines[m].flags & MACHINE_MOUSE)) return(0); + if ((num == MOUSE_TYPE_INTERNAL) && + !(machines[m].flags & MACHINE_MOUSE)) return(0); - dev = mouse_get_device(num); - return(device_is_valid(dev, machines[m].flags)); + dev = mouse_get_device(num); + return(device_is_valid(dev, machines[m].flags)); } @@ -964,182 +922,163 @@ static BOOL CALLBACK #endif win_settings_input_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) { - wchar_t str[128]; - HWND h; - int c = 0; - int d = 0; + wchar_t str[128]; + HWND h; + int c, d; - switch (message) - { - case WM_INITDIALOG: - h = GetDlgItem(hdlg, IDC_COMBO_MOUSE); - c = d = 0; - for (c = 0; c < mouse_get_ndev(); c++) - { - settings_mouse_to_list[c] = d; + switch (message) { + case WM_INITDIALOG: + h = GetDlgItem(hdlg, IDC_COMBO_MOUSE); + c = d = 0; + for (c = 0; c < mouse_get_ndev(); c++) { + settings_device_to_list[c] = d; - if (mouse_valid(c, temp_machine)) - { - mbstowcs(str, mouse_get_name(c), sizeof_w(str)); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)str); + if (mouse_valid(c, temp_machine)) { + mbstowcs(str, mouse_get_name(c), sizeof_w(str)); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM)str); - settings_list_to_mouse[d] = c; - d++; - } + settings_list_to_device[d] = c; + d++; } + } - SendMessage(h, CB_SETCURSEL, settings_mouse_to_list[temp_mouse], 0); + SendMessage(h, CB_SETCURSEL, settings_device_to_list[temp_mouse], 0); - h = GetDlgItem(hdlg, IDC_CONFIGURE_MOUSE); - if (mouse_has_config(temp_mouse)) - { - EnableWindow(h, TRUE); - } - else - { - EnableWindow(h, FALSE); - } - - h = GetDlgItem(hdlg, IDC_COMBO_JOYSTICK); - c = 0; - while (joystick_get_name(c)) - { - SendMessage(h, CB_ADDSTRING, 0, win_get_string(2144 + c)); - c++; - } + h = GetDlgItem(hdlg, IDC_CONFIGURE_MOUSE); + if (mouse_has_config(temp_mouse)) EnableWindow(h, TRUE); - SendMessage(h, CB_SETCURSEL, temp_joystick, 0); + else + EnableWindow(h, FALSE); - h = GetDlgItem(hdlg, IDC_JOY1); - EnableWindow(h, (joystick_get_max_joysticks(temp_joystick) >= 1) ? TRUE : FALSE); - h = GetDlgItem(hdlg, IDC_JOY2); - EnableWindow(h, (joystick_get_max_joysticks(temp_joystick) >= 2) ? TRUE : FALSE); - h = GetDlgItem(hdlg, IDC_JOY3); - EnableWindow(h, (joystick_get_max_joysticks(temp_joystick) >= 3) ? TRUE : FALSE); - h = GetDlgItem(hdlg, IDC_JOY4); - EnableWindow(h, (joystick_get_max_joysticks(temp_joystick) >= 4) ? TRUE : FALSE); + h = GetDlgItem(hdlg, IDC_COMBO_JOYSTICK); + c = 0; + while (joystick_get_name(c)) { + SendMessage(h, CB_ADDSTRING, 0, win_get_string(2105 + c)); + c++; + } + EnableWindow(h, TRUE); + SendMessage(h, CB_SETCURSEL, temp_joystick, 0); - return TRUE; + h = GetDlgItem(hdlg, IDC_JOY1); + EnableWindow(h, (joystick_get_max_joysticks(temp_joystick) >= 1) ? TRUE : FALSE); + h = GetDlgItem(hdlg, IDC_JOY2); + EnableWindow(h, (joystick_get_max_joysticks(temp_joystick) >= 2) ? TRUE : FALSE); + h = GetDlgItem(hdlg, IDC_JOY3); + EnableWindow(h, (joystick_get_max_joysticks(temp_joystick) >= 3) ? TRUE : FALSE); + h = GetDlgItem(hdlg, IDC_JOY4); + EnableWindow(h, (joystick_get_max_joysticks(temp_joystick) >= 4) ? TRUE : FALSE); - case WM_COMMAND: - switch (LOWORD(wParam)) - { - case IDC_COMBO_MOUSE: - h = GetDlgItem(hdlg, IDC_COMBO_MOUSE); - temp_mouse = settings_list_to_mouse[SendMessage(h, CB_GETCURSEL, 0, 0)]; + return TRUE; - h = GetDlgItem(hdlg, IDC_CONFIGURE_MOUSE); - if (mouse_has_config(temp_mouse)) - { - EnableWindow(h, TRUE); - } - else - { - EnableWindow(h, FALSE); - } - break; + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDC_COMBO_MOUSE: + h = GetDlgItem(hdlg, IDC_COMBO_MOUSE); + temp_mouse = settings_list_to_device[SendMessage(h, CB_GETCURSEL, 0, 0)]; - case IDC_CONFIGURE_MOUSE: - h = GetDlgItem(hdlg, IDC_COMBO_MOUSE); - temp_mouse = settings_list_to_mouse[SendMessage(h, CB_GETCURSEL, 0, 0)]; - temp_deviceconfig |= deviceconfig_open(hdlg, (void *)mouse_get_device(temp_mouse)); - break; + h = GetDlgItem(hdlg, IDC_CONFIGURE_MOUSE); + if (mouse_has_config(temp_mouse)) + EnableWindow(h, TRUE); + else + EnableWindow(h, FALSE); + break; - case IDC_COMBO_JOYSTICK: - h = GetDlgItem(hdlg, IDC_COMBO_JOYSTICK); - temp_joystick = SendMessage(h, CB_GETCURSEL, 0, 0); + case IDC_CONFIGURE_MOUSE: + h = GetDlgItem(hdlg, IDC_COMBO_MOUSE); + temp_mouse = settings_list_to_device[SendMessage(h, CB_GETCURSEL, 0, 0)]; + temp_deviceconfig |= deviceconfig_open(hdlg, (void *)mouse_get_device(temp_mouse)); + break; - h = GetDlgItem(hdlg, IDC_JOY1); - EnableWindow(h, (joystick_get_max_joysticks(temp_joystick) >= 1) ? TRUE : FALSE); - h = GetDlgItem(hdlg, IDC_JOY2); - EnableWindow(h, (joystick_get_max_joysticks(temp_joystick) >= 2) ? TRUE : FALSE); - h = GetDlgItem(hdlg, IDC_JOY3); - EnableWindow(h, (joystick_get_max_joysticks(temp_joystick) >= 3) ? TRUE : FALSE); - h = GetDlgItem(hdlg, IDC_JOY4); - EnableWindow(h, (joystick_get_max_joysticks(temp_joystick) >= 4) ? TRUE : FALSE); - break; + case IDC_COMBO_JOYSTICK: + h = GetDlgItem(hdlg, IDC_COMBO_JOYSTICK); + temp_joystick = SendMessage(h, CB_GETCURSEL, 0, 0); - case IDC_JOY1: - h = GetDlgItem(hdlg, IDC_COMBO_JOYSTICK); - temp_joystick = SendMessage(h, CB_GETCURSEL, 0, 0); - temp_deviceconfig |= joystickconfig_open(hdlg, 0, temp_joystick); - break; + h = GetDlgItem(hdlg, IDC_JOY1); + EnableWindow(h, (joystick_get_max_joysticks(temp_joystick) >= 1) ? TRUE : FALSE); + h = GetDlgItem(hdlg, IDC_JOY2); + EnableWindow(h, (joystick_get_max_joysticks(temp_joystick) >= 2) ? TRUE : FALSE); + h = GetDlgItem(hdlg, IDC_JOY3); + EnableWindow(h, (joystick_get_max_joysticks(temp_joystick) >= 3) ? TRUE : FALSE); + h = GetDlgItem(hdlg, IDC_JOY4); + EnableWindow(h, (joystick_get_max_joysticks(temp_joystick) >= 4) ? TRUE : FALSE); + break; - case IDC_JOY2: - h = GetDlgItem(hdlg, IDC_COMBO_JOYSTICK); - temp_joystick = SendMessage(h, CB_GETCURSEL, 0, 0); - temp_deviceconfig |= joystickconfig_open(hdlg, 1, temp_joystick); - break; + case IDC_JOY1: + h = GetDlgItem(hdlg, IDC_COMBO_JOYSTICK); + temp_joystick = SendMessage(h, CB_GETCURSEL, 0, 0); + temp_deviceconfig |= joystickconfig_open(hdlg, 0, temp_joystick); + break; - case IDC_JOY3: - h = GetDlgItem(hdlg, IDC_COMBO_JOYSTICK); - temp_joystick = SendMessage(h, CB_GETCURSEL, 0, 0); - temp_deviceconfig |= joystickconfig_open(hdlg, 2, temp_joystick); - break; + case IDC_JOY2: + h = GetDlgItem(hdlg, IDC_COMBO_JOYSTICK); + temp_joystick = SendMessage(h, CB_GETCURSEL, 0, 0); + temp_deviceconfig |= joystickconfig_open(hdlg, 1, temp_joystick); + break; - case IDC_JOY4: - h = GetDlgItem(hdlg, IDC_COMBO_JOYSTICK); - temp_joystick = SendMessage(h, CB_GETCURSEL, 0, 0); - temp_deviceconfig |= joystickconfig_open(hdlg, 3, temp_joystick); - break; - } - return FALSE; + case IDC_JOY3: + h = GetDlgItem(hdlg, IDC_COMBO_JOYSTICK); + temp_joystick = SendMessage(h, CB_GETCURSEL, 0, 0); + temp_deviceconfig |= joystickconfig_open(hdlg, 2, temp_joystick); + break; - case WM_SAVESETTINGS: - h = GetDlgItem(hdlg, IDC_COMBO_MOUSE); - temp_mouse = settings_list_to_mouse[SendMessage(h, CB_GETCURSEL, 0, 0)]; + case IDC_JOY4: + h = GetDlgItem(hdlg, IDC_COMBO_JOYSTICK); + temp_joystick = SendMessage(h, CB_GETCURSEL, 0, 0); + temp_deviceconfig |= joystickconfig_open(hdlg, 3, temp_joystick); + break; + } + return FALSE; - h = GetDlgItem(hdlg, IDC_COMBO_JOYSTICK); - temp_joystick = SendMessage(h, CB_GETCURSEL, 0, 0); + case WM_SAVESETTINGS: + h = GetDlgItem(hdlg, IDC_COMBO_MOUSE); + temp_mouse = settings_list_to_device[SendMessage(h, CB_GETCURSEL, 0, 0)]; - default: - return FALSE; - } - return FALSE; + h = GetDlgItem(hdlg, IDC_COMBO_JOYSTICK); + temp_joystick = SendMessage(h, CB_GETCURSEL, 0, 0); + + default: + return FALSE; + } + return FALSE; } -int mpu401_present(void) +static int +mpu401_present(void) { - char *n; + char *n; - n = sound_card_get_internal_name(temp_sound_card); - if (n != NULL) - { - if (!strcmp(n, "sb16") || !strcmp(n, "sbawe32")) - { - return 1; - } - } + n = sound_card_get_internal_name(temp_sound_card); + if (n != NULL) { + if (!strcmp(n, "sb16") || !strcmp(n, "sbawe32")) + return 1; + } - return temp_mpu401 ? 1 : 0; + return temp_mpu401 ? 1 : 0; } -int mpu401_standalone_allow(void) + +int +mpu401_standalone_allow(void) { - char *n, *md; + char *n, *md; - n = sound_card_get_internal_name(temp_sound_card); - md = midi_device_get_internal_name(temp_midi_device); - if (n != NULL) - { - if (!strcmp(n, "sb16") || !strcmp(n, "sbawe32")) - { - return 0; - } - } + n = sound_card_get_internal_name(temp_sound_card); + md = midi_device_get_internal_name(temp_midi_device); + if (n != NULL) { + if (!strcmp(n, "sb16") || !strcmp(n, "sbawe32")) + return 0; + } - if (md != NULL) - { - if (!strcmp(md, "none")) - { - return 0; - } - } + if (md != NULL) { + if (!strcmp(md, "none")) + return 0; + } - return 1; + return 1; } + #ifdef __amd64__ static LRESULT CALLBACK #else @@ -1147,239 +1086,202 @@ static BOOL CALLBACK #endif win_settings_sound_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) { - HWND h; - int c = 0; - int d = 0; - LPTSTR lptsTemp; - const device_t *sound_dev; - char *s; + HWND h; + int c, d; + LPTSTR lptsTemp; + const device_t *sound_dev; + char *s; - switch (message) - { - case WM_INITDIALOG: - lptsTemp = (LPTSTR) malloc(512); + switch (message) { + case WM_INITDIALOG: + lptsTemp = (LPTSTR) malloc(512); - h = GetDlgItem(hdlg, IDC_COMBO_SOUND); - c = d = 0; - while (1) - { - s = sound_card_getname(c); + h = GetDlgItem(hdlg, IDC_COMBO_SOUND); + c = d = 0; + while (1) { + s = sound_card_getname(c); - if (!s[0]) - { - break; - } + if (!s[0]) + break; - settings_sound_to_list[c] = d; + settings_device_to_list[c] = d; - if (sound_card_available(c)) - { - sound_dev = sound_card_getdevice(c); + if (sound_card_available(c)) { + sound_dev = sound_card_getdevice(c); - if (device_is_valid(sound_dev, machines[temp_machine].flags)) - { - if (c == 0) - { - SendMessage(h, CB_ADDSTRING, 0, win_get_string(IDS_2152)); - } - else - { - mbstowcs(lptsTemp, s, strlen(s) + 1); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); - } - settings_list_to_sound[d] = c; - d++; - } - } - - c++; - } - SendMessage(h, CB_SETCURSEL, settings_sound_to_list[temp_sound_card], 0); - - EnableWindow(h, d ? TRUE : FALSE); - - h = GetDlgItem(hdlg, IDC_CONFIGURE_SND); - if (sound_card_has_config(temp_sound_card)) - { - EnableWindow(h, TRUE); - } - else - { - EnableWindow(h, FALSE); - } - - h = GetDlgItem(hdlg, IDC_COMBO_MIDI); - c = d = 0; - while (1) - { - s = midi_device_getname(c); - - if (!s[0]) - { - break; - } - - settings_midi_to_list[c] = d; - - if (midi_device_available(c)) - { + if (device_is_valid(sound_dev, machines[temp_machine].flags)) { if (c == 0) - { - SendMessage(h, CB_ADDSTRING, 0, win_get_string(IDS_2152)); - } - else - { + SendMessage(h, CB_ADDSTRING, 0, win_get_string(IDS_2112)); + else { mbstowcs(lptsTemp, s, strlen(s) + 1); SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); } - settings_list_to_midi[d] = c; + settings_list_to_device[d] = c; d++; } - - c++; - } - SendMessage(h, CB_SETCURSEL, settings_midi_to_list[temp_midi_device], 0); - - h = GetDlgItem(hdlg, IDC_CONFIGURE_MIDI); - if (midi_device_has_config(temp_midi_device)) - { - EnableWindow(h, TRUE); - } - else - { - EnableWindow(h, FALSE); } - h = GetDlgItem(hdlg, IDC_CHECK_MPU401); - SendMessage(h, BM_SETCHECK, temp_mpu401, 0); - EnableWindow(h, mpu401_standalone_allow() ? TRUE : FALSE); + c++; + } + SendMessage(h, CB_SETCURSEL, settings_device_to_list[temp_sound_card], 0); - h = GetDlgItem(hdlg, IDC_CONFIGURE_MPU401); - EnableWindow(h, (mpu401_standalone_allow() && temp_mpu401) ? TRUE : FALSE); + EnableWindow(h, d ? TRUE : FALSE); - h=GetDlgItem(hdlg, IDC_CHECK_CMS); - SendMessage(h, BM_SETCHECK, temp_GAMEBLASTER, 0); + h = GetDlgItem(hdlg, IDC_CONFIGURE_SND); + EnableWindow(h, sound_card_has_config(temp_sound_card) ? TRUE : FALSE); - h=GetDlgItem(hdlg, IDC_CHECK_GUS); - SendMessage(h, BM_SETCHECK, temp_GUS, 0); + h = GetDlgItem(hdlg, IDC_COMBO_MIDI); + c = d = 0; + while (1) { + s = midi_device_getname(c); - h=GetDlgItem(hdlg, IDC_CHECK_SSI); - SendMessage(h, BM_SETCHECK, temp_SSI2001, 0); + if (!s[0]) + break; - h=GetDlgItem(hdlg, IDC_CHECK_NUKEDOPL); - SendMessage(h, BM_SETCHECK, temp_opl_type, 0); + settings_midi_to_list[c] = d; - h=GetDlgItem(hdlg, IDC_CHECK_FLOAT); - SendMessage(h, BM_SETCHECK, temp_float, 0); - - free(lptsTemp); - - return TRUE; - - case WM_COMMAND: - switch (LOWORD(wParam)) - { - case IDC_COMBO_SOUND: - h = GetDlgItem(hdlg, IDC_COMBO_SOUND); - temp_sound_card = settings_list_to_sound[SendMessage(h, CB_GETCURSEL, 0, 0)]; - - h = GetDlgItem(hdlg, IDC_CONFIGURE_SND); - if (sound_card_has_config(temp_sound_card)) - { - EnableWindow(h, TRUE); - } - else - { - EnableWindow(h, FALSE); - } - - h = GetDlgItem(hdlg, IDC_CHECK_MPU401); - SendMessage(h, BM_SETCHECK, temp_mpu401, 0); - EnableWindow(h, mpu401_standalone_allow() ? TRUE : FALSE); - - h = GetDlgItem(hdlg, IDC_CONFIGURE_MPU401); - EnableWindow(h, (mpu401_standalone_allow() && temp_mpu401) ? TRUE : FALSE); - break; - - case IDC_CONFIGURE_SND: - h = GetDlgItem(hdlg, IDC_COMBO_SOUND); - temp_sound_card = settings_list_to_sound[SendMessage(h, CB_GETCURSEL, 0, 0)]; - - temp_deviceconfig |= deviceconfig_open(hdlg, (void *)sound_card_getdevice(temp_sound_card)); - break; - - case IDC_COMBO_MIDI: - h = GetDlgItem(hdlg, IDC_COMBO_MIDI); - temp_midi_device = settings_list_to_midi[SendMessage(h, CB_GETCURSEL, 0, 0)]; - - h = GetDlgItem(hdlg, IDC_CONFIGURE_MIDI); - if (midi_device_has_config(temp_midi_device)) - { - EnableWindow(h, TRUE); - } - else - { - EnableWindow(h, FALSE); - } - - h = GetDlgItem(hdlg, IDC_CHECK_MPU401); - SendMessage(h, BM_SETCHECK, temp_mpu401, 0); - EnableWindow(h, mpu401_standalone_allow() ? TRUE : FALSE); - - h = GetDlgItem(hdlg, IDC_CONFIGURE_MPU401); - EnableWindow(h, (mpu401_standalone_allow() && temp_mpu401) ? TRUE : FALSE); - break; - - case IDC_CONFIGURE_MIDI: - h = GetDlgItem(hdlg, IDC_COMBO_MIDI); - temp_midi_device = settings_list_to_midi[SendMessage(h, CB_GETCURSEL, 0, 0)]; - - temp_deviceconfig |= deviceconfig_open(hdlg, (void *)midi_device_getdevice(temp_midi_device)); - break; - - case IDC_CHECK_MPU401: - h = GetDlgItem(hdlg, IDC_CHECK_MPU401); - temp_mpu401 = SendMessage(h, BM_GETCHECK, 0, 0); - - h = GetDlgItem(hdlg, IDC_CONFIGURE_MPU401); - EnableWindow(h, mpu401_present() ? TRUE : FALSE); - break; - - case IDC_CONFIGURE_MPU401: - temp_deviceconfig |= deviceconfig_open(hdlg, (void *)&mpu401_device); - break; + if (midi_device_available(c)) { + if (c == 0) + SendMessage(h, CB_ADDSTRING, 0, win_get_string(IDS_2112)); + else { + mbstowcs(lptsTemp, s, strlen(s) + 1); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); + } + settings_list_to_midi[d] = c; + d++; } - return FALSE; - case WM_SAVESETTINGS: - h = GetDlgItem(hdlg, IDC_COMBO_SOUND); - temp_sound_card = settings_list_to_sound[SendMessage(h, CB_GETCURSEL, 0, 0)]; + c++; + } + SendMessage(h, CB_SETCURSEL, settings_midi_to_list[temp_midi_device], 0); - h = GetDlgItem(hdlg, IDC_COMBO_MIDI); - temp_midi_device = settings_list_to_midi[SendMessage(h, CB_GETCURSEL, 0, 0)]; + h = GetDlgItem(hdlg, IDC_CONFIGURE_MIDI); + if (midi_device_has_config(temp_midi_device)) + EnableWindow(h, TRUE); + else + EnableWindow(h, FALSE); - h = GetDlgItem(hdlg, IDC_CHECK_MPU401); - temp_mpu401 = SendMessage(h, BM_GETCHECK, 0, 0); + h = GetDlgItem(hdlg, IDC_CHECK_MPU401); + SendMessage(h, BM_SETCHECK, temp_mpu401, 0); + EnableWindow(h, mpu401_standalone_allow() ? TRUE : FALSE); - h = GetDlgItem(hdlg, IDC_CHECK_CMS); - temp_GAMEBLASTER = SendMessage(h, BM_GETCHECK, 0, 0); + h = GetDlgItem(hdlg, IDC_CONFIGURE_MPU401); + EnableWindow(h, (mpu401_standalone_allow() && temp_mpu401) ? TRUE : FALSE); - h = GetDlgItem(hdlg, IDC_CHECK_GUS); - temp_GUS = SendMessage(h, BM_GETCHECK, 0, 0); + h=GetDlgItem(hdlg, IDC_CHECK_CMS); + SendMessage(h, BM_SETCHECK, temp_GAMEBLASTER, 0); - h = GetDlgItem(hdlg, IDC_CHECK_SSI); - temp_SSI2001 = SendMessage(h, BM_GETCHECK, 0, 0); + h=GetDlgItem(hdlg, IDC_CHECK_GUS); + SendMessage(h, BM_SETCHECK, temp_GUS, 0); - h = GetDlgItem(hdlg, IDC_CHECK_NUKEDOPL); - temp_opl_type = SendMessage(h, BM_GETCHECK, 0, 0); + h=GetDlgItem(hdlg, IDC_CHECK_SSI); + SendMessage(h, BM_SETCHECK, temp_SSI2001, 0); - h = GetDlgItem(hdlg, IDC_CHECK_FLOAT); - temp_float = SendMessage(h, BM_GETCHECK, 0, 0); + h=GetDlgItem(hdlg, IDC_CHECK_NUKEDOPL); + SendMessage(h, BM_SETCHECK, temp_opl_type, 0); - default: - return FALSE; - } - return FALSE; + h=GetDlgItem(hdlg, IDC_CHECK_FLOAT); + SendMessage(h, BM_SETCHECK, temp_float, 0); + + free(lptsTemp); + + return TRUE; + + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDC_COMBO_SOUND: + h = GetDlgItem(hdlg, IDC_COMBO_SOUND); + temp_sound_card = settings_list_to_device[SendMessage(h, CB_GETCURSEL, 0, 0)]; + + h = GetDlgItem(hdlg, IDC_CONFIGURE_SND); + if (sound_card_has_config(temp_sound_card)) + EnableWindow(h, TRUE); + else + EnableWindow(h, FALSE); + + h = GetDlgItem(hdlg, IDC_CHECK_MPU401); + SendMessage(h, BM_SETCHECK, temp_mpu401, 0); + EnableWindow(h, mpu401_standalone_allow() ? TRUE : FALSE); + + h = GetDlgItem(hdlg, IDC_CONFIGURE_MPU401); + EnableWindow(h, (mpu401_standalone_allow() && temp_mpu401) ? TRUE : FALSE); + break; + + case IDC_CONFIGURE_SND: + h = GetDlgItem(hdlg, IDC_COMBO_SOUND); + temp_sound_card = settings_list_to_device[SendMessage(h, CB_GETCURSEL, 0, 0)]; + + temp_deviceconfig |= deviceconfig_open(hdlg, (void *)sound_card_getdevice(temp_sound_card)); + break; + + case IDC_COMBO_MIDI: + h = GetDlgItem(hdlg, IDC_COMBO_MIDI); + temp_midi_device = settings_list_to_midi[SendMessage(h, CB_GETCURSEL, 0, 0)]; + + h = GetDlgItem(hdlg, IDC_CONFIGURE_MIDI); + if (midi_device_has_config(temp_midi_device)) + EnableWindow(h, TRUE); + else + EnableWindow(h, FALSE); + + h = GetDlgItem(hdlg, IDC_CHECK_MPU401); + SendMessage(h, BM_SETCHECK, temp_mpu401, 0); + EnableWindow(h, mpu401_standalone_allow() ? TRUE : FALSE); + + h = GetDlgItem(hdlg, IDC_CONFIGURE_MPU401); + EnableWindow(h, (mpu401_standalone_allow() && temp_mpu401) ? TRUE : FALSE); + break; + + case IDC_CONFIGURE_MIDI: + h = GetDlgItem(hdlg, IDC_COMBO_MIDI); + temp_midi_device = settings_list_to_midi[SendMessage(h, CB_GETCURSEL, 0, 0)]; + + temp_deviceconfig |= deviceconfig_open(hdlg, (void *)midi_device_getdevice(temp_midi_device)); + break; + + case IDC_CHECK_MPU401: + h = GetDlgItem(hdlg, IDC_CHECK_MPU401); + temp_mpu401 = SendMessage(h, BM_GETCHECK, 0, 0); + + h = GetDlgItem(hdlg, IDC_CONFIGURE_MPU401); + EnableWindow(h, mpu401_present() ? TRUE : FALSE); + break; + + case IDC_CONFIGURE_MPU401: + temp_deviceconfig |= deviceconfig_open(hdlg, (void *)&mpu401_device); + break; + } + return FALSE; + + case WM_SAVESETTINGS: + h = GetDlgItem(hdlg, IDC_COMBO_SOUND); + temp_sound_card = settings_list_to_device[SendMessage(h, CB_GETCURSEL, 0, 0)]; + + h = GetDlgItem(hdlg, IDC_COMBO_MIDI); + temp_midi_device = settings_list_to_midi[SendMessage(h, CB_GETCURSEL, 0, 0)]; + + h = GetDlgItem(hdlg, IDC_CHECK_MPU401); + temp_mpu401 = SendMessage(h, BM_GETCHECK, 0, 0); + + h = GetDlgItem(hdlg, IDC_CHECK_CMS); + temp_GAMEBLASTER = SendMessage(h, BM_GETCHECK, 0, 0); + + h = GetDlgItem(hdlg, IDC_CHECK_GUS); + temp_GUS = SendMessage(h, BM_GETCHECK, 0, 0); + + h = GetDlgItem(hdlg, IDC_CHECK_SSI); + temp_SSI2001 = SendMessage(h, BM_GETCHECK, 0, 0); + + h = GetDlgItem(hdlg, IDC_CHECK_NUKEDOPL); + temp_opl_type = SendMessage(h, BM_GETCHECK, 0, 0); + + h = GetDlgItem(hdlg, IDC_CHECK_FLOAT); + temp_float = SendMessage(h, BM_GETCHECK, 0, 0); + + default: + return FALSE; + } + return FALSE; } @@ -1390,154 +1292,133 @@ static BOOL CALLBACK #endif win_settings_ports_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) { - HWND h; - int c = 0; - int d = 0; - char *s; - LPTSTR lptsTemp; - int i; + HWND h; + int c, d, i; + char *s; + LPTSTR lptsTemp; - switch (message) - { - case WM_INITDIALOG: - lptsTemp = (LPTSTR) malloc(512); + switch (message) { + case WM_INITDIALOG: + lptsTemp = (LPTSTR) malloc(512); - for (i = 0; i < 3; i++) { - h = GetDlgItem(hdlg, IDC_COMBO_LPT1 + i); - c = d = 0; - while (1) { - s = lpt_device_get_name(c); + for (i = 0; i < 3; i++) { + h = GetDlgItem(hdlg, IDC_COMBO_LPT1 + i); + c = d = 0; + while (1) { + s = lpt_device_get_name(c); - if (!s) - break; + if (!s) + break; - if (c == 0) { - SendMessage(h, CB_ADDSTRING, 0, win_get_string(IDS_2152)); - } else { - mbstowcs(lptsTemp, s, strlen(s) + 1); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); - } - - if (!strcmp(temp_lpt_device_names[i], lpt_device_get_internal_name(c))) - d = c; - - c++; + if (c == 0) + SendMessage(h, CB_ADDSTRING, 0, win_get_string(IDS_2112)); + else { + mbstowcs(lptsTemp, s, strlen(s) + 1); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); } - SendMessage(h, CB_SETCURSEL, d, 0); + + if (!strcmp(temp_lpt_device_names[i], lpt_device_get_internal_name(c))) + d = c; + + c++; } + SendMessage(h, CB_SETCURSEL, d, 0); + } - h=GetDlgItem(hdlg, IDC_CHECK_SERIAL1); - SendMessage(h, BM_SETCHECK, temp_serial[0], 0); + h=GetDlgItem(hdlg, IDC_CHECK_SERIAL1); + SendMessage(h, BM_SETCHECK, temp_serial[0], 0); - h=GetDlgItem(hdlg, IDC_CHECK_SERIAL2); - SendMessage(h, BM_SETCHECK, temp_serial[1], 0); + h=GetDlgItem(hdlg, IDC_CHECK_SERIAL2); + SendMessage(h, BM_SETCHECK, temp_serial[1], 0); - h=GetDlgItem(hdlg, IDC_CHECK_PARALLEL); - SendMessage(h, BM_SETCHECK, temp_lpt, 0); + h=GetDlgItem(hdlg, IDC_CHECK_PARALLEL); + SendMessage(h, BM_SETCHECK, temp_lpt, 0); - free(lptsTemp); + free(lptsTemp); - return TRUE; + return TRUE; - case WM_SAVESETTINGS: - for (i = 0; i < 3; i++) { - h = GetDlgItem(hdlg, IDC_COMBO_LPT1 + i); - c = SendMessage(h, CB_GETCURSEL, 0, 0); - strcpy(temp_lpt_device_names[i], lpt_device_get_internal_name(c)); - } + case WM_SAVESETTINGS: + for (i = 0; i < 3; i++) { + h = GetDlgItem(hdlg, IDC_COMBO_LPT1 + i); + c = SendMessage(h, CB_GETCURSEL, 0, 0); + strcpy(temp_lpt_device_names[i], lpt_device_get_internal_name(c)); + } - h = GetDlgItem(hdlg, IDC_CHECK_SERIAL1); - temp_serial[0] = SendMessage(h, BM_GETCHECK, 0, 0); + h = GetDlgItem(hdlg, IDC_CHECK_SERIAL1); + temp_serial[0] = SendMessage(h, BM_GETCHECK, 0, 0); - h = GetDlgItem(hdlg, IDC_CHECK_SERIAL2); - temp_serial[1] = SendMessage(h, BM_GETCHECK, 0, 0); + h = GetDlgItem(hdlg, IDC_CHECK_SERIAL2); + temp_serial[1] = SendMessage(h, BM_GETCHECK, 0, 0); - h = GetDlgItem(hdlg, IDC_CHECK_PARALLEL); - temp_lpt = SendMessage(h, BM_GETCHECK, 0, 0); + h = GetDlgItem(hdlg, IDC_CHECK_PARALLEL); + temp_lpt = SendMessage(h, BM_GETCHECK, 0, 0); - default: - return FALSE; - } - return FALSE; + default: + return FALSE; + } + return FALSE; } -static void recalc_hdc_list(HWND hdlg, int machine, int use_selected_hdc) +static void +recalc_hdc_list(HWND hdlg, int machine, int use_selected_hdc) { - HWND h; + HWND h; + char *s, old_name[32]; + int valid, c, d; - char *s; - int valid = 0; - char old_name[32]; - int c, d; + LPTSTR lptsTemp; - LPTSTR lptsTemp; + lptsTemp = (LPTSTR) malloc(512); - lptsTemp = (LPTSTR) malloc(512); + h = GetDlgItem(hdlg, IDC_COMBO_HDC); - h = GetDlgItem(hdlg, IDC_COMBO_HDC); + valid = 0; - valid = 0; + if (use_selected_hdc) { + c = SendMessage(h, CB_GETCURSEL, 0, 0); - if (use_selected_hdc) - { - c = SendMessage(h, CB_GETCURSEL, 0, 0); - - if (c != -1 && hdc_names[c]) - { - strncpy(old_name, hdc_names[c], sizeof(old_name) - 1); - } - else - { - strcpy(old_name, "none"); - } - } + if (c != -1 && hdc_names[c]) + strncpy(old_name, hdc_names[c], sizeof(old_name) - 1); else - { - strncpy(old_name, temp_hdc_name, sizeof(old_name) - 1); - } + strcpy(old_name, "none"); + } else + strncpy(old_name, temp_hdc_name, sizeof(old_name) - 1); - SendMessage(h, CB_RESETCONTENT, 0, 0); - c = d = 0; - while (1) - { - s = hdc_get_name(c); - if (s[0] == 0) - { - break; - } - if (c==1 && !(machines[temp_machine].flags&MACHINE_HDC)) - { - /* Skip "Internal" if machine doesn't have one. */ - c++; - continue; - } - if (!hdc_available(c) || !device_is_valid(hdc_get_device(c), machines[temp_machine].flags)) - { - c++; - continue; - } - mbstowcs(lptsTemp, s, strlen(s) + 1); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); - - hdc_names[d] = hdc_get_internal_name(c); - if (!strcmp(old_name, hdc_names[d])) - { - SendMessage(h, CB_SETCURSEL, d, 0); - valid = 1; - } + SendMessage(h, CB_RESETCONTENT, 0, 0); + c = d = 0; + while (1) { + s = hdc_get_name(c); + if (s[0] == 0) + break; + if (c==1 && !(machines[temp_machine].flags&MACHINE_HDC)) { + /* Skip "Internal" if machine doesn't have one. */ c++; - d++; + continue; } - - if (!valid) - { - SendMessage(h, CB_SETCURSEL, 0, 0); + if (!hdc_available(c) || !device_is_valid(hdc_get_device(c), machines[temp_machine].flags)) { + c++; + continue; } + mbstowcs(lptsTemp, s, strlen(s) + 1); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); - EnableWindow(h, d ? TRUE : FALSE); + hdc_names[d] = hdc_get_internal_name(c); + if (!strcmp(old_name, hdc_names[d])) { + SendMessage(h, CB_SETCURSEL, d, 0); + valid = 1; + } + c++; + d++; + } - free(lptsTemp); + if (!valid) + SendMessage(h, CB_SETCURSEL, 0, 0); + + EnableWindow(h, d ? TRUE : FALSE); + + free(lptsTemp); } @@ -1548,255 +1429,201 @@ static BOOL CALLBACK #endif win_settings_peripherals_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) { - HWND h; - int c = 0; - int d = 0; - LPTSTR lptsTemp; - const device_t *scsi_dev; - int temp_hdc_type; + HWND h; + int c, d, temp_hdc_type; + LPTSTR lptsTemp; + const device_t *scsi_dev; - switch (message) - { - case WM_INITDIALOG: - lptsTemp = (LPTSTR) malloc(512); + switch (message) { + case WM_INITDIALOG: + lptsTemp = (LPTSTR) malloc(512); - /*SCSI config*/ - h = GetDlgItem(hdlg, IDC_COMBO_SCSI); - c = d = 0; - while (1) - { - char *s = scsi_card_getname(c); + /*SCSI config*/ + h = GetDlgItem(hdlg, IDC_COMBO_SCSI); + c = d = 0; + while (1) { + char *s = scsi_card_getname(c); - if (!s[0]) - { - break; + if (!s[0]) + break; + + settings_device_to_list[c] = d; + + if (scsi_card_available(c)) { + scsi_dev = scsi_card_getdevice(c); + + if (device_is_valid(scsi_dev, machines[temp_machine].flags)) { + if (c == 0) + SendMessage(h, CB_ADDSTRING, 0, win_get_string(IDS_2112)); + else { + mbstowcs(lptsTemp, s, strlen(s) + 1); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); + } + settings_list_to_device[d] = c; + d++; } - - settings_scsi_to_list[c] = d; - - if (scsi_card_available(c)) - { - scsi_dev = scsi_card_getdevice(c); - - - if (device_is_valid(scsi_dev, machines[temp_machine].flags)) - { - if (c == 0) - { - SendMessage(h, CB_ADDSTRING, 0, win_get_string(IDS_2152)); - } - else - { - mbstowcs(lptsTemp, s, strlen(s) + 1); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); - } - settings_list_to_scsi[d] = c; - d++; - } - } - - c++; - } - SendMessage(h, CB_SETCURSEL, settings_scsi_to_list[temp_scsi_card], 0); - - EnableWindow(h, d ? TRUE : FALSE); - - h = GetDlgItem(hdlg, IDC_CONFIGURE_SCSI); - if (scsi_card_has_config(temp_scsi_card)) - { - EnableWindow(h, TRUE); - } - else - { - EnableWindow(h, FALSE); } - recalc_hdc_list(hdlg, temp_machine, 0); + c++; + } + SendMessage(h, CB_SETCURSEL, settings_device_to_list[temp_scsi_card], 0); - h = GetDlgItem(hdlg, IDC_CONFIGURE_HDC); - if (hdc_has_config(hdc_get_from_internal_name(temp_hdc_name))) - EnableWindow(h, TRUE); - else - EnableWindow(h, FALSE); + EnableWindow(h, d ? TRUE : FALSE); - h = GetDlgItem(hdlg, IDC_CHECK_IDE_TER); - EnableWindow(h, (machines[temp_machine].flags & MACHINE_AT) ? TRUE : FALSE); + h = GetDlgItem(hdlg, IDC_CONFIGURE_SCSI); + EnableWindow(h, scsi_card_has_config(temp_scsi_card) ? TRUE : FALSE); - h = GetDlgItem(hdlg, IDC_BUTTON_IDE_TER); - EnableWindow(h, ((machines[temp_machine].flags & MACHINE_AT) && temp_ide_ter) ? TRUE : FALSE); + recalc_hdc_list(hdlg, temp_machine, 0); - h = GetDlgItem(hdlg, IDC_CHECK_IDE_QUA); - EnableWindow(h, (machines[temp_machine].flags & MACHINE_AT) ? TRUE : FALSE); + h = GetDlgItem(hdlg, IDC_CONFIGURE_HDC); + EnableWindow(h, hdc_has_config(hdc_get_from_internal_name(temp_hdc_name)) ? TRUE : FALSE); - h = GetDlgItem(hdlg, IDC_BUTTON_IDE_QUA); - EnableWindow(h, ((machines[temp_machine].flags & MACHINE_AT) && temp_ide_qua) ? TRUE : FALSE); + h = GetDlgItem(hdlg, IDC_CHECK_IDE_TER); + EnableWindow(h, (machines[temp_machine].flags & MACHINE_AT) ? TRUE : FALSE); - h=GetDlgItem(hdlg, IDC_CHECK_IDE_TER); - SendMessage(h, BM_SETCHECK, temp_ide_ter, 0); + h = GetDlgItem(hdlg, IDC_BUTTON_IDE_TER); + EnableWindow(h, ((machines[temp_machine].flags & MACHINE_AT) && temp_ide_ter) ? TRUE : FALSE); - h=GetDlgItem(hdlg, IDC_CHECK_IDE_QUA); - SendMessage(h, BM_SETCHECK, temp_ide_qua, 0); + h = GetDlgItem(hdlg, IDC_CHECK_IDE_QUA); + EnableWindow(h, (machines[temp_machine].flags & MACHINE_AT) ? TRUE : FALSE); - h=GetDlgItem(hdlg, IDC_CHECK_BUGGER); - SendMessage(h, BM_SETCHECK, temp_bugger, 0); + h = GetDlgItem(hdlg, IDC_BUTTON_IDE_QUA); + EnableWindow(h, ((machines[temp_machine].flags & MACHINE_AT) && temp_ide_qua) ? TRUE : FALSE); - free(lptsTemp); + h=GetDlgItem(hdlg, IDC_CHECK_IDE_TER); + SendMessage(h, BM_SETCHECK, temp_ide_ter, 0); - return TRUE; + h=GetDlgItem(hdlg, IDC_CHECK_IDE_QUA); + SendMessage(h, BM_SETCHECK, temp_ide_qua, 0); - case WM_COMMAND: - switch (LOWORD(wParam)) - { - case IDC_COMBO_HDC: - h = GetDlgItem(hdlg, IDC_COMBO_HDC); - temp_hdc_type = hdc_get_from_internal_name(hdc_names[SendMessage(h, CB_GETCURSEL, 0, 0)]); + h=GetDlgItem(hdlg, IDC_CHECK_BUGGER); + SendMessage(h, BM_SETCHECK, temp_bugger, 0); - h = GetDlgItem(hdlg, IDC_CONFIGURE_HDC); - if (hdc_has_config(temp_hdc_type)) - EnableWindow(h, TRUE); - else - EnableWindow(h, FALSE); - break; + free(lptsTemp); - case IDC_CONFIGURE_HDC: - h = GetDlgItem(hdlg, IDC_COMBO_HDC); - temp_hdc_type = hdc_get_from_internal_name(hdc_names[SendMessage(h, CB_GETCURSEL, 0, 0)]); + return TRUE; - temp_deviceconfig |= deviceconfig_open(hdlg, (void *)hdc_get_device(temp_hdc_type)); - break; + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDC_COMBO_HDC: + h = GetDlgItem(hdlg, IDC_COMBO_HDC); + temp_hdc_type = hdc_get_from_internal_name(hdc_names[SendMessage(h, CB_GETCURSEL, 0, 0)]); - case IDC_CONFIGURE_SCSI: - h = GetDlgItem(hdlg, IDC_COMBO_SCSI); - temp_scsi_card = settings_list_to_scsi[SendMessage(h, CB_GETCURSEL, 0, 0)]; + h = GetDlgItem(hdlg, IDC_CONFIGURE_HDC); + EnableWindow(h, hdc_has_config(temp_hdc_type) ? TRUE : FALSE); + break; - temp_deviceconfig |= deviceconfig_open(hdlg, (void *)scsi_card_getdevice(temp_scsi_card)); - break; + case IDC_CONFIGURE_HDC: + h = GetDlgItem(hdlg, IDC_COMBO_HDC); + temp_hdc_type = hdc_get_from_internal_name(hdc_names[SendMessage(h, CB_GETCURSEL, 0, 0)]); - case IDC_COMBO_SCSI: - h = GetDlgItem(hdlg, IDC_COMBO_SCSI); - temp_scsi_card = settings_list_to_scsi[SendMessage(h, CB_GETCURSEL, 0, 0)]; + temp_deviceconfig |= deviceconfig_open(hdlg, (void *)hdc_get_device(temp_hdc_type)); + break; - h = GetDlgItem(hdlg, IDC_CONFIGURE_SCSI); - if (scsi_card_has_config(temp_scsi_card)) - { - EnableWindow(h, TRUE); - } - else - { - EnableWindow(h, FALSE); - } - break; + case IDC_CONFIGURE_SCSI: + h = GetDlgItem(hdlg, IDC_COMBO_SCSI); + temp_scsi_card = settings_list_to_device[SendMessage(h, CB_GETCURSEL, 0, 0)]; - case IDC_CHECK_IDE_TER: - h = GetDlgItem(hdlg, IDC_CHECK_IDE_TER); - temp_ide_ter = SendMessage(h, BM_GETCHECK, 0, 0); + temp_deviceconfig |= deviceconfig_open(hdlg, (void *)scsi_card_getdevice(temp_scsi_card)); + break; - h = GetDlgItem(hdlg, IDC_BUTTON_IDE_TER); - EnableWindow(h, temp_ide_ter ? TRUE : FALSE); - break; + case IDC_COMBO_SCSI: + h = GetDlgItem(hdlg, IDC_COMBO_SCSI); + temp_scsi_card = settings_list_to_device[SendMessage(h, CB_GETCURSEL, 0, 0)]; - case IDC_BUTTON_IDE_TER: - temp_deviceconfig |= deviceconfig_open(hdlg, (void *)&ide_ter_device); - break; + h = GetDlgItem(hdlg, IDC_CONFIGURE_SCSI); + if (scsi_card_has_config(temp_scsi_card)) + EnableWindow(h, TRUE); + else + EnableWindow(h, FALSE); + break; - case IDC_CHECK_IDE_QUA: - h = GetDlgItem(hdlg, IDC_CHECK_IDE_QUA); - temp_ide_qua = SendMessage(h, BM_GETCHECK, 0, 0); + case IDC_CHECK_IDE_TER: + h = GetDlgItem(hdlg, IDC_CHECK_IDE_TER); + temp_ide_ter = SendMessage(h, BM_GETCHECK, 0, 0); - h = GetDlgItem(hdlg, IDC_BUTTON_IDE_QUA); - EnableWindow(h, temp_ide_qua ? TRUE : FALSE); - break; + h = GetDlgItem(hdlg, IDC_BUTTON_IDE_TER); + EnableWindow(h, temp_ide_ter ? TRUE : FALSE); + break; - case IDC_BUTTON_IDE_QUA: - temp_deviceconfig |= deviceconfig_open(hdlg, (void *)&ide_qua_device); - break; - } - return FALSE; + case IDC_BUTTON_IDE_TER: + temp_deviceconfig |= deviceconfig_open(hdlg, (void *)&ide_ter_device); + break; - case WM_SAVESETTINGS: - h = GetDlgItem(hdlg, IDC_COMBO_HDC); - c = SendMessage(h, CB_GETCURSEL, 0, 0); - if (hdc_names[c]) - { - strncpy(temp_hdc_name, hdc_names[c], sizeof(temp_hdc_name) - 1); - } - else - { - strcpy(temp_hdc_name, "none"); - } + case IDC_CHECK_IDE_QUA: + h = GetDlgItem(hdlg, IDC_CHECK_IDE_QUA); + temp_ide_qua = SendMessage(h, BM_GETCHECK, 0, 0); - h = GetDlgItem(hdlg, IDC_COMBO_SCSI); - temp_scsi_card = settings_list_to_scsi[SendMessage(h, CB_GETCURSEL, 0, 0)]; + h = GetDlgItem(hdlg, IDC_BUTTON_IDE_QUA); + EnableWindow(h, temp_ide_qua ? TRUE : FALSE); + break; - h = GetDlgItem(hdlg, IDC_CHECK_IDE_TER); - temp_ide_ter = SendMessage(h, BM_GETCHECK, 0, 0); + case IDC_BUTTON_IDE_QUA: + temp_deviceconfig |= deviceconfig_open(hdlg, (void *)&ide_qua_device); + break; + } + return FALSE; - h = GetDlgItem(hdlg, IDC_CHECK_IDE_QUA); - temp_ide_qua = SendMessage(h, BM_GETCHECK, 0, 0); + case WM_SAVESETTINGS: + h = GetDlgItem(hdlg, IDC_COMBO_HDC); + c = SendMessage(h, CB_GETCURSEL, 0, 0); + if (hdc_names[c]) + strncpy(temp_hdc_name, hdc_names[c], sizeof(temp_hdc_name) - 1); + else + strcpy(temp_hdc_name, "none"); - h = GetDlgItem(hdlg, IDC_CHECK_BUGGER); - temp_bugger = SendMessage(h, BM_GETCHECK, 0, 0); + h = GetDlgItem(hdlg, IDC_COMBO_SCSI); + temp_scsi_card = settings_list_to_device[SendMessage(h, CB_GETCURSEL, 0, 0)]; - default: - return FALSE; - } - return FALSE; + h = GetDlgItem(hdlg, IDC_CHECK_IDE_TER); + temp_ide_ter = SendMessage(h, BM_GETCHECK, 0, 0); + + h = GetDlgItem(hdlg, IDC_CHECK_IDE_QUA); + temp_ide_qua = SendMessage(h, BM_GETCHECK, 0, 0); + + h = GetDlgItem(hdlg, IDC_CHECK_BUGGER); + temp_bugger = SendMessage(h, BM_GETCHECK, 0, 0); + + default: + return FALSE; + } + return FALSE; } -int net_ignore_message = 0; - static void network_recalc_combos(HWND hdlg) { - HWND h; + HWND h; - net_ignore_message = 1; + ignore_change = 1; - h = GetDlgItem(hdlg, IDC_COMBO_PCAP); - if (temp_net_type == NET_TYPE_PCAP) - { - EnableWindow(h, TRUE); - } - else - { - EnableWindow(h, FALSE); - } + h = GetDlgItem(hdlg, IDC_COMBO_PCAP); + EnableWindow(h, (temp_net_type == NET_TYPE_PCAP) ? TRUE : FALSE); - h = GetDlgItem(hdlg, IDC_COMBO_NET); - if (temp_net_type == NET_TYPE_SLIRP) - { - EnableWindow(h, TRUE); - } - else if ((temp_net_type == NET_TYPE_PCAP) && - (network_dev_to_id(temp_pcap_dev) > 0)) - { - EnableWindow(h, TRUE); - } - else - { - EnableWindow(h, FALSE); - } + h = GetDlgItem(hdlg, IDC_COMBO_NET); + if (temp_net_type == NET_TYPE_SLIRP) + EnableWindow(h, TRUE); + else if ((temp_net_type == NET_TYPE_PCAP) && + (network_dev_to_id(temp_pcap_dev) > 0)) + EnableWindow(h, TRUE); + else + EnableWindow(h, FALSE); - h = GetDlgItem(hdlg, IDC_CONFIGURE_NET); - if (network_card_has_config(temp_net_card) && - (temp_net_type == NET_TYPE_SLIRP)) - { - EnableWindow(h, TRUE); - } - else if (network_card_has_config(temp_net_card) && - (temp_net_type == NET_TYPE_PCAP) && - (network_dev_to_id(temp_pcap_dev) > 0)) - { - EnableWindow(h, TRUE); - } - else - { - EnableWindow(h, FALSE); - } + h = GetDlgItem(hdlg, IDC_CONFIGURE_NET); + if (network_card_has_config(temp_net_card) && + (temp_net_type == NET_TYPE_SLIRP)) + EnableWindow(h, TRUE); + else if (network_card_has_config(temp_net_card) && + (temp_net_type == NET_TYPE_PCAP) && + (network_dev_to_id(temp_pcap_dev) > 0)) + EnableWindow(h, TRUE); + else + EnableWindow(h, FALSE); - net_ignore_message = 0; + ignore_change = 0; } + #ifdef __amd64__ static LRESULT CALLBACK #else @@ -1804,569 +1631,522 @@ static BOOL CALLBACK #endif win_settings_network_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) { - HWND h; - int c = 0; - int d = 0; - LPTSTR lptsTemp; + HWND h; + int c, d; + LPTSTR lptsTemp; + char *s; - switch (message) - { - case WM_INITDIALOG: - lptsTemp = (LPTSTR) malloc(512); + switch (message) { + case WM_INITDIALOG: + lptsTemp = (LPTSTR) malloc(512); - h = GetDlgItem(hdlg, IDC_COMBO_NET_TYPE); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) L"None"); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) L"PCap"); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) L"SLiRP"); - SendMessage(h, CB_SETCURSEL, temp_net_type, 0); + h = GetDlgItem(hdlg, IDC_COMBO_NET_TYPE); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) L"None"); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) L"PCap"); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) L"SLiRP"); + SendMessage(h, CB_SETCURSEL, temp_net_type, 0); - h = GetDlgItem(hdlg, IDC_COMBO_PCAP); - if (temp_net_type == NET_TYPE_PCAP) - { - EnableWindow(h, TRUE); - } - else - { - EnableWindow(h, FALSE); - } + h = GetDlgItem(hdlg, IDC_COMBO_PCAP); + if (temp_net_type == NET_TYPE_PCAP) + EnableWindow(h, TRUE); + else + EnableWindow(h, FALSE); - h = GetDlgItem(hdlg, IDC_COMBO_PCAP); - for (c = 0; c < network_ndev; c++) - { - mbstowcs(lptsTemp, network_devs[c].description, strlen(network_devs[c].description) + 1); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); - } - SendMessage(h, CB_SETCURSEL, network_dev_to_id(temp_pcap_dev), 0); - - /*NIC config*/ - h = GetDlgItem(hdlg, IDC_COMBO_NET); - c = d = 0; - while (1) - { - char *s = network_card_getname(c); - - if (s[0] == '\0') - { - break; - } - - settings_network_to_list[c] = d; - - if (network_card_available(c) && device_is_valid(network_card_getdevice(c), machines[temp_machine].flags)) - { - if (c == 0) - { - SendMessage(h, CB_ADDSTRING, 0, win_get_string(2152)); - } - else - { - mbstowcs(lptsTemp, s, strlen(s) + 1); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); - } - settings_list_to_network[d] = c; - d++; - } - - c++; - } - SendMessage(h, CB_SETCURSEL, settings_network_to_list[temp_net_card], 0); - - EnableWindow(h, d ? TRUE : FALSE); - - network_recalc_combos(hdlg); - - free(lptsTemp); - - return TRUE; - - case WM_COMMAND: - switch (LOWORD(wParam)) - { - case IDC_COMBO_NET_TYPE: - if (net_ignore_message) - { - return FALSE; - } - - h = GetDlgItem(hdlg, IDC_COMBO_NET_TYPE); - temp_net_type = SendMessage(h, CB_GETCURSEL, 0, 0); - - network_recalc_combos(hdlg); - break; - - case IDC_COMBO_PCAP: - if (net_ignore_message) - { - return FALSE; - } - - h = GetDlgItem(hdlg, IDC_COMBO_PCAP); - memset(temp_pcap_dev, '\0', sizeof(temp_pcap_dev)); - strcpy(temp_pcap_dev, network_devs[SendMessage(h, CB_GETCURSEL, 0, 0)].device); - - network_recalc_combos(hdlg); - break; - - case IDC_COMBO_NET: - if (net_ignore_message) - { - return FALSE; - } - - h = GetDlgItem(hdlg, IDC_COMBO_NET); - temp_net_card = settings_list_to_network[SendMessage(h, CB_GETCURSEL, 0, 0)]; - - network_recalc_combos(hdlg); - break; - - case IDC_CONFIGURE_NET: - if (net_ignore_message) - { - return FALSE; - } - - h = GetDlgItem(hdlg, IDC_COMBO_NET); - temp_net_card = settings_list_to_network[SendMessage(h, CB_GETCURSEL, 0, 0)]; - - temp_deviceconfig |= deviceconfig_open(hdlg, (void *)network_card_getdevice(temp_net_card)); - break; - } - return FALSE; - - case WM_SAVESETTINGS: - h = GetDlgItem(hdlg, IDC_COMBO_NET_TYPE); - temp_net_type = SendMessage(h, CB_GETCURSEL, 0, 0); - - h = GetDlgItem(hdlg, IDC_COMBO_PCAP); - memset(temp_pcap_dev, '\0', sizeof(temp_pcap_dev)); - strcpy(temp_pcap_dev, network_devs[SendMessage(h, CB_GETCURSEL, 0, 0)].device); - - h = GetDlgItem(hdlg, IDC_COMBO_NET); - temp_net_card = settings_list_to_network[SendMessage(h, CB_GETCURSEL, 0, 0)]; - - default: - return FALSE; - } - - return FALSE; -} - -static BOOL win_settings_hard_disks_image_list_init(HWND hwndList) -{ - HICON hiconItem; - HIMAGELIST hSmall; - - hSmall = ImageList_Create(GetSystemMetrics(SM_CXSMICON), - GetSystemMetrics(SM_CYSMICON), - ILC_MASK | ILC_COLOR32, 1, 1); - - hiconItem = LoadIcon(hinstance, (LPCWSTR) 192); - ImageList_AddIcon(hSmall, hiconItem); - DestroyIcon(hiconItem); - - ListView_SetImageList(hwndList, hSmall, LVSIL_SMALL); - - return TRUE; -} - -int next_free_id = 0; - -static void normalize_hd_list() -{ - hard_disk_t ihdd[HDD_NUM]; - int i, j; - - j = 0; - memset(ihdd, 0x00, HDD_NUM * sizeof(hard_disk_t)); - - for (i = 0; i < HDD_NUM; i++) - { - if (temp_hdd[i].bus != HDD_BUS_DISABLED) - { - memcpy(&(ihdd[j]), &(temp_hdd[i]), sizeof(hard_disk_t)); - j++; + h = GetDlgItem(hdlg, IDC_COMBO_PCAP); + for (c = 0; c < network_ndev; c++) { + mbstowcs(lptsTemp, network_devs[c].description, strlen(network_devs[c].description) + 1); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); } - } + SendMessage(h, CB_SETCURSEL, network_dev_to_id(temp_pcap_dev), 0); - memcpy(temp_hdd, ihdd, HDD_NUM * sizeof(hard_disk_t)); -} + /*NIC config*/ + h = GetDlgItem(hdlg, IDC_COMBO_NET); + c = d = 0; + while (1) { + s = network_card_getname(c); -int hdc_id_to_listview_index[HDD_NUM]; -int hd_listview_items; + if (s[0] == '\0') + break; -hard_disk_t new_hdd; -int hdlv_current_sel; + settings_device_to_list[c] = d; -static int get_selected_hard_disk(HWND hdlg) -{ - int hard_disk = -1; - int i, j = 0; - HWND h; + if (network_card_available(c) && device_is_valid(network_card_getdevice(c), machines[temp_machine].flags)) { + if (c == 0) + SendMessage(h, CB_ADDSTRING, 0, win_get_string(2112)); + else { + mbstowcs(lptsTemp, s, strlen(s) + 1); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); + } + settings_list_to_device[d] = c; + d++; + } - if (hd_listview_items == 0) - { - return 0; - } - - for (i = 0; i < hd_listview_items; i++) - { - h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); - j = ListView_GetItemState(h, i, LVIS_SELECTED); - if (j) - { - hard_disk = i; + c++; } - } - return hard_disk; + SendMessage(h, CB_SETCURSEL, settings_device_to_list[temp_net_card], 0); + EnableWindow(h, d ? TRUE : FALSE); + network_recalc_combos(hdlg); + free(lptsTemp); + + return TRUE; + + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDC_COMBO_NET_TYPE: + if (ignore_change) + return FALSE; + + h = GetDlgItem(hdlg, IDC_COMBO_NET_TYPE); + temp_net_type = SendMessage(h, CB_GETCURSEL, 0, 0); + + network_recalc_combos(hdlg); + break; + + case IDC_COMBO_PCAP: + if (ignore_change) + return FALSE; + + h = GetDlgItem(hdlg, IDC_COMBO_PCAP); + memset(temp_pcap_dev, '\0', sizeof(temp_pcap_dev)); + strcpy(temp_pcap_dev, network_devs[SendMessage(h, CB_GETCURSEL, 0, 0)].device); + + network_recalc_combos(hdlg); + break; + + case IDC_COMBO_NET: + if (ignore_change) + return FALSE; + + h = GetDlgItem(hdlg, IDC_COMBO_NET); + temp_net_card = settings_list_to_device[SendMessage(h, CB_GETCURSEL, 0, 0)]; + + network_recalc_combos(hdlg); + break; + + case IDC_CONFIGURE_NET: + if (ignore_change) + return FALSE; + + h = GetDlgItem(hdlg, IDC_COMBO_NET); + temp_net_card = settings_list_to_device[SendMessage(h, CB_GETCURSEL, 0, 0)]; + + temp_deviceconfig |= deviceconfig_open(hdlg, (void *)network_card_getdevice(temp_net_card)); + break; + } + return FALSE; + + case WM_SAVESETTINGS: + h = GetDlgItem(hdlg, IDC_COMBO_NET_TYPE); + temp_net_type = SendMessage(h, CB_GETCURSEL, 0, 0); + + h = GetDlgItem(hdlg, IDC_COMBO_PCAP); + memset(temp_pcap_dev, '\0', sizeof(temp_pcap_dev)); + strcpy(temp_pcap_dev, network_devs[SendMessage(h, CB_GETCURSEL, 0, 0)].device); + + h = GetDlgItem(hdlg, IDC_COMBO_NET); + temp_net_card = settings_list_to_device[SendMessage(h, CB_GETCURSEL, 0, 0)]; + + default: + return FALSE; + } + + return FALSE; } -static void add_locations(HWND hdlg) -{ - LPTSTR lptsTemp; - HWND h; - int i = 0; - lptsTemp = (LPTSTR) malloc(512); +static void +normalize_hd_list() +{ + hard_disk_t ihdd[HDD_NUM]; + int i, j; + + j = 0; + memset(ihdd, 0x00, HDD_NUM * sizeof(hard_disk_t)); + + for (i = 0; i < HDD_NUM; i++) { + if (temp_hdd[i].bus != HDD_BUS_DISABLED) { + memcpy(&(ihdd[j]), &(temp_hdd[i]), sizeof(hard_disk_t)); + j++; + } + } + + memcpy(temp_hdd, ihdd, HDD_NUM * sizeof(hard_disk_t)); +} + + +static int +get_selected_hard_disk(HWND hdlg) +{ + int hard_disk = -1; + int i, j = 0; + HWND h; + + if (hd_listview_items == 0) + return 0; + + for (i = 0; i < hd_listview_items; i++) { + h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); + j = ListView_GetItemState(h, i, LVIS_SELECTED); + if (j) + hard_disk = i; + } + + return hard_disk; +} + + +static void +add_locations(HWND hdlg) +{ + LPTSTR lptsTemp; + HWND h; + int i = 0; + + lptsTemp = (LPTSTR) malloc(512); + + h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); + for (i = 0; i < 5; i++) + SendMessage(h, CB_ADDSTRING, 0, win_get_string(IDS_4352 + i)); + + h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); + for (i = 0; i < 2; i++) { + wsprintf(lptsTemp, plat_get_string(IDS_4097), i >> 1, i & 1); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); + } + + h = GetDlgItem(hdlg, IDC_COMBO_HD_ID); + for (i = 0; i < 16; i++) { + wsprintf(lptsTemp, plat_get_string(IDS_4098), i); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); + } + + h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL_IDE); + for (i = 0; i < 8; i++) { + wsprintf(lptsTemp, plat_get_string(IDS_4097), i >> 1, i & 1); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); + } + + free(lptsTemp); +} + + +static uint8_t +next_free_binary_channel(uint64_t *tracking) +{ + int64_t i; + + for (i = 0; i < 2; i++) { + if (!(*tracking & (0xffLL << (i << 3LL)))) + return i; + } + + return 2; +} + + +static uint8_t +next_free_ide_channel(void) +{ + int64_t i; + + for (i = 0; i < 8; i++) { + if (!(ide_tracking & (0xffLL << (i << 3LL)))) + return i; + } + + return 7; +} + + +static void +next_free_scsi_id(uint8_t *id) +{ + int64_t i; + + for (i = 0; i < 16; i++) { + if (!(scsi_tracking[i >> 3] & (0xffLL << ((i & 0x07) << 3LL)))) { + *id = i; + return; + } + } + + *id = 6; +} + + +static void +recalc_location_controls(HWND hdlg, int is_add_dlg, int assign_id) +{ + int i = 0; + HWND h; + + int bus = 0; + + for (i = IDT_1722; i <= IDT_1723; i++) { + h = GetDlgItem(hdlg, i); + EnableWindow(h, FALSE); + ShowWindow(h, SW_HIDE); + } + + h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); + EnableWindow(h, FALSE); + ShowWindow(h, SW_HIDE); + + h = GetDlgItem(hdlg, IDC_COMBO_HD_ID); + EnableWindow(h, FALSE); + ShowWindow(h, SW_HIDE); + + h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL_IDE); + EnableWindow(h, FALSE); + ShowWindow(h, SW_HIDE); + + if ((hd_listview_items > 0) || is_add_dlg) { + h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); + bus = SendMessage(h, CB_GETCURSEL, 0, 0); + bus++; + + switch(bus) { + case HDD_BUS_MFM: /* MFM */ + h = GetDlgItem(hdlg, IDT_1722); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + + h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + if (assign_id) + temp_hdd[lv1_current_sel].mfm_channel = next_free_binary_channel(&mfm_tracking); + SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdd.mfm_channel : temp_hdd[lv1_current_sel].mfm_channel, 0); + break; + case HDD_BUS_XTA: /* XTA */ + h = GetDlgItem(hdlg, IDT_1722); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + + h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + if (assign_id) + temp_hdd[lv1_current_sel].xta_channel = next_free_binary_channel(&xta_tracking); + SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdd.xta_channel : temp_hdd[lv1_current_sel].xta_channel, 0); + break; + case HDD_BUS_ESDI: /* ESDI */ + h = GetDlgItem(hdlg, IDT_1722); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + + h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + if (assign_id) + temp_hdd[lv1_current_sel].esdi_channel = next_free_binary_channel(&esdi_tracking); + SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdd.esdi_channel : temp_hdd[lv1_current_sel].esdi_channel, 0); + break; + case HDD_BUS_IDE: /* IDE */ + h = GetDlgItem(hdlg, IDT_1722); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + + h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL_IDE); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + if (assign_id) + temp_hdd[lv1_current_sel].ide_channel = next_free_ide_channel(); + SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdd.ide_channel : temp_hdd[lv1_current_sel].ide_channel, 0); + break; + case HDD_BUS_SCSI: /* SCSI */ + h = GetDlgItem(hdlg, IDT_1723); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + h = GetDlgItem(hdlg, IDT_1724); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + + if (assign_id) + next_free_scsi_id((uint8_t *) is_add_dlg ? &new_hdd.scsi_id : &temp_hdd[lv1_current_sel].scsi_id); + + h = GetDlgItem(hdlg, IDC_COMBO_HD_ID); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdd.scsi_id : temp_hdd[lv1_current_sel].scsi_id, 0); + } + } + + if ((hd_listview_items == 0) && !is_add_dlg) { + h = GetDlgItem(hdlg, IDT_1721); + EnableWindow(h, FALSE); + ShowWindow(h, SW_HIDE); h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); - for (i = 0; i < 5; i++) - { - SendMessage(h, CB_ADDSTRING, 0, win_get_string(IDS_4352 + i)); - } + EnableWindow(h, FALSE); ShowWindow(h, SW_HIDE); + } else { + h = GetDlgItem(hdlg, IDT_1721); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); - h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); - for (i = 0; i < 2; i++) - { - wsprintf(lptsTemp, plat_get_string(IDS_4097), i >> 1, i & 1); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); - } - - h = GetDlgItem(hdlg, IDC_COMBO_HD_ID); - for (i = 0; i < 16; i++) - { - wsprintf(lptsTemp, plat_get_string(IDS_4098), i); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); - } - - h = GetDlgItem(hdlg, IDC_COMBO_HD_LUN); - for (i = 0; i < 8; i++) - { - wsprintf(lptsTemp, plat_get_string(IDS_4098), i); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); - } - - h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL_IDE); - for (i = 0; i < 8; i++) - { - wsprintf(lptsTemp, plat_get_string(IDS_4097), i >> 1, i & 1); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); - } - - free(lptsTemp); + h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + } } -static uint8_t next_free_binary_channel(uint64_t *tracking) + +static int +bus_full(uint64_t *tracking, int count) { - int64_t i; - - for (i = 0; i < 2; i++) { - if (!(*tracking & (0xffLL << (i << 3LL)))) - return i; - } - - return 2; + int full = 0; + switch(count) { + case 2: + default: + full = (*tracking & 0xFF00LL); + full = full && (*tracking & 0x00FFLL); + return full; + case 8: + full = (*tracking & 0xFF00000000000000LL); + full = full && (*tracking & 0x00FF000000000000LL); + full = full && (*tracking & 0x0000FF0000000000LL); + full = full && (*tracking & 0x000000FF00000000LL); + full = full && (*tracking & 0x00000000FF000000LL); + full = full && (*tracking & 0x0000000000FF0000LL); + full = full && (*tracking & 0x000000000000FF00LL); + full = full && (*tracking & 0x00000000000000FFLL); + return full; + } } -static uint8_t next_free_ide_channel(void) + +static void +recalc_next_free_id(HWND hdlg) { - int64_t i; + HWND h; + int i, enable_add = 0; + int c_mfm = 0, c_esdi = 0; + int c_xta = 0, c_ide = 0; + int c_scsi = 0; - for (i = 0; i < 8; i++) { - if (!(ide_tracking & (0xffLL << (i << 3LL)))) - return i; + next_free_id = -1; + + for (i = 0; i < HDD_NUM; i++) { + if (temp_hdd[i].bus == HDD_BUS_MFM) + c_mfm++; + else if (temp_hdd[i].bus == HDD_BUS_ESDI) + c_esdi++; + else if (temp_hdd[i].bus == HDD_BUS_XTA) + c_xta++; + else if (temp_hdd[i].bus == HDD_BUS_IDE) + c_ide++; + else if (temp_hdd[i].bus == HDD_BUS_SCSI) + c_scsi++; + } + + for (i = 0; i < HDD_NUM; i++) { + if (temp_hdd[i].bus == HDD_BUS_DISABLED) { + next_free_id = i; + break; } + } - return 7; + enable_add = enable_add || (next_free_id >= 0); + enable_add = enable_add && ((c_mfm < MFM_NUM) || (c_esdi < ESDI_NUM) || (c_xta < XTA_NUM) || + (c_ide < IDE_NUM) || (c_scsi < SCSI_NUM)); + enable_add = enable_add && !bus_full(&mfm_tracking, 2); + enable_add = enable_add && !bus_full(&esdi_tracking, 2); + enable_add = enable_add && !bus_full(&xta_tracking, 2); + enable_add = enable_add && !bus_full(&ide_tracking, 8); + for (i = 0; i < 2; i++) + enable_add = enable_add && !bus_full(&(scsi_tracking[i]), 8); + + h = GetDlgItem(hdlg, IDC_BUTTON_HDD_ADD_NEW); + EnableWindow(h, enable_add ? TRUE : FALSE); + + h = GetDlgItem(hdlg, IDC_BUTTON_HDD_ADD); + EnableWindow(h, enable_add ? TRUE : FALSE); + + h = GetDlgItem(hdlg, IDC_BUTTON_HDD_REMOVE); + EnableWindow(h, ((c_mfm == 0) && (c_esdi == 0) && (c_xta == 0) && (c_ide == 0) && (c_scsi == 0)) ? + FALSE : TRUE); } -static void next_free_scsi_id_and_lun(uint8_t *id, uint8_t *lun) + +static void +win_settings_hard_disks_update_item(HWND hwndList, int i, int column) { - int64_t i, j; + LVITEM lvI; + WCHAR szText[256]; - for (j = 0; j < 8; j++) { - for (i = 0; i < 16; i++) { - if (!(scsi_tracking[i] & (0xffLL << (j << 3LL)))) { - *id = i; - *lun = j; - return; - } - } - } + lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; + lvI.stateMask = lvI.iSubItem = lvI.state = 0; - *id = 6; - *lun = 7; -} + lvI.iSubItem = column; + lvI.iItem = i; -static void recalc_location_controls(HWND hdlg, int is_add_dlg, int assign_id) -{ - int i = 0; - HWND h; - - int bus = 0; - - for (i = IDT_1722; i <= IDT_1724; i++) - { - h = GetDlgItem(hdlg, i); - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - } - - h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - - h = GetDlgItem(hdlg, IDC_COMBO_HD_ID); - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - - h = GetDlgItem(hdlg, IDC_COMBO_HD_LUN); - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - - h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL_IDE); - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - - if ((hd_listview_items > 0) || is_add_dlg) - { - h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); - bus = SendMessage(h, CB_GETCURSEL, 0, 0); - bus++; - - switch(bus) - { - case HDD_BUS_MFM: /* MFM */ - h = GetDlgItem(hdlg, IDT_1722); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - - h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - if (assign_id) - temp_hdd[hdlv_current_sel].mfm_channel = next_free_binary_channel(&mfm_tracking); - SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdd.mfm_channel : temp_hdd[hdlv_current_sel].mfm_channel, 0); - break; - case HDD_BUS_XTA: /* XTA */ - h = GetDlgItem(hdlg, IDT_1722); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - - h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - if (assign_id) - temp_hdd[hdlv_current_sel].xta_channel = next_free_binary_channel(&xta_tracking); - SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdd.xta_channel : temp_hdd[hdlv_current_sel].xta_channel, 0); - break; - case HDD_BUS_ESDI: /* ESDI */ - h = GetDlgItem(hdlg, IDT_1722); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - - h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - if (assign_id) - temp_hdd[hdlv_current_sel].esdi_channel = next_free_binary_channel(&esdi_tracking); - SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdd.esdi_channel : temp_hdd[hdlv_current_sel].esdi_channel, 0); - break; - case HDD_BUS_IDE: /* IDE */ - h = GetDlgItem(hdlg, IDT_1722); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - - h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL_IDE); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - if (assign_id) - temp_hdd[hdlv_current_sel].ide_channel = next_free_ide_channel(); - SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdd.ide_channel : temp_hdd[hdlv_current_sel].ide_channel, 0); - break; - case HDD_BUS_SCSI: /* SCSI */ - h = GetDlgItem(hdlg, IDT_1723); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - h = GetDlgItem(hdlg, IDT_1724); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - - if (assign_id) - next_free_scsi_id_and_lun((uint8_t *) &temp_hdd[hdlv_current_sel].scsi_id, (uint8_t *) &temp_hdd[hdlv_current_sel].scsi_lun); - - h = GetDlgItem(hdlg, IDC_COMBO_HD_ID); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdd.scsi_id : temp_hdd[hdlv_current_sel].scsi_id, 0); - - h = GetDlgItem(hdlg, IDC_COMBO_HD_LUN); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdd.scsi_lun : temp_hdd[hdlv_current_sel].scsi_lun, 0); - break; - } - } - - if ((hd_listview_items == 0) && !is_add_dlg) - { - h = GetDlgItem(hdlg, IDT_1721); - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - - h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); - EnableWindow(h, FALSE); ShowWindow(h, SW_HIDE); - } - else - { - h = GetDlgItem(hdlg, IDT_1721); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - - h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - } -} - -static int bus_full(uint64_t *tracking, int count) -{ - int full = 0; - switch(count) { - case 2: - default: - full = (*tracking & 0xFF00LL); - full = full && (*tracking & 0x00FFLL); - return full; - case 8: - full = (*tracking & 0xFF00000000000000LL); - full = full && (*tracking & 0x00FF000000000000LL); - full = full && (*tracking & 0x0000FF0000000000LL); - full = full && (*tracking & 0x000000FF00000000LL); - full = full && (*tracking & 0x00000000FF000000LL); - full = full && (*tracking & 0x0000000000FF0000LL); - full = full && (*tracking & 0x000000000000FF00LL); - full = full && (*tracking & 0x00000000000000FFLL); - return full; - } -} - -static void recalc_next_free_id(HWND hdlg) -{ - HWND h; - int i; - - int c_mfm = 0; - int c_esdi = 0; - int c_xta = 0; - int c_ide = 0; - int c_scsi = 0; - int enable_add = 0; - - next_free_id = -1; - - for (i = 0; i < HDD_NUM; i++) - { - if (temp_hdd[i].bus == HDD_BUS_MFM) - { - c_mfm++; - } - else if (temp_hdd[i].bus == HDD_BUS_ESDI) - { - c_esdi++; - } - else if (temp_hdd[i].bus == HDD_BUS_XTA) - { - c_xta++; - } - else if (temp_hdd[i].bus == HDD_BUS_IDE) - { - c_ide++; - } - else if (temp_hdd[i].bus == HDD_BUS_SCSI) - { - c_scsi++; - } - } - - for (i = 0; i < HDD_NUM; i++) - { - if (temp_hdd[i].bus == HDD_BUS_DISABLED) - { - next_free_id = i; + if (column == 0) { + switch(temp_hdd[i].bus) { + case HDD_BUS_MFM: + wsprintf(szText, plat_get_string(IDS_4608), temp_hdd[i].mfm_channel >> 1, temp_hdd[i].mfm_channel & 1); + break; + case HDD_BUS_XTA: + wsprintf(szText, plat_get_string(IDS_4609), temp_hdd[i].xta_channel >> 1, temp_hdd[i].xta_channel & 1); + break; + case HDD_BUS_ESDI: + wsprintf(szText, plat_get_string(IDS_4610), temp_hdd[i].esdi_channel >> 1, temp_hdd[i].esdi_channel & 1); + break; + case HDD_BUS_IDE: + wsprintf(szText, plat_get_string(IDS_4611), temp_hdd[i].ide_channel >> 1, temp_hdd[i].ide_channel & 1); + break; + case HDD_BUS_SCSI: + wsprintf(szText, plat_get_string(IDS_4612), temp_hdd[i].scsi_id); break; - } } + lvI.pszText = szText; + lvI.iImage = 0; + } else if (column == 1) { + lvI.pszText = temp_hdd[i].fn; + lvI.iImage = 0; + } else if (column == 2) { + wsprintf(szText, plat_get_string(IDS_4098), temp_hdd[i].tracks); + lvI.pszText = szText; + lvI.iImage = 0; + } else if (column == 3) { + wsprintf(szText, plat_get_string(IDS_4098), temp_hdd[i].hpc); + lvI.pszText = szText; + lvI.iImage = 0; + } else if (column == 4) { + wsprintf(szText, plat_get_string(IDS_4098), temp_hdd[i].spt); + lvI.pszText = szText; + lvI.iImage = 0; + } else if (column == 5) { + wsprintf(szText, plat_get_string(IDS_4098), (temp_hdd[i].tracks * temp_hdd[i].hpc * temp_hdd[i].spt) >> 11); + lvI.pszText = szText; + lvI.iImage = 0; + } - enable_add = enable_add || (next_free_id >= 0); - enable_add = enable_add && ((c_mfm < MFM_NUM) || (c_esdi < ESDI_NUM) || (c_xta < XTA_NUM) || - (c_ide < IDE_NUM) || (c_scsi < SCSI_NUM)); - enable_add = enable_add && !bus_full(&mfm_tracking, 2); - enable_add = enable_add && !bus_full(&esdi_tracking, 2); - enable_add = enable_add && !bus_full(&xta_tracking, 2); - enable_add = enable_add && !bus_full(&ide_tracking, 8); - for (i = 0; i < 16; i++) - enable_add = enable_add && !bus_full(&(scsi_tracking[i]), 8); - - h = GetDlgItem(hdlg, IDC_BUTTON_HDD_ADD_NEW); - - if (enable_add) - { - EnableWindow(h, TRUE); - } - else - { - EnableWindow(h, FALSE); - } - - h = GetDlgItem(hdlg, IDC_BUTTON_HDD_ADD); - - if (enable_add) - { - EnableWindow(h, TRUE); - } - else - { - EnableWindow(h, FALSE); - } - - h = GetDlgItem(hdlg, IDC_BUTTON_HDD_REMOVE); - - if ((c_mfm == 0) && (c_esdi == 0) && (c_xta == 0) && (c_ide == 0) && (c_scsi == 0)) - { - EnableWindow(h, FALSE); - } - else - { - EnableWindow(h, TRUE); - } + if (ListView_SetItem(hwndList, &lvI) == -1) + return; } -static void win_settings_hard_disks_update_item(HWND hwndList, int i, int column) + +static BOOL +win_settings_hard_disks_recalc_list(HWND hwndList) { - LVITEM lvI; - WCHAR szText[256]; + LVITEM lvI; + int i, j = 0; + WCHAR szText[256]; - lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; - lvI.stateMask = lvI.iSubItem = lvI.state = 0; + hd_listview_items = 0; + lv1_current_sel = -1; - lvI.iSubItem = column; - lvI.iItem = i; + ListView_DeleteAllItems(hwndList); - if (column == 0) - { - switch(temp_hdd[i].bus) - { + lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; + lvI.stateMask = lvI.iSubItem = lvI.state = 0; + + for (i = 0; i < HDD_NUM; i++) { + if (temp_hdd[i].bus > 0) { + hdc_id_to_listview_index[i] = j; + lvI.iSubItem = 0; + switch(temp_hdd[i].bus) { case HDD_BUS_MFM: wsprintf(szText, plat_get_string(IDS_4608), temp_hdd[i].mfm_channel >> 1, temp_hdd[i].mfm_channel & 1); break; @@ -2380,314 +2160,197 @@ static void win_settings_hard_disks_update_item(HWND hwndList, int i, int column wsprintf(szText, plat_get_string(IDS_4611), temp_hdd[i].ide_channel >> 1, temp_hdd[i].ide_channel & 1); break; case HDD_BUS_SCSI: - wsprintf(szText, plat_get_string(IDS_4612), temp_hdd[i].scsi_id, temp_hdd[i].scsi_lun); + wsprintf(szText, plat_get_string(IDS_4612), temp_hdd[i].scsi_id); break; } lvI.pszText = szText; + lvI.iItem = j; lvI.iImage = 0; - } - else if (column == 1) - { + + if (ListView_InsertItem(hwndList, &lvI) == -1) + return FALSE; + + lvI.iSubItem = 1; lvI.pszText = temp_hdd[i].fn; + lvI.iItem = j; lvI.iImage = 0; - } - else if (column == 2) - { + + if (ListView_SetItem(hwndList, &lvI) == -1) + return FALSE; + + lvI.iSubItem = 2; wsprintf(szText, plat_get_string(IDS_4098), temp_hdd[i].tracks); lvI.pszText = szText; + lvI.iItem = j; lvI.iImage = 0; - } - else if (column == 3) - { + + if (ListView_SetItem(hwndList, &lvI) == -1) + return FALSE; + + lvI.iSubItem = 3; wsprintf(szText, plat_get_string(IDS_4098), temp_hdd[i].hpc); lvI.pszText = szText; + lvI.iItem = j; lvI.iImage = 0; - } - else if (column == 4) - { + + if (ListView_SetItem(hwndList, &lvI) == -1) + return FALSE; + + lvI.iSubItem = 4; wsprintf(szText, plat_get_string(IDS_4098), temp_hdd[i].spt); lvI.pszText = szText; + lvI.iItem = j; lvI.iImage = 0; - } - else if (column == 5) - { + + if (ListView_SetItem(hwndList, &lvI) == -1) + return FALSE; + + lvI.iSubItem = 5; wsprintf(szText, plat_get_string(IDS_4098), (temp_hdd[i].tracks * temp_hdd[i].hpc * temp_hdd[i].spt) >> 11); lvI.pszText = szText; + lvI.iItem = j; lvI.iImage = 0; - } - if (ListView_SetItem(hwndList, &lvI) == -1) - { - return; - } -} - -static BOOL win_settings_hard_disks_recalc_list(HWND hwndList) -{ - LVITEM lvI; - int i = 0; - int j = 0; - WCHAR szText[256]; - - hd_listview_items = 0; - hdlv_current_sel = -1; - - ListView_DeleteAllItems(hwndList); - - lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; - lvI.stateMask = lvI.iSubItem = lvI.state = 0; - - for (i = 0; i < HDD_NUM; i++) - { - if (temp_hdd[i].bus > 0) - { - hdc_id_to_listview_index[i] = j; - lvI.iSubItem = 0; - switch(temp_hdd[i].bus) - { - case HDD_BUS_MFM: - wsprintf(szText, plat_get_string(IDS_4608), temp_hdd[i].mfm_channel >> 1, temp_hdd[i].mfm_channel & 1); - break; - case HDD_BUS_XTA: - wsprintf(szText, plat_get_string(IDS_4609), temp_hdd[i].xta_channel >> 1, temp_hdd[i].xta_channel & 1); - break; - case HDD_BUS_ESDI: - wsprintf(szText, plat_get_string(IDS_4610), temp_hdd[i].esdi_channel >> 1, temp_hdd[i].esdi_channel & 1); - break; - case HDD_BUS_IDE: - wsprintf(szText, plat_get_string(IDS_4611), temp_hdd[i].ide_channel >> 1, temp_hdd[i].ide_channel & 1); - break; - case HDD_BUS_SCSI: - wsprintf(szText, plat_get_string(IDS_4612), temp_hdd[i].scsi_id, temp_hdd[i].scsi_lun); - break; - } - lvI.pszText = szText; - lvI.iItem = j; - lvI.iImage = 0; - - if (ListView_InsertItem(hwndList, &lvI) == -1) - { - return FALSE; - } - - lvI.iSubItem = 1; - lvI.pszText = temp_hdd[i].fn; - lvI.iItem = j; - lvI.iImage = 0; - - if (ListView_SetItem(hwndList, &lvI) == -1) - { - return FALSE; - } - - lvI.iSubItem = 2; - wsprintf(szText, plat_get_string(IDS_4098), temp_hdd[i].tracks); - lvI.pszText = szText; - lvI.iItem = j; - lvI.iImage = 0; - - if (ListView_SetItem(hwndList, &lvI) == -1) - { - return FALSE; - } - - lvI.iSubItem = 3; - wsprintf(szText, plat_get_string(IDS_4098), temp_hdd[i].hpc); - lvI.pszText = szText; - lvI.iItem = j; - lvI.iImage = 0; - - if (ListView_SetItem(hwndList, &lvI) == -1) - { - return FALSE; - } - - lvI.iSubItem = 4; - wsprintf(szText, plat_get_string(IDS_4098), temp_hdd[i].spt); - lvI.pszText = szText; - lvI.iItem = j; - lvI.iImage = 0; - - if (ListView_SetItem(hwndList, &lvI) == -1) - { - return FALSE; - } - - lvI.iSubItem = 5; - wsprintf(szText, plat_get_string(IDS_4098), (temp_hdd[i].tracks * temp_hdd[i].hpc * temp_hdd[i].spt) >> 11); - lvI.pszText = szText; - lvI.iItem = j; - lvI.iImage = 0; - - if (ListView_SetItem(hwndList, &lvI) == -1) - { - return FALSE; - } - - j++; - } - else - { - hdc_id_to_listview_index[i] = -1; - } - } - - hd_listview_items = j; - - return TRUE; -} - -/* Icon, Bus, File, C, H, S, Size */ -#define C_COLUMNS_HARD_DISKS 6 - -static BOOL win_settings_hard_disks_init_columns(HWND hwndList) -{ - LVCOLUMN lvc; - int iCol; - - lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; - - for (iCol = 0; iCol < C_COLUMNS_HARD_DISKS; iCol++) - { - lvc.iSubItem = iCol; - lvc.pszText = plat_get_string(2082 + iCol); - - switch(iCol) - { - - case 0: /* Bus */ - lvc.cx = 135; - lvc.fmt = LVCFMT_LEFT; - break; - case 2: /* Cylinders */ - lvc.cx = 41; - lvc.fmt = LVCFMT_RIGHT; - break; - case 3: /* Heads */ - case 4: /* Sectors */ - lvc.cx = 25; - lvc.fmt = LVCFMT_RIGHT; - break; - case 1: /* File */ - lvc.cx = 150; - lvc.fmt = LVCFMT_LEFT; - break; - case 5: /* Size (MB) 8 */ - lvc.cx = 41; - lvc.fmt = LVCFMT_RIGHT; - break; - } - - if (ListView_InsertColumn(hwndList, iCol, &lvc) == -1) - { + if (ListView_SetItem(hwndList, &lvI) == -1) return FALSE; - } + + j++; + } else + hdc_id_to_listview_index[i] = -1; + } + + hd_listview_items = j; + + return TRUE; +} + + +static BOOL +win_settings_hard_disks_init_columns(HWND hwndList) +{ + LVCOLUMN lvc; + int iCol; + + lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; + + for (iCol = 0; iCol < C_COLUMNS_HARD_DISKS; iCol++) { + lvc.iSubItem = iCol; + lvc.pszText = plat_get_string(IDS_2082 + iCol); + + switch(iCol) { + case 0: /* Bus */ + lvc.cx = 135; + lvc.fmt = LVCFMT_LEFT; + break; + case 2: /* Cylinders */ + lvc.cx = 41; + lvc.fmt = LVCFMT_RIGHT; + break; + case 3: /* Heads */ + case 4: /* Sectors */ + lvc.cx = 25; + lvc.fmt = LVCFMT_RIGHT; + break; + case 1: /* File */ + lvc.cx = 150; + lvc.fmt = LVCFMT_LEFT; + break; + case 5: /* Size (MB) 8 */ + lvc.cx = 41; + lvc.fmt = LVCFMT_RIGHT; + break; } - return TRUE; + if (ListView_InsertColumn(hwndList, iCol, &lvc) == -1) + return FALSE; + } + + return TRUE; } -static void get_edit_box_contents(HWND hdlg, int id, uint32_t *val) + +static void +get_edit_box_contents(HWND hdlg, int id, uint32_t *val) { - HWND h; - WCHAR szText[256]; - char stransi[256]; + HWND h; + WCHAR szText[256]; + char stransi[256]; - h = GetDlgItem(hdlg, id); - SendMessage(h, WM_GETTEXT, 255, (LPARAM) szText); - wcstombs(stransi, szText, 256); - sscanf(stransi, "%u", val); + h = GetDlgItem(hdlg, id); + SendMessage(h, WM_GETTEXT, 255, (LPARAM) szText); + wcstombs(stransi, szText, 256); + sscanf(stransi, "%u", val); } -static void get_combo_box_selection(HWND hdlg, int id, uint32_t *val) + +static void +get_combo_box_selection(HWND hdlg, int id, uint32_t *val) { - HWND h; + HWND h; - h = GetDlgItem(hdlg, id); - *val = SendMessage(h, CB_GETCURSEL, 0, 0); + h = GetDlgItem(hdlg, id); + *val = SendMessage(h, CB_GETCURSEL, 0, 0); } -static void set_edit_box_contents(HWND hdlg, int id, uint32_t val) + +static void +set_edit_box_contents(HWND hdlg, int id, uint32_t val) { - HWND h; - WCHAR szText[256]; + HWND h; + WCHAR szText[256]; - h = GetDlgItem(hdlg, id); - wsprintf(szText, plat_get_string(IDS_2156), val); - SendMessage(h, WM_SETTEXT, (WPARAM) wcslen(szText), (LPARAM) szText); + h = GetDlgItem(hdlg, id); + wsprintf(szText, plat_get_string(IDS_2115), val); + SendMessage(h, WM_SETTEXT, (WPARAM) wcslen(szText), (LPARAM) szText); } -int hard_disk_added = 0; - -int64_t max_spt = 63, max_hpc = 255, - max_tracks = 266305; - -int no_update = 0; - -int existing = 0; -uint64_t selection = 127; - -static int spt, hpc, - tracks; -static uint64_t size; -static wchar_t hd_file_name[512]; - -static hard_disk_t *hdd_ptr; static int hdconf_initialize_hdt_combo(HWND hdlg) { - HWND h; - int i = 0; - uint64_t temp_size = 0; - uint32_t size_mb = 0; - WCHAR szText[256]; + HWND h; + int i = 0; + uint64_t temp_size = 0; + uint32_t size_mb = 0; + WCHAR szText[256]; - selection = 127; + selection = 127; - h = GetDlgItem(hdlg, IDC_COMBO_HD_TYPE); - for (i = 0; i < 127; i++) - { - temp_size = hdd_table[i][0] * hdd_table[i][1] * hdd_table[i][2]; - size_mb = (uint32_t) (temp_size >> 11LL); - wsprintf(szText, plat_get_string(IDS_2157), size_mb, hdd_table[i][0], hdd_table[i][1], hdd_table[i][2]); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) szText); - if ((tracks == (int) hdd_table[i][0]) && - (hpc == (int) hdd_table[i][1]) && - (spt == (int) hdd_table[i][2])) - { - selection = i; - } - } - SendMessage(h, CB_ADDSTRING, 0, win_get_string(IDS_4100)); - SendMessage(h, CB_ADDSTRING, 0, win_get_string(IDS_4101)); - SendMessage(h, CB_SETCURSEL, selection, 0); - return selection; + h = GetDlgItem(hdlg, IDC_COMBO_HD_TYPE); + for (i = 0; i < 127; i++) { + temp_size = hdd_table[i][0] * hdd_table[i][1] * hdd_table[i][2]; + size_mb = (uint32_t) (temp_size >> 11LL); + wsprintf(szText, plat_get_string(IDS_2116), size_mb, hdd_table[i][0], hdd_table[i][1], hdd_table[i][2]); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) szText); + if ((tracks == (int) hdd_table[i][0]) && (hpc == (int) hdd_table[i][1]) && + (spt == (int) hdd_table[i][2])) + selection = i; + } + SendMessage(h, CB_ADDSTRING, 0, win_get_string(IDS_4100)); + SendMessage(h, CB_ADDSTRING, 0, win_get_string(IDS_4101)); + SendMessage(h, CB_SETCURSEL, selection, 0); + return selection; } -static void recalc_selection(HWND hdlg) + +static void +recalc_selection(HWND hdlg) { - HWND h; - int i = 0; + HWND h; + int i = 0; - selection = 127; - h = GetDlgItem(hdlg, IDC_COMBO_HD_TYPE); - for (i = 0; i < 127; i++) - { - if ((tracks == (int) hdd_table[i][0]) && - (hpc == (int) hdd_table[i][1]) && - (spt == (int) hdd_table[i][2])) - { - selection = i; - } - } - if ((selection == 127) && (hpc == 16) && (spt == 63)) - { - selection = 128; - } - SendMessage(h, CB_SETCURSEL, selection, 0); + selection = 127; + h = GetDlgItem(hdlg, IDC_COMBO_HD_TYPE); + for (i = 0; i < 127; i++) { + if ((tracks == (int) hdd_table[i][0]) && + (hpc == (int) hdd_table[i][1]) && + (spt == (int) hdd_table[i][2])) + selection = i; + } + if ((selection == 127) && (hpc == 16) && (spt == 63)) + selection = 128; + SendMessage(h, CB_SETCURSEL, selection, 0); } -static int chs_enabled = 0; #ifdef __amd64__ static LRESULT CALLBACK @@ -2696,728 +2359,696 @@ static BOOL CALLBACK #endif win_settings_hard_disks_add_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) { - HWND h; - uint32_t temp, i = 0; - FILE *f; - uint32_t sector_size = 512; - uint32_t zero = 0; - uint32_t base = 0x1000; - uint64_t signature = 0xD778A82044445459ll; - char buf[512]; - char *big_buf; - int b = 0; - uint64_t r = 0; - uint8_t channel = 0; - uint8_t id = 0, lun = 0; - wchar_t *twcs; + HWND h; + FILE *f; + uint32_t temp, i = 0, sector_size = 512; + uint32_t zero = 0, base = 0x1000; + uint64_t signature = 0xD778A82044445459ll; + uint64_t temp_size, r = 0; + char buf[512], *big_buf; + int b = 0; + uint8_t channel = 0; + uint8_t id = 0; + wchar_t *twcs; + vhd_footer_t *vft = NULL; - switch (message) - { - case WM_INITDIALOG: - memset(hd_file_name, 0, sizeof(hd_file_name)); + switch (message) { + case WM_INITDIALOG: + memset(hd_file_name, 0, sizeof(hd_file_name)); - hdd_ptr = &(temp_hdd[next_free_id]); + hdd_ptr = &(temp_hdd[next_free_id]); - SetWindowText(hdlg, plat_get_string((existing & 1) ? IDS_4103 : IDS_4102)); + SetWindowText(hdlg, plat_get_string((existing & 1) ? IDS_4103 : IDS_4102)); - no_update = 1; - spt = (existing & 1) ? 0 : 17; - set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, spt); - hpc = (existing & 1) ? 0 : 15; - set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, hpc); - tracks = (existing & 1) ? 0 : 1023; - set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, tracks); - size = (tracks * hpc * spt) << 9; - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20LL)); - hdconf_initialize_hdt_combo(hdlg); - if (existing & 1) - { - h = GetDlgItem(hdlg, IDC_EDIT_HD_SPT); - EnableWindow(h, FALSE); - h = GetDlgItem(hdlg, IDC_EDIT_HD_HPC); - EnableWindow(h, FALSE); - h = GetDlgItem(hdlg, IDC_EDIT_HD_CYL); - EnableWindow(h, FALSE); - h = GetDlgItem(hdlg, IDC_EDIT_HD_SIZE); - EnableWindow(h, FALSE); - h = GetDlgItem(hdlg, IDC_COMBO_HD_TYPE); - EnableWindow(h, FALSE); - chs_enabled = 0; - } - else - { - chs_enabled = 1; - } - add_locations(hdlg); - h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); - hdd_ptr->bus = HDD_BUS_IDE; - max_spt = 63; - max_hpc = 255; - SendMessage(h, CB_SETCURSEL, hdd_ptr->bus, 0); - max_tracks = 266305; - recalc_location_controls(hdlg, 1, 0); - - channel = next_free_ide_channel(); - next_free_scsi_id_and_lun(&id, &lun); - h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); - SendMessage(h, CB_SETCURSEL, 0, 0); - h = GetDlgItem(hdlg, IDC_COMBO_HD_ID); - SendMessage(h, CB_SETCURSEL, id, 0); - h = GetDlgItem(hdlg, IDC_COMBO_HD_LUN); - SendMessage(h, CB_SETCURSEL, lun, 0); - h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL_IDE); - SendMessage(h, CB_SETCURSEL, channel, 0); - - new_hdd.mfm_channel = next_free_binary_channel(&mfm_tracking); - new_hdd.esdi_channel = next_free_binary_channel(&esdi_tracking); - new_hdd.xta_channel = next_free_binary_channel(&xta_tracking); - new_hdd.ide_channel = channel; - new_hdd.scsi_id = id; - new_hdd.scsi_lun = lun; - - h = GetDlgItem(hdlg, IDC_EDIT_HD_FILE_NAME); + no_update = 1; + spt = (existing & 1) ? 0 : 17; + set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, spt); + hpc = (existing & 1) ? 0 : 15; + set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, hpc); + tracks = (existing & 1) ? 0 : 1023; + set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, tracks); + size = (tracks * hpc * spt) << 9; + set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20LL)); + hdconf_initialize_hdt_combo(hdlg); + if (existing & 1) { + h = GetDlgItem(hdlg, IDC_EDIT_HD_SPT); EnableWindow(h, FALSE); - - h = GetDlgItem(hdlg, IDT_1752); + h = GetDlgItem(hdlg, IDC_EDIT_HD_HPC); EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - - h = GetDlgItem(hdlg, IDC_PBAR_IMG_CREATE); + h = GetDlgItem(hdlg, IDC_EDIT_HD_CYL); EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); + h = GetDlgItem(hdlg, IDC_EDIT_HD_SIZE); + EnableWindow(h, FALSE); + h = GetDlgItem(hdlg, IDC_COMBO_HD_TYPE); + EnableWindow(h, FALSE); + chs_enabled = 0; + } else + chs_enabled = 1; + add_locations(hdlg); + h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); + hdd_ptr->bus = HDD_BUS_IDE; + max_spt = 63; + max_hpc = 255; + SendMessage(h, CB_SETCURSEL, hdd_ptr->bus, 0); + max_tracks = 266305; + recalc_location_controls(hdlg, 1, 0); - no_update = 0; - return TRUE; + channel = next_free_ide_channel(); + next_free_scsi_id(&id); + h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); + SendMessage(h, CB_SETCURSEL, 0, 0); + h = GetDlgItem(hdlg, IDC_COMBO_HD_ID); + SendMessage(h, CB_SETCURSEL, id, 0); + h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL_IDE); + SendMessage(h, CB_SETCURSEL, channel, 0); - case WM_COMMAND: - switch (LOWORD(wParam)) - { - case IDOK: - h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); - hdd_ptr->bus = SendMessage(h, CB_GETCURSEL, 0, 0) + 1; + new_hdd.mfm_channel = next_free_binary_channel(&mfm_tracking); + new_hdd.esdi_channel = next_free_binary_channel(&esdi_tracking); + new_hdd.xta_channel = next_free_binary_channel(&xta_tracking); + new_hdd.ide_channel = channel; + new_hdd.scsi_id = id; - /* Make sure no file name is allowed with removable SCSI hard disks. */ - if (wcslen(hd_file_name) == 0) - { - hdd_ptr->bus = HDD_BUS_DISABLED; - settings_msgbox(MBX_ERROR, (wchar_t *)IDS_4112); - return TRUE; - } + h = GetDlgItem(hdlg, IDC_EDIT_HD_FILE_NAME); + EnableWindow(h, FALSE); - get_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, &(hdd_ptr->spt)); - get_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, &(hdd_ptr->hpc)); - get_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, &(hdd_ptr->tracks)); - spt = hdd_ptr->spt; - hpc = hdd_ptr->hpc; - tracks = hdd_ptr->tracks; + h = GetDlgItem(hdlg, IDT_1752); + EnableWindow(h, FALSE); + ShowWindow(h, SW_HIDE); - switch(hdd_ptr->bus) - { - case HDD_BUS_MFM: - h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); - hdd_ptr->mfm_channel = SendMessage(h, CB_GETCURSEL, 0, 0); - break; - case HDD_BUS_ESDI: - h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); - hdd_ptr->esdi_channel = SendMessage(h, CB_GETCURSEL, 0, 0); - break; - case HDD_BUS_XTA: - h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); - hdd_ptr->xta_channel = SendMessage(h, CB_GETCURSEL, 0, 0); - break; - case HDD_BUS_IDE: - h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL_IDE); - hdd_ptr->ide_channel = SendMessage(h, CB_GETCURSEL, 0, 0); - break; - case HDD_BUS_SCSI: - h = GetDlgItem(hdlg, IDC_COMBO_HD_ID); - hdd_ptr->scsi_id = SendMessage(h, CB_GETCURSEL, 0, 0); - h = GetDlgItem(hdlg, IDC_COMBO_HD_LUN); - hdd_ptr->scsi_lun = SendMessage(h, CB_GETCURSEL, 0, 0); - break; - } + h = GetDlgItem(hdlg, IDC_PBAR_IMG_CREATE); + EnableWindow(h, FALSE); + ShowWindow(h, SW_HIDE); - memset(hdd_ptr->fn, 0, sizeof(hdd_ptr->fn)); - wcscpy(hdd_ptr->fn, hd_file_name); + no_update = 0; + return TRUE; - sector_size = 512; + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDOK: + h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); + hdd_ptr->bus = SendMessage(h, CB_GETCURSEL, 0, 0) + 1; - if (!(existing & 1) && (wcslen(hd_file_name) > 0)) - { - f = _wfopen(hd_file_name, L"wb"); - - if (image_is_hdi(hd_file_name)) - { - if (size >= 0x100000000ll) - { - fclose(f); - settings_msgbox(MBX_ERROR, (wchar_t *)IDS_4104); - return TRUE; - } - - fwrite(&zero, 1, 4, f); /* 00000000: Zero/unknown */ - fwrite(&zero, 1, 4, f); /* 00000004: Zero/unknown */ - fwrite(&base, 1, 4, f); /* 00000008: Offset at which data starts */ - fwrite(&size, 1, 4, f); /* 0000000C: Full size of the data (32-bit) */ - fwrite(§or_size, 1, 4, f); /* 00000010: Sector size in bytes */ - fwrite(&spt, 1, 4, f); /* 00000014: Sectors per cylinder */ - fwrite(&hpc, 1, 4, f); /* 00000018: Heads per cylinder */ - fwrite(&tracks, 1, 4, f); /* 0000001C: Cylinders */ - - for (i = 0; i < 0x3f8; i++) - { - fwrite(&zero, 1, 4, f); - } - } - else if (image_is_hdx(hd_file_name, 0)) - { - if (size > 0xffffffffffffffffll) - { - fclose(f); - settings_msgbox(MBX_ERROR, (wchar_t *)IDS_4105); - return TRUE; - } - - fwrite(&signature, 1, 8, f); /* 00000000: Signature */ - fwrite(&size, 1, 8, f); /* 00000008: Full size of the data (64-bit) */ - fwrite(§or_size, 1, 4, f); /* 00000010: Sector size in bytes */ - fwrite(&spt, 1, 4, f); /* 00000014: Sectors per cylinder */ - fwrite(&hpc, 1, 4, f); /* 00000018: Heads per cylinder */ - fwrite(&tracks, 1, 4, f); /* 0000001C: Cylinders */ - fwrite(&zero, 1, 4, f); /* 00000020: [Translation] Sectors per cylinder */ - fwrite(&zero, 1, 4, f); /* 00000004: [Translation] Heads per cylinder */ - } - - memset(buf, 0, 512); - - r = size >> 20; - size &= 0xfffff; - - if (size || r) { - h = GetDlgItem(hdlg, IDT_1731); - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - - h = GetDlgItem(hdlg, IDC_EDIT_HD_FILE_NAME); - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - - h = GetDlgItem(hdlg, IDC_CFILE); - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - - h = GetDlgItem(hdlg, IDC_PBAR_IMG_CREATE); - EnableWindow(h, TRUE); - ShowWindow(h, SW_SHOW); - SendMessage(h, PBM_SETRANGE32, (WPARAM) 0, (LPARAM) r); - SendMessage(h, PBM_SETPOS, (WPARAM) 0, (LPARAM) 0); - - h = GetDlgItem(hdlg, IDT_1752); - EnableWindow(h, TRUE); - ShowWindow(h, SW_SHOW); - } - - if (size) - { - fwrite(buf, 1, size, f); - SendMessage(h, PBM_SETPOS, (WPARAM) 1, (LPARAM) 0); - } - - if (r) - { - big_buf = (char *) malloc(1048576); - memset(big_buf, 0, 1048576); - for (i = 0; i < r; i++) - { - fwrite(big_buf, 1, 1048576, f); - SendMessage(h, PBM_SETPOS, (WPARAM) (size + 1), (LPARAM) 0); - } - free(big_buf); - } - - fclose(f); - settings_msgbox(MBX_INFO, (wchar_t *)IDS_4113); - } - - hard_disk_added = 1; - EndDialog(hdlg, 0); - return TRUE; - - case IDCANCEL: - hard_disk_added = 0; + /* Make sure no file name is allowed with removable SCSI hard disks. */ + if (wcslen(hd_file_name) == 0) { hdd_ptr->bus = HDD_BUS_DISABLED; - EndDialog(hdlg, 0); + settings_msgbox(MBX_ERROR, (wchar_t *)IDS_4112); return TRUE; + } - case IDC_CFILE: - if (!file_dlg_w(hdlg, plat_get_string(IDS_4106), L"", !(existing & 1))) - { - if (!wcschr(wopenfilestring, L'.')) { - if (wcslen(wopenfilestring) && (wcslen(wopenfilestring) <= 256)) { - twcs = &wopenfilestring[wcslen(wopenfilestring)]; - twcs[0] = L'.'; - twcs[1] = L'i'; - twcs[2] = L'm'; - twcs[3] = L'g'; - } - } + get_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, &(hdd_ptr->spt)); + get_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, &(hdd_ptr->hpc)); + get_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, &(hdd_ptr->tracks)); + spt = hdd_ptr->spt; + hpc = hdd_ptr->hpc; + tracks = hdd_ptr->tracks; - if (!(existing & 1)) - { - f = _wfopen(wopenfilestring, L"rb"); - if (f != NULL) - { - fclose(f); - if (settings_msgbox(MBX_QUESTION, (wchar_t *)IDS_4111) != 0) /* yes */ - { - return FALSE; - } - } - } + switch(hdd_ptr->bus) { + case HDD_BUS_MFM: + h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); + hdd_ptr->mfm_channel = SendMessage(h, CB_GETCURSEL, 0, 0); + break; + case HDD_BUS_ESDI: + h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); + hdd_ptr->esdi_channel = SendMessage(h, CB_GETCURSEL, 0, 0); + break; + case HDD_BUS_XTA: + h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); + hdd_ptr->xta_channel = SendMessage(h, CB_GETCURSEL, 0, 0); + break; + case HDD_BUS_IDE: + h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL_IDE); + hdd_ptr->ide_channel = SendMessage(h, CB_GETCURSEL, 0, 0); + break; + case HDD_BUS_SCSI: + h = GetDlgItem(hdlg, IDC_COMBO_HD_ID); + hdd_ptr->scsi_id = SendMessage(h, CB_GETCURSEL, 0, 0); + break; + } - f = _wfopen(wopenfilestring, (existing & 1) ? L"rb" : L"wb"); - if (f == NULL) - { -hdd_add_file_open_error: - settings_msgbox(MBX_ERROR, (existing & 1) ? (wchar_t *)IDS_4107 : (wchar_t *)IDS_4108); + memset(hdd_ptr->fn, 0, sizeof(hdd_ptr->fn)); + wcscpy(hdd_ptr->fn, hd_file_name); + + sector_size = 512; + + if (!(existing & 1) && (wcslen(hd_file_name) > 0)) { + f = _wfopen(hd_file_name, L"wb"); + + if (size > 0x1FFFFFFE00ll) { + fclose(f); + settings_msgbox(MBX_ERROR, (wchar_t *)IDS_4105); + return TRUE; + } + + if (image_is_hdi(hd_file_name)) { + if (size >= 0x100000000ll) { + fclose(f); + settings_msgbox(MBX_ERROR, (wchar_t *)IDS_4104); return TRUE; } - if (existing & 1) - { - if (image_is_hdi(wopenfilestring) || image_is_hdx(wopenfilestring, 1)) - { - fseeko64(f, 0x10, SEEK_SET); - fread(§or_size, 1, 4, f); - if (sector_size != 512) - { - settings_msgbox(MBX_ERROR, (wchar_t *)IDS_4109); - fclose(f); - return TRUE; - } - spt = hpc = tracks = 0; - fread(&spt, 1, 4, f); - fread(&hpc, 1, 4, f); - fread(&tracks, 1, 4, f); - } - else - { - fseeko64(f, 0, SEEK_END); - size = ftello64(f); - fclose(f); - if (((size % 17) == 0) && (size <= 142606336)) - { - spt = 17; - if (size <= 26738688) - { - hpc = 4; - } - else if (((size % 3072) == 0) && (size <= 53477376)) - { - hpc = 6; - } - else - { - for (i = 5; i < 16; i++) - { - if (((size % (i << 9)) == 0) && (size <= ((i * 17) << 19))) - { - break; - } - if (i == 5) - { - i++; - } - } - hpc = i; - } - } - else - { - spt = 63; - hpc = 16; - } - tracks = ((size >> 9) / hpc) / spt; - } + fwrite(&zero, 1, 4, f); /* 00000000: Zero/unknown */ + fwrite(&zero, 1, 4, f); /* 00000004: Zero/unknown */ + fwrite(&base, 1, 4, f); /* 00000008: Offset at which data starts */ + fwrite(&size, 1, 4, f); /* 0000000C: Full size of the data (32-bit) */ + fwrite(§or_size, 1, 4, f); /* 00000010: Sector size in bytes */ + fwrite(&spt, 1, 4, f); /* 00000014: Sectors per cylinder */ + fwrite(&hpc, 1, 4, f); /* 00000018: Heads per cylinder */ + fwrite(&tracks, 1, 4, f); /* 0000001C: Cylinders */ - if ((spt > max_spt) || (hpc > max_hpc) || (tracks > max_tracks)) - { - goto hdd_add_file_open_error; - } - no_update = 1; - - set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, spt); - set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, hpc); - set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, tracks); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, size >> 20); - recalc_selection(hdlg); - - h = GetDlgItem(hdlg, IDC_EDIT_HD_SPT); - EnableWindow(h, TRUE); - h = GetDlgItem(hdlg, IDC_EDIT_HD_HPC); - EnableWindow(h, TRUE); - h = GetDlgItem(hdlg, IDC_EDIT_HD_CYL); - EnableWindow(h, TRUE); - h = GetDlgItem(hdlg, IDC_EDIT_HD_SIZE); - EnableWindow(h, TRUE); - h = GetDlgItem(hdlg, IDC_COMBO_HD_TYPE); - EnableWindow(h, TRUE); - - chs_enabled = 1; - - no_update = 0; + for (i = 0; i < 0x3f8; i++) + fwrite(&zero, 1, 4, f); + } else if (image_is_hdx(hd_file_name, 0)) { + fwrite(&signature, 1, 8, f); /* 00000000: Signature */ + fwrite(&size, 1, 8, f); /* 00000008: Full size of the data (64-bit) */ + fwrite(§or_size, 1, 4, f); /* 00000010: Sector size in bytes */ + fwrite(&spt, 1, 4, f); /* 00000014: Sectors per cylinder */ + fwrite(&hpc, 1, 4, f); /* 00000018: Heads per cylinder */ + fwrite(&tracks, 1, 4, f); /* 0000001C: Cylinders */ + fwrite(&zero, 1, 4, f); /* 00000020: [Translation] Sectors per cylinder */ + fwrite(&zero, 1, 4, f); /* 00000004: [Translation] Heads per cylinder */ } - else - { - fclose(f); + + memset(buf, 0, 512); + + temp_size = size; + + r = size >> 20; + size &= 0xfffff; + + if (size || r) { + h = GetDlgItem(hdlg, IDT_1731); + EnableWindow(h, FALSE); + ShowWindow(h, SW_HIDE); + + h = GetDlgItem(hdlg, IDC_EDIT_HD_FILE_NAME); + EnableWindow(h, FALSE); + ShowWindow(h, SW_HIDE); + + h = GetDlgItem(hdlg, IDC_CFILE); + EnableWindow(h, FALSE); + ShowWindow(h, SW_HIDE); + + h = GetDlgItem(hdlg, IDC_PBAR_IMG_CREATE); + EnableWindow(h, TRUE); + ShowWindow(h, SW_SHOW); + SendMessage(h, PBM_SETRANGE32, (WPARAM) 0, (LPARAM) r); + SendMessage(h, PBM_SETPOS, (WPARAM) 0, (LPARAM) 0); + + h = GetDlgItem(hdlg, IDT_1752); + EnableWindow(h, TRUE); + ShowWindow(h, SW_SHOW); + } + + if (size) { + fwrite(buf, 1, size, f); + SendMessage(h, PBM_SETPOS, (WPARAM) 1, (LPARAM) 0); + } + + if (r) { + big_buf = (char *) malloc(1048576); + memset(big_buf, 0, 1048576); + for (i = 0; i < r; i++) { + fwrite(big_buf, 1, 1048576, f); + SendMessage(h, PBM_SETPOS, (WPARAM) (size + 1), (LPARAM) 0); + } + free(big_buf); + } + + if (image_is_vhd(hd_file_name, 0)) { + /* VHD image. */ + /* Generate new footer. */ + new_vhd_footer(&vft); + vft->orig_size = vft->curr_size = temp_size; + vft->geom.cyl = tracks; + vft->geom.heads = hpc; + vft->geom.spt = spt; + generate_vhd_checksum(vft); + memset(buf, 0, 512); + vhd_footer_to_bytes((uint8_t *) buf, vft); + fwrite(buf, 1, 512, f); + memset(buf, 0, 512); + free(vft); + vft = NULL; + } + + fclose(f); + settings_msgbox(MBX_INFO, (wchar_t *)IDS_4113); + } + + hard_disk_added = 1; + EndDialog(hdlg, 0); + return TRUE; + + case IDCANCEL: + hard_disk_added = 0; + hdd_ptr->bus = HDD_BUS_DISABLED; + EndDialog(hdlg, 0); + return TRUE; + + case IDC_CFILE: + if (!file_dlg_w(hdlg, plat_get_string(IDS_4106), L"", !(existing & 1))) { + if (!wcschr(wopenfilestring, L'.')) { + if (wcslen(wopenfilestring) && (wcslen(wopenfilestring) <= 256)) { + twcs = &wopenfilestring[wcslen(wopenfilestring)]; + twcs[0] = L'.'; + twcs[1] = L'i'; + twcs[2] = L'm'; + twcs[3] = L'g'; } } - h = GetDlgItem(hdlg, IDC_EDIT_HD_FILE_NAME); - SendMessage(h, WM_SETTEXT, 0, (LPARAM) wopenfilestring); - memset(hd_file_name, 0, sizeof(hd_file_name)); - wcscpy(hd_file_name, wopenfilestring); - - return TRUE; - - case IDC_EDIT_HD_CYL: - if (no_update) - { - return FALSE; + if (!(existing & 1)) { + f = _wfopen(wopenfilestring, L"rb"); + if (f != NULL) { + fclose(f); + if (settings_msgbox(MBX_QUESTION, (wchar_t *)IDS_4111) != 0) /* yes */ + return FALSE; + } } - no_update = 1; - get_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, &temp); - if (tracks != (int64_t) temp) - { - tracks = temp; - size = (tracks * hpc * spt) << 9LL; - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); - recalc_selection(hdlg); + f = _wfopen(wopenfilestring, (existing & 1) ? L"rb" : L"wb"); + if (f == NULL) { +hdd_add_file_open_error: + settings_msgbox(MBX_ERROR, (existing & 1) ? (wchar_t *)IDS_4107 : (wchar_t *)IDS_4108); + return TRUE; } + if (existing & 1) { + if (image_is_hdi(wopenfilestring) || image_is_hdx(wopenfilestring, 1)) { + fseeko64(f, 0x10, SEEK_SET); + fread(§or_size, 1, 4, f); + if (sector_size != 512) { + settings_msgbox(MBX_ERROR, (wchar_t *)IDS_4109); + fclose(f); + return TRUE; + } + spt = hpc = tracks = 0; + fread(&spt, 1, 4, f); + fread(&hpc, 1, 4, f); + fread(&tracks, 1, 4, f); + } else if (image_is_vhd(wopenfilestring, 1)) { + fseeko64(f, -512, SEEK_END); + fread(buf, 1, 512, f); + new_vhd_footer(&vft); + vhd_footer_from_bytes(vft, (uint8_t *) buf); + size = vft->orig_size; + tracks = vft->geom.cyl; + hpc = vft->geom.heads; + spt = vft->geom.spt; + free(vft); + vft = NULL; + } else { + fseeko64(f, 0, SEEK_END); + size = ftello64(f); + fclose(f); + if (((size % 17) == 0) && (size <= 142606336)) { + spt = 17; + if (size <= 26738688) + hpc = 4; + else if (((size % 3072) == 0) && (size <= 53477376)) + hpc = 6; + else { + for (i = 5; i < 16; i++) { + if (((size % (i << 9)) == 0) && (size <= ((i * 17) << 19))) + break; + if (i == 5) + i++; + } + hpc = i; + } + } else { + spt = 63; + hpc = 16; + } - if (tracks > max_tracks) - { - tracks = max_tracks; - size = (tracks * hpc * spt) << 9LL; - set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, tracks); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); - recalc_selection(hdlg); - } + tracks = ((size >> 9) / hpc) / spt; + } - no_update = 0; - break; + if ((spt > max_spt) || (hpc > max_hpc) || (tracks > max_tracks)) + goto hdd_add_file_open_error; + no_update = 1; - case IDC_EDIT_HD_HPC: - if (no_update) - { - return FALSE; - } - - no_update = 1; - get_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, &temp); - if (hpc != (int64_t) temp) - { - hpc = temp; - size = (tracks * hpc * spt) << 9LL; - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); - recalc_selection(hdlg); - } - - if (hpc > max_hpc) - { - hpc = max_hpc; - size = (tracks * hpc * spt) << 9LL; - set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, hpc); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); - recalc_selection(hdlg); - } - - no_update = 0; - break; - - case IDC_EDIT_HD_SPT: - if (no_update) - { - return FALSE; - } - - no_update = 1; - get_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, &temp); - if (spt != (int64_t) temp) - { - spt = temp; - size = (tracks * hpc * spt) << 9LL; - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); - recalc_selection(hdlg); - } - - if (spt > max_spt) - { - spt = max_spt; - size = (tracks * hpc * spt) << 9LL; set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, spt); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); - recalc_selection(hdlg); - } - - no_update = 0; - break; - - case IDC_EDIT_HD_SIZE: - if (no_update) - { - return FALSE; - } - - no_update = 1; - get_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, &temp); - if (temp != (uint32_t) (size >> 20)) - { - size = ((uint64_t) temp) << 20LL; - tracks = (((uint32_t) (size >> 9)) / hpc) / spt; - set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, tracks); - recalc_selection(hdlg); - } - - if (tracks > max_tracks) - { - tracks = max_tracks; - size = (tracks * hpc * spt) << 9LL; - set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, tracks); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); - recalc_selection(hdlg); - } - - no_update = 0; - break; - - case IDC_COMBO_HD_TYPE: - if (no_update) - { - return FALSE; - } - - no_update = 1; - get_combo_box_selection(hdlg, IDC_COMBO_HD_TYPE, &temp); - if ((temp != selection) && (temp != 127) && (temp != 128)) - { - selection = temp; - tracks = hdd_table[selection][0]; - hpc = hdd_table[selection][1]; - spt = hdd_table[selection][2]; - size = (tracks * hpc * spt) << 9LL; - set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, tracks); set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, hpc); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, spt); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); - } - else if ((temp != selection) && (temp == 127)) - { - selection = temp; - } - else if ((temp != selection) && (temp == 128)) - { - selection = temp; - hpc = 16; - spt = 63; - size = (tracks * hpc * spt) << 9LL; - set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, hpc); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, spt); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); - } - - if (spt > max_spt) - { - spt = max_spt; - size = (tracks * hpc * spt) << 9LL; - set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, spt); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); - recalc_selection(hdlg); - } - - if (hpc > max_hpc) - { - hpc = max_hpc; - size = (tracks * hpc * spt) << 9LL; - set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, hpc); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); - recalc_selection(hdlg); - } - - if (tracks > max_tracks) - { - tracks = max_tracks; - size = (tracks * hpc * spt) << 9LL; set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, tracks); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); + set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, size >> 20); recalc_selection(hdlg); - } - no_update = 0; - break; - - case IDC_COMBO_HD_BUS: - if (no_update) - { - return FALSE; - } - - no_update = 1; - recalc_location_controls(hdlg, 1, 0); - h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); - b = SendMessage(h,CB_GETCURSEL,0,0) + 1; - if (b == hdd_ptr->bus) - { - goto hd_add_bus_skip; - } - - hdd_ptr->bus = b; - - switch(hdd_ptr->bus) - { - case HDD_BUS_DISABLED: - default: - max_spt = max_hpc = max_tracks = 0; - break; - case HDD_BUS_MFM: - max_spt = 17; - max_hpc = 15; - max_tracks = 1023; - break; - case HDD_BUS_ESDI: - case HDD_BUS_XTA: - max_spt = 63; - max_hpc = 16; - max_tracks = 1023; - break; - case HDD_BUS_IDE: - max_spt = 63; - max_hpc = 255; - max_tracks = 266305; - break; - case HDD_BUS_SCSI: - max_spt = 99; - max_hpc = 255; - max_tracks = 266305; - break; - } - - if (!chs_enabled) - { h = GetDlgItem(hdlg, IDC_EDIT_HD_SPT); - EnableWindow(h, FALSE); + EnableWindow(h, TRUE); h = GetDlgItem(hdlg, IDC_EDIT_HD_HPC); - EnableWindow(h, FALSE); + EnableWindow(h, TRUE); h = GetDlgItem(hdlg, IDC_EDIT_HD_CYL); - EnableWindow(h, FALSE); + EnableWindow(h, TRUE); h = GetDlgItem(hdlg, IDC_EDIT_HD_SIZE); - EnableWindow(h, FALSE); + EnableWindow(h, TRUE); h = GetDlgItem(hdlg, IDC_COMBO_HD_TYPE); - EnableWindow(h, FALSE); - } + EnableWindow(h, TRUE); - if (spt > max_spt) - { - spt = max_spt; - size = (tracks * hpc * spt) << 9LL; - set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, spt); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); - recalc_selection(hdlg); - } + chs_enabled = 1; - if (hpc > max_hpc) - { - hpc = max_hpc; - size = (tracks * hpc * spt) << 9LL; - set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, hpc); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); - recalc_selection(hdlg); - } + no_update = 0; + } else + fclose(f); + } - if (tracks > max_tracks) - { - tracks = max_tracks; - size = (tracks * hpc * spt) << 9LL; - set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, tracks); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); - recalc_selection(hdlg); - } + h = GetDlgItem(hdlg, IDC_EDIT_HD_FILE_NAME); + SendMessage(h, WM_SETTEXT, 0, (LPARAM) wopenfilestring); + memset(hd_file_name, 0, sizeof(hd_file_name)); + wcscpy(hd_file_name, wopenfilestring); + + return TRUE; + + case IDC_EDIT_HD_CYL: + if (no_update) + return FALSE; + + no_update = 1; + get_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, &temp); + if (tracks != (int64_t) temp) { + tracks = temp; + size = (tracks * hpc * spt) << 9LL; + set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); + recalc_selection(hdlg); + } + + if (tracks > max_tracks) { + tracks = max_tracks; + size = (tracks * hpc * spt) << 9LL; + set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, tracks); + set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); + recalc_selection(hdlg); + } + + no_update = 0; + break; + + case IDC_EDIT_HD_HPC: + if (no_update) + return FALSE; + + no_update = 1; + get_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, &temp); + if (hpc != (int64_t) temp) { + hpc = temp; + size = (tracks * hpc * spt) << 9LL; + set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); + recalc_selection(hdlg); + } + + if (hpc > max_hpc) { + hpc = max_hpc; + size = (tracks * hpc * spt) << 9LL; + set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, hpc); + set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); + recalc_selection(hdlg); + } + + no_update = 0; + break; + + case IDC_EDIT_HD_SPT: + if (no_update) + return FALSE; + + no_update = 1; + get_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, &temp); + if (spt != (int64_t) temp) { + spt = temp; + size = (tracks * hpc * spt) << 9LL; + set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); + recalc_selection(hdlg); + } + + if (spt > max_spt) { + spt = max_spt; + size = (tracks * hpc * spt) << 9LL; + set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, spt); + set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); + recalc_selection(hdlg); + } + + no_update = 0; + break; + + case IDC_EDIT_HD_SIZE: + if (no_update) + return FALSE; + + no_update = 1; + get_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, &temp); + if (temp != (uint32_t) (size >> 20)) { + size = ((uint64_t) temp) << 20LL; + /* This is needed to ensure VHD standard compliance. */ + hdd_image_calc_chs((uint32_t *) &tracks, (uint32_t *) &hpc, (uint32_t *) &spt, temp); + set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, tracks); + set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, hpc); + set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, spt); + recalc_selection(hdlg); + } + + if (tracks > max_tracks) { + tracks = max_tracks; + size = (tracks * hpc * spt) << 9LL; + set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, tracks); + set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); + recalc_selection(hdlg); + } + + if (hpc > max_hpc) { + hpc = max_hpc; + size = (tracks * hpc * spt) << 9LL; + set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, hpc); + set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); + recalc_selection(hdlg); + } + + if (spt > max_spt) { + spt = max_spt; + size = (tracks * hpc * spt) << 9LL; + set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, spt); + set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); + recalc_selection(hdlg); + } + + no_update = 0; + break; + + case IDC_COMBO_HD_TYPE: + if (no_update) + return FALSE; + + no_update = 1; + get_combo_box_selection(hdlg, IDC_COMBO_HD_TYPE, &temp); + if ((temp != selection) && (temp != 127) && (temp != 128)) { + selection = temp; + tracks = hdd_table[selection][0]; + hpc = hdd_table[selection][1]; + spt = hdd_table[selection][2]; + size = (tracks * hpc * spt) << 9LL; + set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, tracks); + set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, hpc); + set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, spt); + set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); + } else if ((temp != selection) && (temp == 127)) + selection = temp; + else if ((temp != selection) && (temp == 128)) { + selection = temp; + hpc = 16; + spt = 63; + size = (tracks * hpc * spt) << 9LL; + set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, hpc); + set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, spt); + set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); + } + + if (spt > max_spt) { + spt = max_spt; + size = (tracks * hpc * spt) << 9LL; + set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, spt); + set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); + recalc_selection(hdlg); + } + + if (hpc > max_hpc) { + hpc = max_hpc; + size = (tracks * hpc * spt) << 9LL; + set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, hpc); + set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); + recalc_selection(hdlg); + } + + if (tracks > max_tracks) { + tracks = max_tracks; + size = (tracks * hpc * spt) << 9LL; + set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, tracks); + set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); + recalc_selection(hdlg); + } + + no_update = 0; + break; + + case IDC_COMBO_HD_BUS: + if (no_update) + return FALSE; + + no_update = 1; + recalc_location_controls(hdlg, 1, 0); + h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); + b = SendMessage(h,CB_GETCURSEL,0,0) + 1; + if (b == hdd_ptr->bus) + goto hd_add_bus_skip; + + hdd_ptr->bus = b; + + switch(hdd_ptr->bus) { + case HDD_BUS_DISABLED: + default: + max_spt = max_hpc = max_tracks = 0; + break; + case HDD_BUS_MFM: + max_spt = 17; + max_hpc = 15; + max_tracks = 1023; + break; + case HDD_BUS_ESDI: + case HDD_BUS_XTA: + max_spt = 63; + max_hpc = 16; + max_tracks = 1023; + break; + case HDD_BUS_IDE: + max_spt = 63; + max_hpc = 255; + max_tracks = 266305; + break; + case HDD_BUS_SCSI: + max_spt = 99; + max_hpc = 255; + max_tracks = 266305; + break; + } + + if (!chs_enabled) { + h = GetDlgItem(hdlg, IDC_EDIT_HD_SPT); + EnableWindow(h, FALSE); + h = GetDlgItem(hdlg, IDC_EDIT_HD_HPC); + EnableWindow(h, FALSE); + h = GetDlgItem(hdlg, IDC_EDIT_HD_CYL); + EnableWindow(h, FALSE); + h = GetDlgItem(hdlg, IDC_EDIT_HD_SIZE); + EnableWindow(h, FALSE); + h = GetDlgItem(hdlg, IDC_COMBO_HD_TYPE); + EnableWindow(h, FALSE); + } + + if (spt > max_spt) { + spt = max_spt; + size = (tracks * hpc * spt) << 9LL; + set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, spt); + set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); + recalc_selection(hdlg); + } + + if (hpc > max_hpc) { + hpc = max_hpc; + size = (tracks * hpc * spt) << 9LL; + set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, hpc); + set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); + recalc_selection(hdlg); + } + + if (tracks > max_tracks) { + tracks = max_tracks; + size = (tracks * hpc * spt) << 9LL; + set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, tracks); + set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); + recalc_selection(hdlg); + } hd_add_bus_skip: - no_update = 0; - break; - } + no_update = 0; + break; + } - return FALSE; - } + return FALSE; + } - return FALSE; + return FALSE; } -int hard_disk_was_added(void) + +int +hard_disk_was_added(void) { - return hard_disk_added; + return hard_disk_added; } -void hard_disk_add_open(HWND hwnd, int is_existing) + +void +hard_disk_add_open(HWND hwnd, int is_existing) { - existing = is_existing; - hard_disk_added = 0; - DialogBox(hinstance, (LPCWSTR)DLG_CFG_HARD_DISKS_ADD, hwnd, win_settings_hard_disks_add_proc); + existing = is_existing; + hard_disk_added = 0; + DialogBox(hinstance, (LPCWSTR)DLG_CFG_HARD_DISKS_ADD, hwnd, win_settings_hard_disks_add_proc); } -static void hard_disk_track(uint8_t id) + +static void +hard_disk_track(uint8_t id) { - switch(temp_hdd[id].bus) { - case HDD_BUS_MFM: - mfm_tracking |= (1 << (temp_hdd[id].mfm_channel << 3)); - break; - case HDD_BUS_ESDI: - esdi_tracking |= (1 << (temp_hdd[id].esdi_channel << 3)); - break; - case HDD_BUS_XTA: - xta_tracking |= (1 << (temp_hdd[id].xta_channel << 3)); - break; - case HDD_BUS_IDE: - ide_tracking |= (1 << (temp_hdd[id].ide_channel << 3)); - break; - case HDD_BUS_SCSI: - scsi_tracking[temp_hdd[id].scsi_id] |= (1 << (temp_hdd[id].scsi_lun << 3)); - break; - } + switch(temp_hdd[id].bus) { + case HDD_BUS_MFM: + mfm_tracking |= (1 << (temp_hdd[id].mfm_channel << 3)); + break; + case HDD_BUS_ESDI: + esdi_tracking |= (1 << (temp_hdd[id].esdi_channel << 3)); + break; + case HDD_BUS_XTA: + xta_tracking |= (1 << (temp_hdd[id].xta_channel << 3)); + break; + case HDD_BUS_IDE: + ide_tracking |= (1 << (temp_hdd[id].ide_channel << 3)); + break; + case HDD_BUS_SCSI: + scsi_tracking[temp_hdd[id].scsi_id >> 3] |= (1 << ((temp_hdd[id].scsi_id & 0x07) << 3)); + break; + } } -static void hard_disk_untrack(uint8_t id) + +static void +hard_disk_untrack(uint8_t id) { - switch(temp_hdd[id].bus) { - case HDD_BUS_MFM: - mfm_tracking &= ~(1 << (temp_hdd[id].mfm_channel << 3)); - break; - case HDD_BUS_ESDI: - esdi_tracking &= ~(1 << (temp_hdd[id].esdi_channel << 3)); - break; - case HDD_BUS_XTA: - xta_tracking &= ~(1 << (temp_hdd[id].xta_channel << 3)); - break; - case HDD_BUS_IDE: - ide_tracking &= ~(1 << (temp_hdd[id].ide_channel << 3)); - break; - case HDD_BUS_SCSI: - scsi_tracking[temp_hdd[id].scsi_id] &= ~(1 << (temp_hdd[id].scsi_lun << 3)); - break; - } + switch(temp_hdd[id].bus) { + case HDD_BUS_MFM: + mfm_tracking &= ~(1 << (temp_hdd[id].mfm_channel << 3)); + break; + case HDD_BUS_ESDI: + esdi_tracking &= ~(1 << (temp_hdd[id].esdi_channel << 3)); + break; + case HDD_BUS_XTA: + xta_tracking &= ~(1 << (temp_hdd[id].xta_channel << 3)); + break; + case HDD_BUS_IDE: + ide_tracking &= ~(1 << (temp_hdd[id].ide_channel << 3)); + break; + case HDD_BUS_SCSI: + scsi_tracking[temp_hdd[id].scsi_id >> 3] &= ~(1 << ((temp_hdd[id].scsi_id & 0x07) << 3)); + break; + } } -static void hard_disk_track_all(void) + +static void +hard_disk_track_all(void) { - int i; + int i; - for (i = 0; i < HDD_NUM; i++) - hard_disk_track(i); + for (i = 0; i < HDD_NUM; i++) + hard_disk_track(i); } -int ignore_change = 0; #ifdef __amd64__ static LRESULT CALLBACK @@ -3426,667 +3057,210 @@ static BOOL CALLBACK #endif win_settings_hard_disks_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) { - HWND h; - int old_sel = 0; - int b = 0; - int assign = 0; + HWND h; + int old_sel = 0, b = 0, assign = 0; + const uint8_t hd_icons[2] = { 64, 0 }; - switch (message) - { - case WM_INITDIALOG: - ignore_change = 1; + switch (message) { + case WM_INITDIALOG: + ignore_change = 1; - normalize_hd_list(); /* Normalize the hard disks so that non-disabled hard disks start from index 0, and so they are contiguous. - This will cause an emulator reset prompt on the first opening of this category with a messy hard disk list - (which can only happen by manually editing the configuration file). */ - h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); - win_settings_hard_disks_init_columns(h); - win_settings_hard_disks_image_list_init(h); - win_settings_hard_disks_recalc_list(h); - recalc_next_free_id(hdlg); - add_locations(hdlg); - if (hd_listview_items > 0) - { - ListView_SetItemState(h, 0, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); - hdlv_current_sel = 0; - h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); - SendMessage(h, CB_SETCURSEL, temp_hdd[0].bus - 1, 0); - } - else - { - hdlv_current_sel = -1; - } - recalc_location_controls(hdlg, 0, 0); - - ignore_change = 0; - return TRUE; + normalize_hd_list(); /* Normalize the hard disks so that non-disabled hard disks start from index 0, and so they are contiguous. + This will cause an emulator reset prompt on the first opening of this category with a messy hard disk list + (which can only happen by manually editing the configuration file). */ + h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); + win_settings_hard_disks_init_columns(h); + image_list_init(h, (const uint8_t *) hd_icons); + win_settings_hard_disks_recalc_list(h); + recalc_next_free_id(hdlg); + add_locations(hdlg); + if (hd_listview_items > 0) { + ListView_SetItemState(h, 0, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); + lv1_current_sel = 0; + h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); + SendMessage(h, CB_SETCURSEL, temp_hdd[0].bus - 1, 0); + } else + lv1_current_sel = -1; + recalc_location_controls(hdlg, 0, 0); - case WM_NOTIFY: - if ((hd_listview_items == 0) || ignore_change) - { + ignore_change = 0; + return TRUE; + + case WM_NOTIFY: + if ((hd_listview_items == 0) || ignore_change) + return FALSE; + + if ((((LPNMHDR)lParam)->code == LVN_ITEMCHANGED) && (((LPNMHDR)lParam)->idFrom == IDC_LIST_HARD_DISKS)) { + old_sel = lv1_current_sel; + lv1_current_sel = get_selected_hard_disk(hdlg); + if (lv1_current_sel == old_sel) + return FALSE; + else if (lv1_current_sel == -1) { + ignore_change = 1; + lv1_current_sel = old_sel; + ListView_SetItemState(h, lv1_current_sel, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); + ignore_change = 0; return FALSE; } + ignore_change = 1; + h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); + SendMessage(h, CB_SETCURSEL, temp_hdd[lv1_current_sel].bus - 1, 0); + recalc_location_controls(hdlg, 0, 0); + ignore_change = 0; + } + break; - if ((((LPNMHDR)lParam)->code == LVN_ITEMCHANGED) && (((LPNMHDR)lParam)->idFrom == IDC_LIST_HARD_DISKS)) - { - old_sel = hdlv_current_sel; - hdlv_current_sel = get_selected_hard_disk(hdlg); - if (hdlv_current_sel == old_sel) - { - return FALSE; - } - else if (hdlv_current_sel == -1) - { - ignore_change = 1; - hdlv_current_sel = old_sel; - ListView_SetItemState(h, hdlv_current_sel, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); - ignore_change = 0; - return FALSE; - } + case WM_COMMAND: + if (ignore_change && (LOWORD(wParam) != IDC_BUTTON_HDD_ADD) && + (LOWORD(wParam) != IDC_BUTTON_HDD_ADD_NEW) && (LOWORD(wParam) != IDC_BUTTON_HDD_REMOVE)) + return FALSE; + switch (LOWORD(wParam)) { + case IDC_COMBO_HD_BUS: ignore_change = 1; h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); - SendMessage(h, CB_SETCURSEL, temp_hdd[hdlv_current_sel].bus - 1, 0); - recalc_location_controls(hdlg, 0, 0); - ignore_change = 0; - } - break; - - case WM_COMMAND: - switch (LOWORD(wParam)) - { - case IDC_COMBO_HD_BUS: - if (ignore_change) - { - return FALSE; - } - - ignore_change = 1; - h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); - b = SendMessage(h, CB_GETCURSEL, 0, 0) + 1; - if (b == temp_hdd[hdlv_current_sel].bus) - { - goto hd_bus_skip; - } - hard_disk_untrack(hdlv_current_sel); - assign = (temp_hdd[hdlv_current_sel].bus == b) ? 0 : 1; - temp_hdd[hdlv_current_sel].bus = b; - recalc_location_controls(hdlg, 0, assign); - hard_disk_track(hdlv_current_sel); - h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); - win_settings_hard_disks_update_item(h, hdlv_current_sel, 0); + b = SendMessage(h, CB_GETCURSEL, 0, 0) + 1; + if (b == temp_hdd[lv1_current_sel].bus) + goto hd_bus_skip; + hard_disk_untrack(lv1_current_sel); + assign = (temp_hdd[lv1_current_sel].bus == b) ? 0 : 1; + temp_hdd[lv1_current_sel].bus = b; + recalc_location_controls(hdlg, 0, assign); + hard_disk_track(lv1_current_sel); + h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); + win_settings_hard_disks_update_item(h, lv1_current_sel, 0); hd_bus_skip: - ignore_change = 0; - return FALSE; + ignore_change = 0; + return FALSE; - case IDC_COMBO_HD_CHANNEL: - if (ignore_change) - { - return FALSE; - } + case IDC_COMBO_HD_CHANNEL: + ignore_change = 1; + h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); + hard_disk_untrack(lv1_current_sel); + if (temp_hdd[lv1_current_sel].bus == HDD_BUS_MFM) + temp_hdd[lv1_current_sel].mfm_channel = SendMessage(h, CB_GETCURSEL, 0, 0); + else if (temp_hdd[lv1_current_sel].bus == HDD_BUS_ESDI) + temp_hdd[lv1_current_sel].esdi_channel = SendMessage(h, CB_GETCURSEL, 0, 0); + else if (temp_hdd[lv1_current_sel].bus == HDD_BUS_XTA) + temp_hdd[lv1_current_sel].xta_channel = SendMessage(h, CB_GETCURSEL, 0, 0); + hard_disk_track(lv1_current_sel); + h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); + win_settings_hard_disks_update_item(h, lv1_current_sel, 0); + ignore_change = 0; + return FALSE; - ignore_change = 1; - h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); - hard_disk_untrack(hdlv_current_sel); - if (temp_hdd[hdlv_current_sel].bus == HDD_BUS_MFM) - { - temp_hdd[hdlv_current_sel].mfm_channel = SendMessage(h, CB_GETCURSEL, 0, 0); - } - else if (temp_hdd[hdlv_current_sel].bus == HDD_BUS_ESDI) - { - temp_hdd[hdlv_current_sel].esdi_channel = SendMessage(h, CB_GETCURSEL, 0, 0); - } - else if (temp_hdd[hdlv_current_sel].bus == HDD_BUS_XTA) - { - temp_hdd[hdlv_current_sel].xta_channel = SendMessage(h, CB_GETCURSEL, 0, 0); - } - hard_disk_track(hdlv_current_sel); - h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); - win_settings_hard_disks_update_item(h, hdlv_current_sel, 0); - ignore_change = 0; - return FALSE; + case IDC_COMBO_HD_CHANNEL_IDE: + ignore_change = 1; + h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL_IDE); + hard_disk_untrack(lv1_current_sel); + temp_hdd[lv1_current_sel].ide_channel = SendMessage(h, CB_GETCURSEL, 0, 0); + hard_disk_track(lv1_current_sel); + h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); + win_settings_hard_disks_update_item(h, lv1_current_sel, 0); + ignore_change = 0; + return FALSE; - case IDC_COMBO_HD_CHANNEL_IDE: - if (ignore_change) - { - return FALSE; - } + case IDC_COMBO_HD_ID: + ignore_change = 1; + h = GetDlgItem(hdlg, IDC_COMBO_HD_ID); + hard_disk_untrack(lv1_current_sel); + temp_hdd[lv1_current_sel].scsi_id = SendMessage(h, CB_GETCURSEL, 0, 0); + hard_disk_track(lv1_current_sel); + h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); + win_settings_hard_disks_update_item(h, lv1_current_sel, 0); + ignore_change = 0; + return FALSE; - ignore_change = 1; - h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL_IDE); - hard_disk_untrack(hdlv_current_sel); - temp_hdd[hdlv_current_sel].ide_channel = SendMessage(h, CB_GETCURSEL, 0, 0); - hard_disk_track(hdlv_current_sel); - h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); - win_settings_hard_disks_update_item(h, hdlv_current_sel, 0); - ignore_change = 0; - return FALSE; - - case IDC_COMBO_HD_ID: - if (ignore_change) - { - return FALSE; - } - - ignore_change = 1; - h = GetDlgItem(hdlg, IDC_COMBO_HD_ID); - hard_disk_untrack(hdlv_current_sel); - temp_hdd[hdlv_current_sel].scsi_id = SendMessage(h, CB_GETCURSEL, 0, 0); - hard_disk_track(hdlv_current_sel); - h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); - win_settings_hard_disks_update_item(h, hdlv_current_sel, 0); - ignore_change = 0; - return FALSE; - - case IDC_COMBO_HD_LUN: - if (ignore_change) - { - return FALSE; - } - - ignore_change = 1; - h = GetDlgItem(hdlg, IDC_COMBO_HD_LUN); - hard_disk_untrack(hdlv_current_sel); - temp_hdd[hdlv_current_sel].scsi_lun = SendMessage(h, CB_GETCURSEL, 0, 0); - hard_disk_track(hdlv_current_sel); - h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); - win_settings_hard_disks_update_item(h, hdlv_current_sel, 0); - ignore_change = 0; - return FALSE; - - case IDC_BUTTON_HDD_ADD: - hard_disk_add_open(hdlg, 1); - if (hard_disk_added) - { - ignore_change = 1; - h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); - win_settings_hard_disks_recalc_list(h); - recalc_next_free_id(hdlg); - hard_disk_track_all(); - ignore_change = 0; - } - return FALSE; - - case IDC_BUTTON_HDD_ADD_NEW: - hard_disk_add_open(hdlg, 0); - if (hard_disk_added) - { - ignore_change = 1; - h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); - win_settings_hard_disks_recalc_list(h); - recalc_next_free_id(hdlg); - hard_disk_track_all(); - ignore_change = 0; - } - return FALSE; - - case IDC_BUTTON_HDD_REMOVE: - memcpy(temp_hdd[hdlv_current_sel].fn, L"", 4); - hard_disk_untrack(hdlv_current_sel); - temp_hdd[hdlv_current_sel].bus = HDD_BUS_DISABLED; /* Only set the bus to zero, the list normalize code below will take care of turning this entire entry to a complete zero. */ - normalize_hd_list(); /* Normalize the hard disks so that non-disabled hard disks start from index 0, and so they are contiguous. */ + case IDC_BUTTON_HDD_ADD: + hard_disk_add_open(hdlg, 1); + if (hard_disk_added) { ignore_change = 1; h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); win_settings_hard_disks_recalc_list(h); recalc_next_free_id(hdlg); - if (hd_listview_items > 0) - { - ListView_SetItemState(h, 0, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); - hdlv_current_sel = 0; - h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); - SendMessage(h, CB_SETCURSEL, temp_hdd[0].bus - 1, 0); - } - else - { - hdlv_current_sel = -1; - } - recalc_location_controls(hdlg, 0, 0); + hard_disk_track_all(); ignore_change = 0; - return FALSE; - } + } + return FALSE; - default: - return FALSE; - } + case IDC_BUTTON_HDD_ADD_NEW: + hard_disk_add_open(hdlg, 0); + if (hard_disk_added) { + ignore_change = 1; + h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); + win_settings_hard_disks_recalc_list(h); + recalc_next_free_id(hdlg); + hard_disk_track_all(); + ignore_change = 0; + } + return FALSE; - return FALSE; -} - -static int fdlv_current_sel; - -static int cdlv_current_sel; -static int zdlv_current_sel; - -static int combo_id_to_string_id(int combo_id) -{ - return IDS_5376 + combo_id; -} - -static int combo_id_to_format_string_id(int combo_id) -{ - return IDS_5632 + combo_id; -} - -static BOOL win_settings_floppy_drives_image_list_init(HWND hwndList) -{ - HICON hiconItem; - HIMAGELIST hSmall; - - int i = 0; - intptr_t icon; - - hSmall = ImageList_Create(GetSystemMetrics(SM_CXSMICON), - GetSystemMetrics(SM_CYSMICON), - ILC_MASK | ILC_COLOR32, 1, 1); - - for (i = 0; i < 14; i++) - { - icon = fdd_type_to_icon(i); - hiconItem = LoadIcon(hinstance, (LPCWSTR) icon); - ImageList_AddIcon(hSmall, hiconItem); - DestroyIcon(hiconItem); - } - - ListView_SetImageList(hwndList, hSmall, LVSIL_SMALL); - - return TRUE; -} - -static BOOL win_settings_cdrom_drives_image_list_init(HWND hwndList) -{ - HICON hiconItem; - HIMAGELIST hSmall; - - hSmall = ImageList_Create(GetSystemMetrics(SM_CXSMICON), - GetSystemMetrics(SM_CYSMICON), - ILC_MASK | ILC_COLOR32, 1, 1); - - hiconItem = LoadIcon(hinstance, (LPCWSTR) 514); - ImageList_AddIcon(hSmall, hiconItem); - DestroyIcon(hiconItem); - - hiconItem = LoadIcon(hinstance, (LPCWSTR) 160); - ImageList_AddIcon(hSmall, hiconItem); - DestroyIcon(hiconItem); - - ListView_SetImageList(hwndList, hSmall, LVSIL_SMALL); - - return TRUE; -} - -static BOOL win_settings_zip_drives_image_list_init(HWND hwndList) -{ - HICON hiconItem; - HIMAGELIST hSmall; - - hSmall = ImageList_Create(GetSystemMetrics(SM_CXSMICON), - GetSystemMetrics(SM_CYSMICON), - ILC_MASK | ILC_COLOR32, 1, 1); - - hiconItem = LoadIcon(hinstance, (LPCWSTR) 515); - ImageList_AddIcon(hSmall, hiconItem); - DestroyIcon(hiconItem); - - hiconItem = LoadIcon(hinstance, (LPCWSTR) 176); - ImageList_AddIcon(hSmall, hiconItem); - DestroyIcon(hiconItem); - - ListView_SetImageList(hwndList, hSmall, LVSIL_SMALL); - - return TRUE; -} - -static BOOL win_settings_floppy_drives_recalc_list(HWND hwndList) -{ - LVITEM lvI; - int i = 0; - char s[256]; - WCHAR szText[256]; - - lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; - lvI.stateMask = lvI.state = 0; - - for (i = 0; i < 4; i++) - { - lvI.iSubItem = 0; - if (temp_fdd_types[i] > 0) - { - strcpy(s, fdd_getname(temp_fdd_types[i])); - mbstowcs(szText, s, strlen(s) + 1); - lvI.pszText = szText; - } - else - { - lvI.pszText = plat_get_string(IDS_5376); - } - lvI.iItem = i; - lvI.iImage = temp_fdd_types[i]; - - if (ListView_InsertItem(hwndList, &lvI) == -1) - return FALSE; - - lvI.iSubItem = 1; - lvI.pszText = plat_get_string(temp_fdd_turbo[i] ? IDS_2060 : IDS_2061); - lvI.iItem = i; - lvI.iImage = 0; - - if (ListView_SetItem(hwndList, &lvI) == -1) - { - return FALSE; + case IDC_BUTTON_HDD_REMOVE: + memcpy(temp_hdd[lv1_current_sel].fn, L"", 4); + hard_disk_untrack(lv1_current_sel); + temp_hdd[lv1_current_sel].bus = HDD_BUS_DISABLED; /* Only set the bus to zero, the list normalize code below will take care of turning this entire entry to a complete zero. */ + normalize_hd_list(); /* Normalize the hard disks so that non-disabled hard disks start from index 0, and so they are contiguous. */ + ignore_change = 1; + h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); + win_settings_hard_disks_recalc_list(h); + recalc_next_free_id(hdlg); + if (hd_listview_items > 0) { + ListView_SetItemState(h, 0, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); + lv1_current_sel = 0; + h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); + SendMessage(h, CB_SETCURSEL, temp_hdd[0].bus - 1, 0); + } else + lv1_current_sel = -1; + recalc_location_controls(hdlg, 0, 0); + ignore_change = 0; + return FALSE; } - lvI.iSubItem = 2; - lvI.pszText = plat_get_string(temp_fdd_check_bpb[i] ? IDS_2060 : IDS_2061); - lvI.iItem = i; - lvI.iImage = 0; - - if (ListView_SetItem(hwndList, &lvI) == -1) - { - return FALSE; - } - } - - return TRUE; -} - -static BOOL win_settings_cdrom_drives_recalc_list(HWND hwndList) -{ - LVITEM lvI; - int i = 0; - WCHAR szText[256]; - int fsid = 0; - - lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; - lvI.stateMask = lvI.iSubItem = lvI.state = 0; - - for (i = 0; i < 4; i++) - { - fsid = combo_id_to_format_string_id(temp_cdrom_drives[i].bus_type); - - lvI.iSubItem = 0; - switch (temp_cdrom_drives[i].bus_type) - { - case CDROM_BUS_DISABLED: - default: - lvI.pszText = plat_get_string(fsid); - lvI.iImage = 0; - break; - case CDROM_BUS_ATAPI: - wsprintf(szText, plat_get_string(fsid), temp_cdrom_drives[i].ide_channel >> 1, temp_cdrom_drives[i].ide_channel & 1); - lvI.pszText = szText; - lvI.iImage = 1; - break; - case CDROM_BUS_SCSI: - wsprintf(szText, plat_get_string(fsid), temp_cdrom_drives[i].scsi_device_id, temp_cdrom_drives[i].scsi_device_lun); - lvI.pszText = szText; - lvI.iImage = 1; - break; - } - - lvI.iItem = i; - - if (ListView_InsertItem(hwndList, &lvI) == -1) - return FALSE; - - lvI.iSubItem = 1; - if (temp_cdrom_drives[i].bus_type == CDROM_BUS_DISABLED) - lvI.pszText = plat_get_string(IDS_2152); - else { - wsprintf(szText, L"%ix", temp_cdrom_drives[i].speed); - lvI.pszText = szText; - } - lvI.iItem = i; - lvI.iImage = 0; - - if (ListView_SetItem(hwndList, &lvI) == -1) - { - return FALSE; - } - } - - return TRUE; -} - -static BOOL win_settings_zip_drives_recalc_list(HWND hwndList) -{ - LVITEM lvI; - int i = 0; - WCHAR szText[256]; - int fsid = 0; - - lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; - lvI.stateMask = lvI.iSubItem = lvI.state = 0; - - for (i = 0; i < 4; i++) - { - fsid = combo_id_to_format_string_id(temp_zip_drives[i].bus_type); - - lvI.iSubItem = 0; - switch (temp_zip_drives[i].bus_type) - { - case ZIP_BUS_DISABLED: - default: - lvI.pszText = plat_get_string(fsid); - lvI.iImage = 0; - break; - case ZIP_BUS_ATAPI: - wsprintf(szText, plat_get_string(fsid), temp_zip_drives[i].ide_channel >> 1, temp_zip_drives[i].ide_channel & 1); - lvI.pszText = szText; - lvI.iImage = 1; - break; - case ZIP_BUS_SCSI: - wsprintf(szText, plat_get_string(fsid), temp_zip_drives[i].scsi_device_id, temp_zip_drives[i].scsi_device_lun); - lvI.pszText = szText; - lvI.iImage = 1; - break; - } - - lvI.iItem = i; - - if (ListView_InsertItem(hwndList, &lvI) == -1) - return FALSE; - - lvI.iSubItem = 1; - lvI.pszText = plat_get_string(temp_zip_drives[i].is_250 ? IDS_5901 : IDS_5900); - lvI.iItem = i; - lvI.iImage = 0; - - if (ListView_SetItem(hwndList, &lvI) == -1) - { - return FALSE; - } - } - - return TRUE; -} - -static BOOL win_settings_floppy_drives_init_columns(HWND hwndList) -{ - LVCOLUMN lvc; - - lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; - - lvc.iSubItem = 0; - lvc.pszText = plat_get_string(IDS_2143); - - lvc.cx = 292; - lvc.fmt = LVCFMT_LEFT; - - if (ListView_InsertColumn(hwndList, 0, &lvc) == -1) - { + default: return FALSE; - } + } - lvc.iSubItem = 1; - lvc.pszText = plat_get_string(IDS_2059); - - lvc.cx = 50; - lvc.fmt = LVCFMT_LEFT; - - if (ListView_InsertColumn(hwndList, 1, &lvc) == -1) - { - return FALSE; - } - - lvc.iSubItem = 2; - lvc.pszText = plat_get_string(IDS_2170); - - lvc.cx = 75; - lvc.fmt = LVCFMT_LEFT; - - if (ListView_InsertColumn(hwndList, 2, &lvc) == -1) - { - return FALSE; - } - return TRUE; + return FALSE; } -static BOOL win_settings_cdrom_drives_init_columns(HWND hwndList) + +static int +combo_id_to_string_id(int combo_id) { - LVCOLUMN lvc; - - lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; - - lvc.iSubItem = 0; - lvc.pszText = plat_get_string(IDS_2082); - - lvc.cx = 342; - lvc.fmt = LVCFMT_LEFT; - - if (ListView_InsertColumn(hwndList, 0, &lvc) == -1) - { - return FALSE; - } - - lvc.iSubItem = 1; - lvc.pszText = plat_get_string(IDS_2178); - - lvc.cx = 50; - lvc.fmt = LVCFMT_LEFT; - - if (ListView_InsertColumn(hwndList, 1, &lvc) == -1) - { - return FALSE; - } - - return TRUE; + return IDS_5376 + combo_id; } -static BOOL win_settings_zip_drives_init_columns(HWND hwndList) + +static int +combo_id_to_format_string_id(int combo_id) { - LVCOLUMN lvc; - - lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; - - lvc.iSubItem = 0; - lvc.pszText = plat_get_string(IDS_2082); - - lvc.cx = 342; - lvc.fmt = LVCFMT_LEFT; - - if (ListView_InsertColumn(hwndList, 0, &lvc) == -1) - { - return FALSE; - } - - lvc.iSubItem = 1; - lvc.pszText = plat_get_string(IDS_2143); - - lvc.cx = 50; - lvc.fmt = LVCFMT_LEFT; - - if (ListView_InsertColumn(hwndList, 1, &lvc) == -1) - { - return FALSE; - } - - return TRUE; + return IDS_5632 + combo_id; } -static int get_selected_floppy_drive(HWND hdlg) + +static BOOL +win_settings_floppy_drives_recalc_list(HWND hwndList) { - int floppy_drive = -1; - int i, j = 0; - HWND h; + LVITEM lvI; + int i = 0; + char s[256]; + WCHAR szText[256]; - for (i = 0; i < 6; i++) - { - h = GetDlgItem(hdlg, IDC_LIST_FLOPPY_DRIVES); - j = ListView_GetItemState(h, i, LVIS_SELECTED); - if (j) - { - floppy_drive = i; - } - } - - return floppy_drive; -} - -static int get_selected_cdrom_drive(HWND hdlg) -{ - int cd_drive = -1; - int i, j = 0; - HWND h; - - for (i = 0; i < 6; i++) - { - h = GetDlgItem(hdlg, IDC_LIST_CDROM_DRIVES); - j = ListView_GetItemState(h, i, LVIS_SELECTED); - if (j) - { - cd_drive = i; - } - } - - return cd_drive; -} - -static int get_selected_zip_drive(HWND hdlg) -{ - int zip_disk_drive = -1; - int i, j = 0; - HWND h; - - for (i = 0; i < 6; i++) - { - h = GetDlgItem(hdlg, IDC_LIST_ZIP_DRIVES); - j = ListView_GetItemState(h, i, LVIS_SELECTED); - if (j) - { - zip_disk_drive = i; - } - } - - return zip_disk_drive; -} - -static void win_settings_floppy_drives_update_item(HWND hwndList, int i) -{ - LVITEM lvI; - char s[256]; - WCHAR szText[256]; - - lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; - lvI.stateMask = lvI.iSubItem = lvI.state = 0; + lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; + lvI.stateMask = lvI.state = 0; + for (i = 0; i < 4; i++) { lvI.iSubItem = 0; - lvI.iItem = i; - - if (temp_fdd_types[i] > 0) - { + if (temp_fdd_types[i] > 0) { strcpy(s, fdd_getname(temp_fdd_types[i])); mbstowcs(szText, s, strlen(s) + 1); lvI.pszText = szText; - } - else - { + } else lvI.pszText = plat_get_string(IDS_5376); - } + lvI.iItem = i; lvI.iImage = temp_fdd_types[i]; - if (ListView_SetItem(hwndList, &lvI) == -1) - { - return; - } + if (ListView_InsertItem(hwndList, &lvI) == -1) + return FALSE; lvI.iSubItem = 1; lvI.pszText = plat_get_string(temp_fdd_turbo[i] ? IDS_2060 : IDS_2061); @@ -4094,9 +3268,7 @@ static void win_settings_floppy_drives_update_item(HWND hwndList, int i) lvI.iImage = 0; if (ListView_SetItem(hwndList, &lvI) == -1) - { - return; - } + return FALSE; lvI.iSubItem = 2; lvI.pszText = plat_get_string(temp_fdd_check_bpb[i] ? IDS_2060 : IDS_2061); @@ -4104,27 +3276,28 @@ static void win_settings_floppy_drives_update_item(HWND hwndList, int i) lvI.iImage = 0; if (ListView_SetItem(hwndList, &lvI) == -1) - { - return; - } + return FALSE; + } + + return TRUE; } -static void win_settings_cdrom_drives_update_item(HWND hwndList, int i) + +static BOOL +win_settings_cdrom_drives_recalc_list(HWND hwndList) { - LVITEM lvI; - WCHAR szText[256]; - int fsid; + LVITEM lvI; + int i = 0, fsid = 0; + WCHAR szText[256]; - lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; - lvI.stateMask = lvI.iSubItem = lvI.state = 0; - - lvI.iSubItem = 0; - lvI.iItem = i; + lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; + lvI.stateMask = lvI.iSubItem = lvI.state = 0; + for (i = 0; i < 4; i++) { fsid = combo_id_to_format_string_id(temp_cdrom_drives[i].bus_type); - switch (temp_cdrom_drives[i].bus_type) - { + lvI.iSubItem = 0; + switch (temp_cdrom_drives[i].bus_type) { case CDROM_BUS_DISABLED: default: lvI.pszText = plat_get_string(fsid); @@ -4136,20 +3309,20 @@ static void win_settings_cdrom_drives_update_item(HWND hwndList, int i) lvI.iImage = 1; break; case CDROM_BUS_SCSI: - wsprintf(szText, plat_get_string(fsid), temp_cdrom_drives[i].scsi_device_id, temp_cdrom_drives[i].scsi_device_lun); + wsprintf(szText, plat_get_string(fsid), temp_cdrom_drives[i].scsi_device_id); lvI.pszText = szText; lvI.iImage = 1; break; } - if (ListView_SetItem(hwndList, &lvI) == -1) - { - return; - } + lvI.iItem = i; + + if (ListView_InsertItem(hwndList, &lvI) == -1) + return FALSE; lvI.iSubItem = 1; if (temp_cdrom_drives[i].bus_type == CDROM_BUS_DISABLED) - lvI.pszText = plat_get_string(IDS_2152); + lvI.pszText = plat_get_string(IDS_2112); else { wsprintf(szText, L"%ix", temp_cdrom_drives[i].speed); lvI.pszText = szText; @@ -4158,27 +3331,28 @@ static void win_settings_cdrom_drives_update_item(HWND hwndList, int i) lvI.iImage = 0; if (ListView_SetItem(hwndList, &lvI) == -1) - { - return; - } + return FALSE; + } + + return TRUE; } -static void win_settings_zip_drives_update_item(HWND hwndList, int i) + +static BOOL +win_settings_zip_drives_recalc_list(HWND hwndList) { - LVITEM lvI; - WCHAR szText[256]; - int fsid; + LVITEM lvI; + int i = 0, fsid = 0; + WCHAR szText[256]; - lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; - lvI.stateMask = lvI.iSubItem = lvI.state = 0; - - lvI.iSubItem = 0; - lvI.iItem = i; + lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; + lvI.stateMask = lvI.iSubItem = lvI.state = 0; + for (i = 0; i < 4; i++) { fsid = combo_id_to_format_string_id(temp_zip_drives[i].bus_type); - switch (temp_zip_drives[i].bus_type) - { + lvI.iSubItem = 0; + switch (temp_zip_drives[i].bus_type) { case ZIP_BUS_DISABLED: default: lvI.pszText = plat_get_string(fsid); @@ -4190,16 +3364,16 @@ static void win_settings_zip_drives_update_item(HWND hwndList, int i) lvI.iImage = 1; break; case ZIP_BUS_SCSI: - wsprintf(szText, plat_get_string(fsid), temp_zip_drives[i].scsi_device_id, temp_zip_drives[i].scsi_device_lun); + wsprintf(szText, plat_get_string(fsid), temp_zip_drives[i].scsi_device_id); lvI.pszText = szText; lvI.iImage = 1; break; } - if (ListView_SetItem(hwndList, &lvI) == -1) - { - return; - } + lvI.iItem = i; + + if (ListView_InsertItem(hwndList, &lvI) == -1) + return FALSE; lvI.iSubItem = 1; lvI.pszText = plat_get_string(temp_zip_drives[i].is_250 ? IDS_5901 : IDS_5900); @@ -4207,296 +3381,507 @@ static void win_settings_zip_drives_update_item(HWND hwndList, int i) lvI.iImage = 0; if (ListView_SetItem(hwndList, &lvI) == -1) - { - return; - } + return FALSE; + } + + return TRUE; } -static void cdrom_add_locations(HWND hdlg) + +static BOOL +win_settings_floppy_drives_init_columns(HWND hwndList) { - LPTSTR lptsTemp; - HWND h; - int i = 0; + LVCOLUMN lvc; - lptsTemp = (LPTSTR) malloc(512); + lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; - h = GetDlgItem(hdlg, IDC_COMBO_CD_BUS); - for (i = CDROM_BUS_DISABLED; i <= CDROM_BUS_SCSI; i++) - { - if ((i == CDROM_BUS_DISABLED) || (i >= CDROM_BUS_ATAPI)) - { - SendMessage(h, CB_ADDSTRING, 0, win_get_string(combo_id_to_string_id(i))); - } - } + lvc.iSubItem = 0; + lvc.pszText = plat_get_string(IDS_2101); - h = GetDlgItem(hdlg, IDC_COMBO_CD_SPEED); - for (i = 1; i <= 72; i++) - { - wsprintf(lptsTemp, L"%ix", i); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); - } + lvc.cx = 292; + lvc.fmt = LVCFMT_LEFT; - h = GetDlgItem(hdlg, IDC_COMBO_CD_ID); - for (i = 0; i < 16; i++) - { - wsprintf(lptsTemp, plat_get_string(IDS_4098), i); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); - } + if (ListView_InsertColumn(hwndList, 0, &lvc) == -1) + return FALSE; - h = GetDlgItem(hdlg, IDC_COMBO_CD_LUN); - for (i = 0; i < 8; i++) - { - wsprintf(lptsTemp, plat_get_string(IDS_4098), i); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); - } + lvc.iSubItem = 1; + lvc.pszText = plat_get_string(IDS_2059); - h = GetDlgItem(hdlg, IDC_COMBO_CD_CHANNEL_IDE); - for (i = 0; i < 8; i++) - { - wsprintf(lptsTemp, plat_get_string(IDS_4097), i >> 1, i & 1); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); - } + lvc.cx = 50; + lvc.fmt = LVCFMT_LEFT; - free(lptsTemp); + if (ListView_InsertColumn(hwndList, 1, &lvc) == -1) + return FALSE; + + lvc.iSubItem = 2; + lvc.pszText = plat_get_string(IDS_2088); + + lvc.cx = 75; + lvc.fmt = LVCFMT_LEFT; + + if (ListView_InsertColumn(hwndList, 2, &lvc) == -1) + return FALSE; + + return TRUE; } + +static BOOL +win_settings_cdrom_drives_init_columns(HWND hwndList) +{ + LVCOLUMN lvc; + + lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; + + lvc.iSubItem = 0; + lvc.pszText = plat_get_string(IDS_2082); + + lvc.cx = 342; + lvc.fmt = LVCFMT_LEFT; + + if (ListView_InsertColumn(hwndList, 0, &lvc) == -1) + return FALSE; + + lvc.iSubItem = 1; + lvc.pszText = plat_get_string(IDS_2053); + + lvc.cx = 50; + lvc.fmt = LVCFMT_LEFT; + + if (ListView_InsertColumn(hwndList, 1, &lvc) == -1) + return FALSE; + + return TRUE; +} + + +static BOOL +win_settings_zip_drives_init_columns(HWND hwndList) +{ + LVCOLUMN lvc; + + lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; + + lvc.iSubItem = 0; + lvc.pszText = plat_get_string(IDS_2082); + + lvc.cx = 342; + lvc.fmt = LVCFMT_LEFT; + + if (ListView_InsertColumn(hwndList, 0, &lvc) == -1) + return FALSE; + + lvc.iSubItem = 1; + lvc.pszText = plat_get_string(IDS_2101); + + lvc.cx = 50; + lvc.fmt = LVCFMT_LEFT; + + if (ListView_InsertColumn(hwndList, 1, &lvc) == -1) + return FALSE; + + return TRUE; +} + + +static int +get_selected_drive(HWND hdlg, int id) +{ + int drive = -1; + int i, j = 0; + HWND h; + + for (i = 0; i < 4; i++) { + h = GetDlgItem(hdlg, id); + j = ListView_GetItemState(h, i, LVIS_SELECTED); + if (j) + drive = i; + } + + return drive; +} + + +static void +win_settings_floppy_drives_update_item(HWND hwndList, int i) +{ + LVITEM lvI; + char s[256]; + WCHAR szText[256]; + + lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; + lvI.stateMask = lvI.iSubItem = lvI.state = 0; + + lvI.iSubItem = 0; + lvI.iItem = i; + + if (temp_fdd_types[i] > 0) { + strcpy(s, fdd_getname(temp_fdd_types[i])); + mbstowcs(szText, s, strlen(s) + 1); + lvI.pszText = szText; + } else + lvI.pszText = plat_get_string(IDS_5376); + lvI.iImage = temp_fdd_types[i]; + + if (ListView_SetItem(hwndList, &lvI) == -1) + return; + + lvI.iSubItem = 1; + lvI.pszText = plat_get_string(temp_fdd_turbo[i] ? IDS_2060 : IDS_2061); + lvI.iItem = i; + lvI.iImage = 0; + + if (ListView_SetItem(hwndList, &lvI) == -1) + return; + + lvI.iSubItem = 2; + lvI.pszText = plat_get_string(temp_fdd_check_bpb[i] ? IDS_2060 : IDS_2061); + lvI.iItem = i; + lvI.iImage = 0; + + if (ListView_SetItem(hwndList, &lvI) == -1) + return; +} + + +static void +win_settings_cdrom_drives_update_item(HWND hwndList, int i) +{ + LVITEM lvI; + WCHAR szText[256]; + int fsid; + + lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; + lvI.stateMask = lvI.iSubItem = lvI.state = 0; + + lvI.iSubItem = 0; + lvI.iItem = i; + + fsid = combo_id_to_format_string_id(temp_cdrom_drives[i].bus_type); + + switch (temp_cdrom_drives[i].bus_type) { + case CDROM_BUS_DISABLED: + default: + lvI.pszText = plat_get_string(fsid); + lvI.iImage = 0; + break; + case CDROM_BUS_ATAPI: + wsprintf(szText, plat_get_string(fsid), temp_cdrom_drives[i].ide_channel >> 1, temp_cdrom_drives[i].ide_channel & 1); + lvI.pszText = szText; + lvI.iImage = 1; + break; + case CDROM_BUS_SCSI: + wsprintf(szText, plat_get_string(fsid), temp_cdrom_drives[i].scsi_device_id); + lvI.pszText = szText; + lvI.iImage = 1; + break; + } + + if (ListView_SetItem(hwndList, &lvI) == -1) + return; + + lvI.iSubItem = 1; + if (temp_cdrom_drives[i].bus_type == CDROM_BUS_DISABLED) + lvI.pszText = plat_get_string(IDS_2112); + else { + wsprintf(szText, L"%ix", temp_cdrom_drives[i].speed); + lvI.pszText = szText; + } + lvI.iItem = i; + lvI.iImage = 0; + + if (ListView_SetItem(hwndList, &lvI) == -1) + return; +} + + +static void +win_settings_zip_drives_update_item(HWND hwndList, int i) +{ + LVITEM lvI; + WCHAR szText[256]; + int fsid; + + lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; + lvI.stateMask = lvI.iSubItem = lvI.state = 0; + + lvI.iSubItem = 0; + lvI.iItem = i; + + fsid = combo_id_to_format_string_id(temp_zip_drives[i].bus_type); + + switch (temp_zip_drives[i].bus_type) { + case ZIP_BUS_DISABLED: + default: + lvI.pszText = plat_get_string(fsid); + lvI.iImage = 0; + break; + case ZIP_BUS_ATAPI: + wsprintf(szText, plat_get_string(fsid), temp_zip_drives[i].ide_channel >> 1, temp_zip_drives[i].ide_channel & 1); + lvI.pszText = szText; + lvI.iImage = 1; + break; + case ZIP_BUS_SCSI: + wsprintf(szText, plat_get_string(fsid), temp_zip_drives[i].scsi_device_id); + lvI.pszText = szText; + lvI.iImage = 1; + break; + } + + if (ListView_SetItem(hwndList, &lvI) == -1) + return; + + lvI.iSubItem = 1; + lvI.pszText = plat_get_string(temp_zip_drives[i].is_250 ? IDS_5901 : IDS_5900); + lvI.iItem = i; + lvI.iImage = 0; + + if (ListView_SetItem(hwndList, &lvI) == -1) + return; +} + + +static void +cdrom_add_locations(HWND hdlg) +{ + LPTSTR lptsTemp; + HWND h; + int i = 0; + + lptsTemp = (LPTSTR) malloc(512); + + h = GetDlgItem(hdlg, IDC_COMBO_CD_BUS); + for (i = CDROM_BUS_DISABLED; i <= CDROM_BUS_SCSI; i++) { + if ((i == CDROM_BUS_DISABLED) || (i >= CDROM_BUS_ATAPI)) + SendMessage(h, CB_ADDSTRING, 0, win_get_string(combo_id_to_string_id(i))); + } + + h = GetDlgItem(hdlg, IDC_COMBO_CD_SPEED); + for (i = 1; i <= 72; i++) { + wsprintf(lptsTemp, L"%ix", i); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); + } + + h = GetDlgItem(hdlg, IDC_COMBO_CD_ID); + for (i = 0; i < 16; i++) { + wsprintf(lptsTemp, plat_get_string(IDS_4098), i); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); + } + + h = GetDlgItem(hdlg, IDC_COMBO_CD_CHANNEL_IDE); + for (i = 0; i < 8; i++) { + wsprintf(lptsTemp, plat_get_string(IDS_4097), i >> 1, i & 1); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); + } + + free(lptsTemp); +} + + static void cdrom_recalc_location_controls(HWND hdlg, int assign_id) { - int i = 0; - HWND h; + int i = 0; + HWND h; - int bus = temp_cdrom_drives[cdlv_current_sel].bus_type; + int bus = temp_cdrom_drives[lv1_current_sel].bus_type; - for (i = IDT_1741; i < (IDT_1743 + 1); i++) - { - h = GetDlgItem(hdlg, i); - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - } - - h = GetDlgItem(hdlg, IDC_COMBO_CD_ID); + for (i = IDT_1741; i < (IDT_1742 + 1); i++) { + h = GetDlgItem(hdlg, i); EnableWindow(h, FALSE); ShowWindow(h, SW_HIDE); + } - h = GetDlgItem(hdlg, IDC_COMBO_CD_LUN); + h = GetDlgItem(hdlg, IDC_COMBO_CD_ID); + EnableWindow(h, FALSE); + ShowWindow(h, SW_HIDE); + + h = GetDlgItem(hdlg, IDC_COMBO_CD_CHANNEL_IDE); + EnableWindow(h, FALSE); + ShowWindow(h, SW_HIDE); + + h = GetDlgItem(hdlg, IDC_COMBO_CD_SPEED); + if (bus == CDROM_BUS_DISABLED) { EnableWindow(h, FALSE); ShowWindow(h, SW_HIDE); + } else { + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + SendMessage(h, CB_SETCURSEL, temp_cdrom_drives[lv1_current_sel].speed - 1, 0); + } - h = GetDlgItem(hdlg, IDC_COMBO_CD_CHANNEL_IDE); + h = GetDlgItem(hdlg, IDT_1758); + if (bus == CDROM_BUS_DISABLED) { EnableWindow(h, FALSE); ShowWindow(h, SW_HIDE); + } else { + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + } - h = GetDlgItem(hdlg, IDC_COMBO_CD_SPEED); - if (bus == CDROM_BUS_DISABLED) { - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - } else { + switch(bus) { + case CDROM_BUS_ATAPI: /* ATAPI */ + h = GetDlgItem(hdlg, IDT_1742); ShowWindow(h, SW_SHOW); EnableWindow(h, TRUE); - SendMessage(h, CB_SETCURSEL, temp_cdrom_drives[cdlv_current_sel].speed - 1, 0); - } - switch(bus) - { - case CDROM_BUS_ATAPI: /* ATAPI */ - h = GetDlgItem(hdlg, IDT_1743); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); + if (assign_id) + temp_cdrom_drives[lv1_current_sel].ide_channel = next_free_ide_channel(); - if (assign_id) - temp_cdrom_drives[cdlv_current_sel].ide_channel = next_free_ide_channel(); + h = GetDlgItem(hdlg, IDC_COMBO_CD_CHANNEL_IDE); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + SendMessage(h, CB_SETCURSEL, temp_cdrom_drives[lv1_current_sel].ide_channel, 0); + break; + case CDROM_BUS_SCSI: /* SCSI */ + h = GetDlgItem(hdlg, IDT_1741); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); - h = GetDlgItem(hdlg, IDC_COMBO_CD_CHANNEL_IDE); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - SendMessage(h, CB_SETCURSEL, temp_cdrom_drives[cdlv_current_sel].ide_channel, 0); - break; - case CDROM_BUS_SCSI: /* SCSI */ - h = GetDlgItem(hdlg, IDT_1741); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - h = GetDlgItem(hdlg, IDT_1742); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); + if (assign_id) + next_free_scsi_id((uint8_t *) &temp_cdrom_drives[lv1_current_sel].scsi_device_id); - if (assign_id) - next_free_scsi_id_and_lun((uint8_t *) &temp_cdrom_drives[cdlv_current_sel].scsi_device_id, (uint8_t *) &temp_cdrom_drives[cdlv_current_sel].scsi_device_lun); - - h = GetDlgItem(hdlg, IDC_COMBO_CD_ID); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - SendMessage(h, CB_SETCURSEL, temp_cdrom_drives[cdlv_current_sel].scsi_device_id, 0); - - h = GetDlgItem(hdlg, IDC_COMBO_CD_LUN); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - SendMessage(h, CB_SETCURSEL, temp_cdrom_drives[cdlv_current_sel].scsi_device_lun, 0); - break; - } + h = GetDlgItem(hdlg, IDC_COMBO_CD_ID); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + SendMessage(h, CB_SETCURSEL, temp_cdrom_drives[lv1_current_sel].scsi_device_id, 0); + break; + } } -static void zip_add_locations(HWND hdlg) + +static void +zip_add_locations(HWND hdlg) { - LPTSTR lptsTemp; - HWND h; - int i = 0; + LPTSTR lptsTemp; + HWND h; + int i = 0; - lptsTemp = (LPTSTR) malloc(512); + lptsTemp = (LPTSTR) malloc(512); - h = GetDlgItem(hdlg, IDC_COMBO_ZIP_BUS); - for (i = ZIP_BUS_DISABLED; i <= ZIP_BUS_SCSI; i++) - { - if ((i == ZIP_BUS_DISABLED) || (i >= ZIP_BUS_ATAPI)) - { - SendMessage(h, CB_ADDSTRING, 0, win_get_string(combo_id_to_string_id(i))); - } - } + h = GetDlgItem(hdlg, IDC_COMBO_ZIP_BUS); + for (i = ZIP_BUS_DISABLED; i <= ZIP_BUS_SCSI; i++) { + if ((i == ZIP_BUS_DISABLED) || (i >= ZIP_BUS_ATAPI)) + SendMessage(h, CB_ADDSTRING, 0, win_get_string(combo_id_to_string_id(i))); + } - h = GetDlgItem(hdlg, IDC_COMBO_ZIP_ID); - for (i = 0; i < 16; i++) - { - wsprintf(lptsTemp, plat_get_string(IDS_4098), i); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); - } + h = GetDlgItem(hdlg, IDC_COMBO_ZIP_ID); + for (i = 0; i < 16; i++) { + wsprintf(lptsTemp, plat_get_string(IDS_4098), i); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); + } - h = GetDlgItem(hdlg, IDC_COMBO_ZIP_LUN); - for (i = 0; i < 8; i++) - { - wsprintf(lptsTemp, plat_get_string(IDS_4098), i); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); - } + h = GetDlgItem(hdlg, IDC_COMBO_ZIP_CHANNEL_IDE); + for (i = 0; i < 8; i++) { + wsprintf(lptsTemp, plat_get_string(IDS_4097), i >> 1, i & 1); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); + } - h = GetDlgItem(hdlg, IDC_COMBO_ZIP_CHANNEL_IDE); - for (i = 0; i < 8; i++) - { - wsprintf(lptsTemp, plat_get_string(IDS_4097), i >> 1, i & 1); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); - } - - free(lptsTemp); + free(lptsTemp); } -static void zip_recalc_location_controls(HWND hdlg, int assign_id) + +static void +zip_recalc_location_controls(HWND hdlg, int assign_id) { - int i = 0; - HWND h; + int i = 0; + HWND h; - int bus = temp_zip_drives[zdlv_current_sel].bus_type; + int bus = temp_zip_drives[lv2_current_sel].bus_type; - for (i = IDT_1754; i < (IDT_1756 + 1); i++) - { - h = GetDlgItem(hdlg, i); - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - } - - h = GetDlgItem(hdlg, IDC_COMBO_ZIP_ID); + for (i = IDT_1754; i < (IDT_1755 + 1); i++) { + h = GetDlgItem(hdlg, i); EnableWindow(h, FALSE); ShowWindow(h, SW_HIDE); + } - h = GetDlgItem(hdlg, IDC_COMBO_ZIP_LUN); + h = GetDlgItem(hdlg, IDC_COMBO_ZIP_ID); + EnableWindow(h, FALSE); + ShowWindow(h, SW_HIDE); + + h = GetDlgItem(hdlg, IDC_COMBO_ZIP_CHANNEL_IDE); + EnableWindow(h, FALSE); + ShowWindow(h, SW_HIDE); + + h = GetDlgItem(hdlg, IDC_CHECK250); + if (bus == ZIP_BUS_DISABLED) { EnableWindow(h, FALSE); ShowWindow(h, SW_HIDE); + } else { + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + SendMessage(h, BM_SETCHECK, temp_zip_drives[lv2_current_sel].is_250, 0); + } - h = GetDlgItem(hdlg, IDC_COMBO_ZIP_CHANNEL_IDE); - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); + switch(bus) { + case ZIP_BUS_ATAPI: /* ATAPI */ + h = GetDlgItem(hdlg, IDT_1755); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); - switch(bus) - { - case ZIP_BUS_ATAPI: /* ATAPI */ - h = GetDlgItem(hdlg, IDT_1756); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); + if (assign_id) + temp_zip_drives[lv2_current_sel].ide_channel = next_free_ide_channel(); - if (assign_id) - temp_zip_drives[zdlv_current_sel].ide_channel = next_free_ide_channel(); + h = GetDlgItem(hdlg, IDC_COMBO_ZIP_CHANNEL_IDE); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + SendMessage(h, CB_SETCURSEL, temp_zip_drives[lv2_current_sel].ide_channel, 0); + break; + case ZIP_BUS_SCSI: /* SCSI */ + h = GetDlgItem(hdlg, IDT_1754); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); - h = GetDlgItem(hdlg, IDC_COMBO_ZIP_CHANNEL_IDE); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - SendMessage(h, CB_SETCURSEL, temp_zip_drives[zdlv_current_sel].ide_channel, 0); - break; - case ZIP_BUS_SCSI: /* SCSI */ - h = GetDlgItem(hdlg, IDT_1754); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - h = GetDlgItem(hdlg, IDT_1755); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); + if (assign_id) + next_free_scsi_id((uint8_t *) &temp_zip_drives[lv2_current_sel].scsi_device_id); - if (assign_id) - next_free_scsi_id_and_lun((uint8_t *) &temp_zip_drives[zdlv_current_sel].scsi_device_id, (uint8_t *) &temp_zip_drives[zdlv_current_sel].scsi_device_lun); - - h = GetDlgItem(hdlg, IDC_COMBO_ZIP_ID); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - SendMessage(h, CB_SETCURSEL, temp_zip_drives[zdlv_current_sel].scsi_device_id, 0); - - h = GetDlgItem(hdlg, IDC_COMBO_ZIP_LUN); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - SendMessage(h, CB_SETCURSEL, temp_zip_drives[zdlv_current_sel].scsi_device_lun, 0); - break; - } + h = GetDlgItem(hdlg, IDC_COMBO_ZIP_ID); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + SendMessage(h, CB_SETCURSEL, temp_zip_drives[lv2_current_sel].scsi_device_id, 0); + break; + } } -static void cdrom_track(uint8_t id) +static void +cdrom_track(uint8_t id) { - if (temp_cdrom_drives[id].bus_type == CDROM_BUS_ATAPI) - ide_tracking |= (2 << (temp_cdrom_drives[id].ide_channel << 3)); - else if (temp_cdrom_drives[id].bus_type == CDROM_BUS_SCSI) - scsi_tracking[temp_cdrom_drives[id].scsi_device_id] |= (1 << temp_cdrom_drives[id].scsi_device_lun); + if (temp_cdrom_drives[id].bus_type == CDROM_BUS_ATAPI) + ide_tracking |= (2 << (temp_cdrom_drives[id].ide_channel << 3)); + else if (temp_cdrom_drives[id].bus_type == CDROM_BUS_SCSI) + scsi_tracking[temp_cdrom_drives[id].scsi_device_id >> 3] |= (1 << (temp_cdrom_drives[id].scsi_device_id & 0x07)); } -static void cdrom_untrack(uint8_t id) + +static void +cdrom_untrack(uint8_t id) { - if (temp_cdrom_drives[id].bus_type == CDROM_BUS_ATAPI) - ide_tracking &= ~(2 << (temp_cdrom_drives[id].ide_channel << 3)); - else if (temp_cdrom_drives[id].bus_type == CDROM_BUS_SCSI) - scsi_tracking[temp_cdrom_drives[id].scsi_device_id] &= ~(1 << temp_cdrom_drives[id].scsi_device_lun); + if (temp_cdrom_drives[id].bus_type == CDROM_BUS_ATAPI) + ide_tracking &= ~(2 << (temp_cdrom_drives[id].ide_channel << 3)); + else if (temp_cdrom_drives[id].bus_type == CDROM_BUS_SCSI) + scsi_tracking[temp_cdrom_drives[id].scsi_device_id >> 3] &= ~(1 << (temp_cdrom_drives[id].scsi_device_id & 0x07)); } -#if 0 -static void cdrom_track_all(void) + +static void +zip_track(uint8_t id) { - int i; - - for (i = 0; i < CDROM_NUM; i++) - cdrom_track(i); + if (temp_zip_drives[id].bus_type == ZIP_BUS_ATAPI) + ide_tracking |= (1 << temp_zip_drives[id].ide_channel); + else if (temp_zip_drives[id].bus_type == ZIP_BUS_SCSI) + scsi_tracking[temp_zip_drives[id].scsi_device_id >> 3] |= (1 << (temp_zip_drives[id].scsi_device_id & 0x07)); } -#endif -static void zip_track(uint8_t id) +static void +zip_untrack(uint8_t id) { - if (temp_zip_drives[id].bus_type == ZIP_BUS_ATAPI) - ide_tracking |= (1 << temp_zip_drives[id].ide_channel); - else if (temp_zip_drives[id].bus_type == ZIP_BUS_SCSI) - scsi_tracking[temp_zip_drives[id].scsi_device_id] |= (1 << temp_zip_drives[id].scsi_device_lun); + if (temp_zip_drives[id].bus_type == ZIP_BUS_ATAPI) + ide_tracking &= ~(1 << temp_zip_drives[id].ide_channel); + else if (temp_zip_drives[id].bus_type == ZIP_BUS_SCSI) + scsi_tracking[temp_zip_drives[id].scsi_device_id >> 3] &= ~(1 << (temp_zip_drives[id].scsi_device_id & 0x07)); } -static void zip_untrack(uint8_t id) -{ - if (temp_zip_drives[id].bus_type == ZIP_BUS_ATAPI) - ide_tracking &= ~(1 << temp_zip_drives[id].ide_channel); - else if (temp_zip_drives[id].bus_type == ZIP_BUS_SCSI) - scsi_tracking[temp_zip_drives[id].scsi_device_id] &= ~(1 << temp_zip_drives[id].scsi_device_lun); -} - -#if 0 -static void zip_track_all(void) -{ - int i; - - for (i = 0; i < ZIP_NUM; i++) - zip_track(i); -} -#endif - - -int fd_ignore_change = 0; #ifdef __amd64__ static LRESULT CALLBACK @@ -4505,133 +3890,104 @@ static BOOL CALLBACK #endif win_settings_floppy_drives_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) { - HWND h; - int i = 0; - int old_sel = 0; - WCHAR szText[256]; + HWND h; + int i = 0, old_sel = 0; + WCHAR szText[256]; + const uint8_t fd_icons[15] = { 248, 16, 16, 16, 16, 16, 16, 24, 24, 24, 24, 24, 24, 24, 0 }; - switch (message) - { - case WM_INITDIALOG: - fd_ignore_change = 1; + switch (message) { + case WM_INITDIALOG: + ignore_change = 1; - fdlv_current_sel = 0; - h = GetDlgItem(hdlg, IDC_LIST_FLOPPY_DRIVES); - win_settings_floppy_drives_init_columns(h); - win_settings_floppy_drives_image_list_init(h); - win_settings_floppy_drives_recalc_list(h); - ListView_SetItemState(h, 0, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); - h = GetDlgItem(hdlg, IDC_COMBO_FD_TYPE); - for (i = 0; i < 14; i++) - { - if (i == 0) - { - SendMessage(h, CB_ADDSTRING, 0, win_get_string(IDS_5376)); - } - else - { - mbstowcs(szText, fdd_getname(i), strlen(fdd_getname(i)) + 1); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) szText); - } + lv1_current_sel = 0; + h = GetDlgItem(hdlg, IDC_LIST_FLOPPY_DRIVES); + win_settings_floppy_drives_init_columns(h); + image_list_init(h, (const uint8_t *) fd_icons); + win_settings_floppy_drives_recalc_list(h); + ListView_SetItemState(h, 0, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); + h = GetDlgItem(hdlg, IDC_COMBO_FD_TYPE); + for (i = 0; i < 14; i++) { + if (i == 0) + SendMessage(h, CB_ADDSTRING, 0, win_get_string(IDS_5376)); + else { + mbstowcs(szText, fdd_getname(i), strlen(fdd_getname(i)) + 1); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) szText); } - SendMessage(h, CB_SETCURSEL, temp_fdd_types[fdlv_current_sel], 0); + } + SendMessage(h, CB_SETCURSEL, temp_fdd_types[lv1_current_sel], 0); - h = GetDlgItem(hdlg, IDC_CHECKTURBO); - SendMessage(h, BM_SETCHECK, temp_fdd_turbo[fdlv_current_sel], 0); + h = GetDlgItem(hdlg, IDC_CHECKTURBO); + SendMessage(h, BM_SETCHECK, temp_fdd_turbo[lv1_current_sel], 0); - h = GetDlgItem(hdlg, IDC_CHECKBPB); - SendMessage(h, BM_SETCHECK, temp_fdd_check_bpb[fdlv_current_sel], 0); + h = GetDlgItem(hdlg, IDC_CHECKBPB); + SendMessage(h, BM_SETCHECK, temp_fdd_check_bpb[lv1_current_sel], 0); - fd_ignore_change = 0; - return TRUE; + ignore_change = 0; + return TRUE; - case WM_NOTIFY: - if (fd_ignore_change) - { + case WM_NOTIFY: + if (ignore_change) + return FALSE; + + if ((((LPNMHDR)lParam)->code == LVN_ITEMCHANGED) && (((LPNMHDR)lParam)->idFrom == IDC_LIST_FLOPPY_DRIVES)) { + old_sel = lv1_current_sel; + lv1_current_sel = get_selected_drive(hdlg, IDC_LIST_FLOPPY_DRIVES); + if (lv1_current_sel == old_sel) + return FALSE; + else if (lv1_current_sel == -1) { + ignore_change = 1; + lv1_current_sel = old_sel; + ListView_SetItemState(h, lv1_current_sel, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); + ignore_change = 0; return FALSE; } + ignore_change = 1; + h = GetDlgItem(hdlg, IDC_COMBO_FD_TYPE); + SendMessage(h, CB_SETCURSEL, temp_fdd_types[lv1_current_sel], 0); + h = GetDlgItem(hdlg, IDC_CHECKTURBO); + SendMessage(h, BM_SETCHECK, temp_fdd_turbo[lv1_current_sel], 0); + h = GetDlgItem(hdlg, IDC_CHECKBPB); + SendMessage(h, BM_SETCHECK, temp_fdd_check_bpb[lv1_current_sel], 0); + ignore_change = 0; + } + break; - if ((((LPNMHDR)lParam)->code == LVN_ITEMCHANGED) && (((LPNMHDR)lParam)->idFrom == IDC_LIST_FLOPPY_DRIVES)) - { - old_sel = fdlv_current_sel; - fdlv_current_sel = get_selected_floppy_drive(hdlg); - if (fdlv_current_sel == old_sel) - { - return FALSE; - } - else if (fdlv_current_sel == -1) - { - fd_ignore_change = 1; - fdlv_current_sel = old_sel; - ListView_SetItemState(h, fdlv_current_sel, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); - fd_ignore_change = 0; - return FALSE; - } - fd_ignore_change = 1; - h = GetDlgItem(hdlg, IDC_COMBO_FD_TYPE); - SendMessage(h, CB_SETCURSEL, temp_fdd_types[fdlv_current_sel], 0); - h = GetDlgItem(hdlg, IDC_CHECKTURBO); - SendMessage(h, BM_SETCHECK, temp_fdd_turbo[fdlv_current_sel], 0); - h = GetDlgItem(hdlg, IDC_CHECKBPB); - SendMessage(h, BM_SETCHECK, temp_fdd_check_bpb[fdlv_current_sel], 0); - fd_ignore_change = 0; - } - break; - - case WM_COMMAND: - switch (LOWORD(wParam)) - { - case IDC_COMBO_FD_TYPE: - if (fd_ignore_change) - { - return FALSE; - } - - fd_ignore_change = 1; - h = GetDlgItem(hdlg, IDC_COMBO_FD_TYPE); - temp_fdd_types[fdlv_current_sel] = SendMessage(h, CB_GETCURSEL, 0, 0); - h = GetDlgItem(hdlg, IDC_LIST_FLOPPY_DRIVES); - win_settings_floppy_drives_update_item(h, fdlv_current_sel); - fd_ignore_change = 0; - return FALSE; - - case IDC_CHECKTURBO: - if (fd_ignore_change) - { - return FALSE; - } - - fd_ignore_change = 1; - h = GetDlgItem(hdlg, IDC_CHECKTURBO); - temp_fdd_turbo[fdlv_current_sel] = SendMessage(h, BM_GETCHECK, 0, 0); - h = GetDlgItem(hdlg, IDC_LIST_FLOPPY_DRIVES); - win_settings_floppy_drives_update_item(h, fdlv_current_sel); - fd_ignore_change = 0; - return FALSE; - - case IDC_CHECKBPB: - if (fd_ignore_change) - { - return FALSE; - } - - fd_ignore_change = 1; - h = GetDlgItem(hdlg, IDC_CHECKBPB); - temp_fdd_check_bpb[fdlv_current_sel] = SendMessage(h, BM_GETCHECK, 0, 0); - h = GetDlgItem(hdlg, IDC_LIST_FLOPPY_DRIVES); - win_settings_floppy_drives_update_item(h, fdlv_current_sel); - fd_ignore_change = 0; - return FALSE; - } - - default: + case WM_COMMAND: + if (ignore_change) return FALSE; - } - return FALSE; + ignore_change = 1; + switch (LOWORD(wParam)) { + case IDC_COMBO_FD_TYPE: + h = GetDlgItem(hdlg, IDC_COMBO_FD_TYPE); + temp_fdd_types[lv1_current_sel] = SendMessage(h, CB_GETCURSEL, 0, 0); + h = GetDlgItem(hdlg, IDC_LIST_FLOPPY_DRIVES); + win_settings_floppy_drives_update_item(h, lv1_current_sel); + break; + + case IDC_CHECKTURBO: + h = GetDlgItem(hdlg, IDC_CHECKTURBO); + temp_fdd_turbo[lv1_current_sel] = SendMessage(h, BM_GETCHECK, 0, 0); + h = GetDlgItem(hdlg, IDC_LIST_FLOPPY_DRIVES); + win_settings_floppy_drives_update_item(h, lv1_current_sel); + break; + + case IDC_CHECKBPB: + h = GetDlgItem(hdlg, IDC_CHECKBPB); + temp_fdd_check_bpb[lv1_current_sel] = SendMessage(h, BM_GETCHECK, 0, 0); + h = GetDlgItem(hdlg, IDC_LIST_FLOPPY_DRIVES); + win_settings_floppy_drives_update_item(h, lv1_current_sel); + break; + } + ignore_change = 0; + + default: + return FALSE; + } + + return FALSE; } -int rd_ignore_change = 0; #ifdef __amd64__ static LRESULT CALLBACK @@ -4640,29 +3996,94 @@ static BOOL CALLBACK #endif win_settings_other_removable_devices_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) { - HWND h; - int old_sel = 0; - int b = 0; - uint32_t b2 = 0; - int assign = 0; + HWND h; + int old_sel = 0, b = 0, assign = 0; + uint32_t b2 = 0; + const uint8_t cd_icons[3] = { 249, 32, 0 }; + const uint8_t zip_icons[3] = { 250, 48, 0 }; - switch (message) - { - case WM_INITDIALOG: - rd_ignore_change = 1; + switch (message) { + case WM_INITDIALOG: + ignore_change = 1; - cdlv_current_sel = 0; - h = GetDlgItem(hdlg, IDC_LIST_CDROM_DRIVES); - win_settings_cdrom_drives_init_columns(h); - win_settings_cdrom_drives_image_list_init(h); - win_settings_cdrom_drives_recalc_list(h); - ListView_SetItemState(h, 0, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); - cdrom_add_locations(hdlg); + lv1_current_sel = 0; + h = GetDlgItem(hdlg, IDC_LIST_CDROM_DRIVES); + win_settings_cdrom_drives_init_columns(h); + image_list_init(h, (const uint8_t *) cd_icons); + win_settings_cdrom_drives_recalc_list(h); + ListView_SetItemState(h, 0, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); + cdrom_add_locations(hdlg); + + h = GetDlgItem(hdlg, IDC_COMBO_CD_BUS); + + switch (temp_cdrom_drives[lv1_current_sel].bus_type) { + case CDROM_BUS_DISABLED: + default: + b = 0; + break; + case CDROM_BUS_ATAPI: + b = 1; + break; + case CDROM_BUS_SCSI: + b = 2; + break; + } + + SendMessage(h, CB_SETCURSEL, b, 0); + + cdrom_recalc_location_controls(hdlg, 0); + + lv2_current_sel = 0; + h = GetDlgItem(hdlg, IDC_LIST_ZIP_DRIVES); + win_settings_zip_drives_init_columns(h); + image_list_init(h, (const uint8_t *) zip_icons); + win_settings_zip_drives_recalc_list(h); + ListView_SetItemState(h, 0, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); + zip_add_locations(hdlg); + + h = GetDlgItem(hdlg, IDC_COMBO_ZIP_BUS); + + switch (temp_zip_drives[lv2_current_sel].bus_type) { + case ZIP_BUS_DISABLED: + default: + b = 0; + break; + case ZIP_BUS_ATAPI: + b = 1; + break; + case ZIP_BUS_SCSI: + b = 2; + break; + } + + SendMessage(h, CB_SETCURSEL, b, 0); + + zip_recalc_location_controls(hdlg, 0); + + ignore_change = 0; + return TRUE; + + case WM_NOTIFY: + if (ignore_change) + return FALSE; + + if ((((LPNMHDR)lParam)->code == LVN_ITEMCHANGED) && (((LPNMHDR)lParam)->idFrom == IDC_LIST_CDROM_DRIVES)) { + old_sel = lv1_current_sel; + lv1_current_sel = get_selected_drive(hdlg, IDC_LIST_CDROM_DRIVES); + if (lv1_current_sel == old_sel) + return FALSE; + else if (lv1_current_sel == -1) { + ignore_change = 1; + lv1_current_sel = old_sel; + ListView_SetItemState(h, lv1_current_sel, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); + ignore_change = 0; + return FALSE; + } + ignore_change = 1; h = GetDlgItem(hdlg, IDC_COMBO_CD_BUS); - switch (temp_cdrom_drives[cdlv_current_sel].bus_type) - { + switch (temp_cdrom_drives[lv1_current_sel].bus_type) { case CDROM_BUS_DISABLED: default: b = 0; @@ -4678,19 +4099,24 @@ win_settings_other_removable_devices_proc(HWND hdlg, UINT message, WPARAM wParam SendMessage(h, CB_SETCURSEL, b, 0); cdrom_recalc_location_controls(hdlg, 0); - - zdlv_current_sel = 0; - h = GetDlgItem(hdlg, IDC_LIST_ZIP_DRIVES); - win_settings_zip_drives_init_columns(h); - win_settings_zip_drives_image_list_init(h); - win_settings_zip_drives_recalc_list(h); - ListView_SetItemState(h, 0, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); - zip_add_locations(hdlg); + ignore_change = 0; + } else if ((((LPNMHDR)lParam)->code == LVN_ITEMCHANGED) && (((LPNMHDR)lParam)->idFrom == IDC_LIST_ZIP_DRIVES)) { + old_sel = lv2_current_sel; + lv2_current_sel = get_selected_drive(hdlg, IDC_LIST_ZIP_DRIVES); + if (lv2_current_sel == old_sel) + return FALSE; + else if (lv2_current_sel == -1) { + ignore_change = 1; + lv2_current_sel = old_sel; + ListView_SetItemState(h, lv2_current_sel, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); + ignore_change = 0; + return FALSE; + } + ignore_change = 1; h = GetDlgItem(hdlg, IDC_COMBO_ZIP_BUS); - switch (temp_zip_drives[zdlv_current_sel].bus_type) - { + switch (temp_zip_drives[lv2_current_sel].bus_type) { case ZIP_BUS_DISABLED: default: b = 0; @@ -4707,425 +4133,200 @@ win_settings_other_removable_devices_proc(HWND hdlg, UINT message, WPARAM wParam zip_recalc_location_controls(hdlg, 0); - h = GetDlgItem(hdlg, IDC_CHECK250); - SendMessage(h, BM_SETCHECK, temp_zip_drives[zdlv_current_sel].is_250, 0); + ignore_change = 0; + } + break; - rd_ignore_change = 0; - return TRUE; - - case WM_NOTIFY: - if (rd_ignore_change) - { - return FALSE; - } - - if ((((LPNMHDR)lParam)->code == LVN_ITEMCHANGED) && (((LPNMHDR)lParam)->idFrom == IDC_LIST_CDROM_DRIVES)) - { - old_sel = cdlv_current_sel; - cdlv_current_sel = get_selected_cdrom_drive(hdlg); - if (cdlv_current_sel == old_sel) - { - return FALSE; - } - else if (cdlv_current_sel == -1) - { - rd_ignore_change = 1; - cdlv_current_sel = old_sel; - ListView_SetItemState(h, cdlv_current_sel, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); - rd_ignore_change = 0; - return FALSE; - } - rd_ignore_change = 1; - - h = GetDlgItem(hdlg, IDC_COMBO_CD_BUS); - - switch (temp_cdrom_drives[cdlv_current_sel].bus_type) - { - case CDROM_BUS_DISABLED: - default: - b = 0; - break; - case CDROM_BUS_ATAPI: - b = 1; - break; - case CDROM_BUS_SCSI: - b = 2; - break; - } - - SendMessage(h, CB_SETCURSEL, b, 0); - - cdrom_recalc_location_controls(hdlg, 0); - rd_ignore_change = 0; - } - else if ((((LPNMHDR)lParam)->code == LVN_ITEMCHANGED) && (((LPNMHDR)lParam)->idFrom == IDC_LIST_ZIP_DRIVES)) - { - old_sel = zdlv_current_sel; - zdlv_current_sel = get_selected_zip_drive(hdlg); - if (zdlv_current_sel == old_sel) - { - return FALSE; - } - else if (zdlv_current_sel == -1) - { - rd_ignore_change = 1; - zdlv_current_sel = old_sel; - ListView_SetItemState(h, zdlv_current_sel, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); - rd_ignore_change = 0; - return FALSE; - } - rd_ignore_change = 1; - - h = GetDlgItem(hdlg, IDC_COMBO_ZIP_BUS); - - switch (temp_zip_drives[zdlv_current_sel].bus_type) - { - case ZIP_BUS_DISABLED: - default: - b = 0; - break; - case ZIP_BUS_ATAPI: - b = 1; - break; - case ZIP_BUS_SCSI: - b = 2; - break; - } - - SendMessage(h, CB_SETCURSEL, b, 0); - - zip_recalc_location_controls(hdlg, 0); - - h = GetDlgItem(hdlg, IDC_CHECK250); - SendMessage(h, BM_SETCHECK, temp_zip_drives[zdlv_current_sel].is_250, 0); - - rd_ignore_change = 0; - } - break; - - case WM_COMMAND: - switch (LOWORD(wParam)) - { - case IDC_COMBO_CD_BUS: - if (rd_ignore_change) - { - return FALSE; - } - - rd_ignore_change = 1; - h = GetDlgItem(hdlg, IDC_COMBO_CD_BUS); - b = SendMessage(h, CB_GETCURSEL, 0, 0); - switch (b) - { - case 0: - b2 = CDROM_BUS_DISABLED; - break; - case 1: - b2 = CDROM_BUS_ATAPI; - break; - case 2: - b2 = CDROM_BUS_SCSI; - break; - } - if (b2 == temp_cdrom_drives[cdlv_current_sel].bus_type) - { - goto cdrom_bus_skip; - } - cdrom_untrack(cdlv_current_sel); - assign = (temp_cdrom_drives[cdlv_current_sel].bus_type == b2) ? 0 : 1; - if (temp_cdrom_drives[cdlv_current_sel].bus_type == CDROM_BUS_DISABLED) - temp_cdrom_drives[cdlv_current_sel].speed = 8; - temp_cdrom_drives[cdlv_current_sel].bus_type = b2; - cdrom_recalc_location_controls(hdlg, assign); - cdrom_track(cdlv_current_sel); - h = GetDlgItem(hdlg, IDC_LIST_CDROM_DRIVES); - win_settings_cdrom_drives_update_item(h, cdlv_current_sel); -cdrom_bus_skip: - rd_ignore_change = 0; - return FALSE; - - case IDC_COMBO_CD_ID: - if (rd_ignore_change) - { - return FALSE; - } - - rd_ignore_change = 1; - h = GetDlgItem(hdlg, IDC_COMBO_CD_ID); - cdrom_untrack(cdlv_current_sel); - temp_cdrom_drives[cdlv_current_sel].scsi_device_id = SendMessage(h, CB_GETCURSEL, 0, 0); - cdrom_track(cdlv_current_sel); - h = GetDlgItem(hdlg, IDC_LIST_CDROM_DRIVES); - win_settings_cdrom_drives_update_item(h, cdlv_current_sel); - rd_ignore_change = 0; - return FALSE; - - case IDC_COMBO_CD_LUN: - if (rd_ignore_change) - { - return FALSE; - } - - rd_ignore_change = 1; - h = GetDlgItem(hdlg, IDC_COMBO_CD_LUN); - cdrom_untrack(cdlv_current_sel); - temp_cdrom_drives[cdlv_current_sel].scsi_device_lun = SendMessage(h, CB_GETCURSEL, 0, 0); - cdrom_track(cdlv_current_sel); - h = GetDlgItem(hdlg, IDC_LIST_CDROM_DRIVES); - win_settings_cdrom_drives_update_item(h, cdlv_current_sel); - rd_ignore_change = 0; - return FALSE; - - case IDC_COMBO_CD_CHANNEL_IDE: - if (rd_ignore_change) - { - return FALSE; - } - - rd_ignore_change = 1; - h = GetDlgItem(hdlg, IDC_COMBO_CD_CHANNEL_IDE); - cdrom_untrack(cdlv_current_sel); - temp_cdrom_drives[cdlv_current_sel].ide_channel = SendMessage(h, CB_GETCURSEL, 0, 0); - cdrom_track(cdlv_current_sel); - h = GetDlgItem(hdlg, IDC_LIST_CDROM_DRIVES); - win_settings_cdrom_drives_update_item(h, cdlv_current_sel); - rd_ignore_change = 0; - return FALSE; - - case IDC_COMBO_CD_SPEED: - if (rd_ignore_change) - { - return FALSE; - } - - rd_ignore_change = 1; - h = GetDlgItem(hdlg, IDC_COMBO_CD_SPEED); - temp_cdrom_drives[cdlv_current_sel].speed = SendMessage(h, CB_GETCURSEL, 0, 0) + 1; - h = GetDlgItem(hdlg, IDC_LIST_CDROM_DRIVES); - win_settings_cdrom_drives_update_item(h, cdlv_current_sel); - rd_ignore_change = 0; - return FALSE; - - case IDC_COMBO_ZIP_BUS: - if (rd_ignore_change) - { - return FALSE; - } - - rd_ignore_change = 1; - h = GetDlgItem(hdlg, IDC_COMBO_ZIP_BUS); - b = SendMessage(h, CB_GETCURSEL, 0, 0); - switch (b) - { - case 0: - b2 = ZIP_BUS_DISABLED; - break; - case 1: - b2 = ZIP_BUS_ATAPI; - break; - case 2: - b2 = ZIP_BUS_SCSI; - break; - } - if (b2 == temp_zip_drives[zdlv_current_sel].bus_type) - { - goto zip_bus_skip; - } - zip_untrack(zdlv_current_sel); - assign = (temp_zip_drives[zdlv_current_sel].bus_type == b2) ? 0 : 1; - temp_zip_drives[zdlv_current_sel].bus_type = b2; - zip_recalc_location_controls(hdlg, assign); - zip_track(zdlv_current_sel); - h = GetDlgItem(hdlg, IDC_LIST_ZIP_DRIVES); - win_settings_zip_drives_update_item(h, zdlv_current_sel); -zip_bus_skip: - rd_ignore_change = 0; - return FALSE; - - case IDC_COMBO_ZIP_ID: - if (rd_ignore_change) - { - return FALSE; - } - - rd_ignore_change = 1; - h = GetDlgItem(hdlg, IDC_COMBO_ZIP_ID); - zip_untrack(zdlv_current_sel); - temp_zip_drives[zdlv_current_sel].scsi_device_id = SendMessage(h, CB_GETCURSEL, 0, 0); - zip_track(zdlv_current_sel); - h = GetDlgItem(hdlg, IDC_LIST_ZIP_DRIVES); - win_settings_zip_drives_update_item(h, zdlv_current_sel); - rd_ignore_change = 0; - return FALSE; - - case IDC_COMBO_ZIP_LUN: - if (rd_ignore_change) - { - return FALSE; - } - - rd_ignore_change = 1; - h = GetDlgItem(hdlg, IDC_COMBO_ZIP_LUN); - zip_untrack(zdlv_current_sel); - temp_zip_drives[zdlv_current_sel].scsi_device_lun = SendMessage(h, CB_GETCURSEL, 0, 0); - zip_track(zdlv_current_sel); - h = GetDlgItem(hdlg, IDC_LIST_ZIP_DRIVES); - win_settings_zip_drives_update_item(h, zdlv_current_sel); - rd_ignore_change = 0; - return FALSE; - - case IDC_COMBO_ZIP_CHANNEL_IDE: - if (rd_ignore_change) - { - return FALSE; - } - - rd_ignore_change = 1; - h = GetDlgItem(hdlg, IDC_COMBO_ZIP_CHANNEL_IDE); - zip_untrack(zdlv_current_sel); - temp_zip_drives[zdlv_current_sel].ide_channel = SendMessage(h, CB_GETCURSEL, 0, 0); - zip_track(zdlv_current_sel); - h = GetDlgItem(hdlg, IDC_LIST_ZIP_DRIVES); - win_settings_zip_drives_update_item(h, zdlv_current_sel); - rd_ignore_change = 0; - return FALSE; - - case IDC_CHECK250: - if (rd_ignore_change) - { - return FALSE; - } - - rd_ignore_change = 1; - h = GetDlgItem(hdlg, IDC_CHECK250); - temp_zip_drives[zdlv_current_sel].is_250 = SendMessage(h, BM_GETCHECK, 0, 0); - h = GetDlgItem(hdlg, IDC_LIST_ZIP_DRIVES); - win_settings_zip_drives_update_item(h, zdlv_current_sel); - rd_ignore_change = 0; - return FALSE; - } - - default: + case WM_COMMAND: + if (ignore_change) return FALSE; - } - return FALSE; + ignore_change = 1; + switch (LOWORD(wParam)) { + case IDC_COMBO_CD_BUS: + h = GetDlgItem(hdlg, IDC_COMBO_CD_BUS); + b = SendMessage(h, CB_GETCURSEL, 0, 0); + switch (b) { + case 0: + b2 = CDROM_BUS_DISABLED; + break; + case 1: + b2 = CDROM_BUS_ATAPI; + break; + case 2: + b2 = CDROM_BUS_SCSI; + break; + } + if (b2 == temp_cdrom_drives[lv1_current_sel].bus_type) + break; + cdrom_untrack(lv1_current_sel); + assign = (temp_cdrom_drives[lv1_current_sel].bus_type == b2) ? 0 : 1; + if (temp_cdrom_drives[lv1_current_sel].bus_type == CDROM_BUS_DISABLED) + temp_cdrom_drives[lv1_current_sel].speed = 8; + temp_cdrom_drives[lv1_current_sel].bus_type = b2; + cdrom_recalc_location_controls(hdlg, assign); + cdrom_track(lv1_current_sel); + h = GetDlgItem(hdlg, IDC_LIST_CDROM_DRIVES); + win_settings_cdrom_drives_update_item(h, lv1_current_sel); + break; + + case IDC_COMBO_CD_ID: + h = GetDlgItem(hdlg, IDC_COMBO_CD_ID); + cdrom_untrack(lv1_current_sel); + temp_cdrom_drives[lv1_current_sel].scsi_device_id = SendMessage(h, CB_GETCURSEL, 0, 0); + cdrom_track(lv1_current_sel); + h = GetDlgItem(hdlg, IDC_LIST_CDROM_DRIVES); + win_settings_cdrom_drives_update_item(h, lv1_current_sel); + break; + + case IDC_COMBO_CD_CHANNEL_IDE: + h = GetDlgItem(hdlg, IDC_COMBO_CD_CHANNEL_IDE); + cdrom_untrack(lv1_current_sel); + temp_cdrom_drives[lv1_current_sel].ide_channel = SendMessage(h, CB_GETCURSEL, 0, 0); + cdrom_track(lv1_current_sel); + h = GetDlgItem(hdlg, IDC_LIST_CDROM_DRIVES); + win_settings_cdrom_drives_update_item(h, lv1_current_sel); + break; + + case IDC_COMBO_CD_SPEED: + h = GetDlgItem(hdlg, IDC_COMBO_CD_SPEED); + temp_cdrom_drives[lv1_current_sel].speed = SendMessage(h, CB_GETCURSEL, 0, 0) + 1; + h = GetDlgItem(hdlg, IDC_LIST_CDROM_DRIVES); + win_settings_cdrom_drives_update_item(h, lv1_current_sel); + break; + + case IDC_COMBO_ZIP_BUS: + h = GetDlgItem(hdlg, IDC_COMBO_ZIP_BUS); + b = SendMessage(h, CB_GETCURSEL, 0, 0); + switch (b) { + case 0: + b2 = ZIP_BUS_DISABLED; + break; + case 1: + b2 = ZIP_BUS_ATAPI; + break; + case 2: + b2 = ZIP_BUS_SCSI; + break; + } + if (b2 == temp_zip_drives[lv2_current_sel].bus_type) + break; + zip_untrack(lv2_current_sel); + assign = (temp_zip_drives[lv2_current_sel].bus_type == b2) ? 0 : 1; + temp_zip_drives[lv2_current_sel].bus_type = b2; + zip_recalc_location_controls(hdlg, assign); + zip_track(lv2_current_sel); + h = GetDlgItem(hdlg, IDC_LIST_ZIP_DRIVES); + win_settings_zip_drives_update_item(h, lv2_current_sel); + break; + + case IDC_COMBO_ZIP_ID: + h = GetDlgItem(hdlg, IDC_COMBO_ZIP_ID); + zip_untrack(lv2_current_sel); + temp_zip_drives[lv2_current_sel].scsi_device_id = SendMessage(h, CB_GETCURSEL, 0, 0); + zip_track(lv2_current_sel); + h = GetDlgItem(hdlg, IDC_LIST_ZIP_DRIVES); + win_settings_zip_drives_update_item(h, lv2_current_sel); + break; + + case IDC_COMBO_ZIP_CHANNEL_IDE: + h = GetDlgItem(hdlg, IDC_COMBO_ZIP_CHANNEL_IDE); + zip_untrack(lv2_current_sel); + temp_zip_drives[lv2_current_sel].ide_channel = SendMessage(h, CB_GETCURSEL, 0, 0); + zip_track(lv2_current_sel); + h = GetDlgItem(hdlg, IDC_LIST_ZIP_DRIVES); + win_settings_zip_drives_update_item(h, lv2_current_sel); + break; + + case IDC_CHECK250: + h = GetDlgItem(hdlg, IDC_CHECK250); + temp_zip_drives[lv2_current_sel].is_250 = SendMessage(h, BM_GETCHECK, 0, 0); + h = GetDlgItem(hdlg, IDC_LIST_ZIP_DRIVES); + win_settings_zip_drives_update_item(h, lv2_current_sel); + break; + } + ignore_change = 0; + + default: + return FALSE; + } + + return FALSE; } -#define SETTINGS_PAGE_MACHINE 0 -#define SETTINGS_PAGE_VIDEO 1 -#define SETTINGS_PAGE_INPUT 2 -#define SETTINGS_PAGE_SOUND 3 -#define SETTINGS_PAGE_NETWORK 4 -#define SETTINGS_PAGE_PORTS 5 -#define SETTINGS_PAGE_PERIPHERALS 6 -#define SETTINGS_PAGE_HARD_DISKS 7 -#define SETTINGS_PAGE_FLOPPY_DRIVES 8 -#define SETTINGS_PAGE_OTHER_REMOVABLE_DEVICES 9 void win_settings_show_child(HWND hwndParent, DWORD child_id) { - if (child_id == displayed_category) - { + if (child_id == displayed_category) + return; + else + displayed_category = child_id; + + SendMessage(hwndChildDialog, WM_SAVESETTINGS, 0, 0); + + DestroyWindow(hwndChildDialog); + + switch(child_id) { + case SETTINGS_PAGE_MACHINE: + hwndChildDialog = CreateDialog(hinstance, (LPCWSTR)DLG_CFG_MACHINE, hwndParent, win_settings_machine_proc); + break; + case SETTINGS_PAGE_VIDEO: + hwndChildDialog = CreateDialog(hinstance, (LPCWSTR)DLG_CFG_VIDEO, hwndParent, win_settings_video_proc); + break; + case SETTINGS_PAGE_INPUT: + hwndChildDialog = CreateDialog(hinstance, (LPCWSTR)DLG_CFG_INPUT, hwndParent, win_settings_input_proc); + break; + case SETTINGS_PAGE_SOUND: + hwndChildDialog = CreateDialog(hinstance, (LPCWSTR)DLG_CFG_SOUND, hwndParent, win_settings_sound_proc); + break; + case SETTINGS_PAGE_NETWORK: + hwndChildDialog = CreateDialog(hinstance, (LPCWSTR)DLG_CFG_NETWORK, hwndParent, win_settings_network_proc); + break; + case SETTINGS_PAGE_PORTS: + hwndChildDialog = CreateDialog(hinstance, (LPCWSTR)DLG_CFG_PORTS, hwndParent, win_settings_ports_proc); + break; + case SETTINGS_PAGE_PERIPHERALS: + hwndChildDialog = CreateDialog(hinstance, (LPCWSTR)DLG_CFG_PERIPHERALS, hwndParent, win_settings_peripherals_proc); + break; + case SETTINGS_PAGE_HARD_DISKS: + hwndChildDialog = CreateDialog(hinstance, (LPCWSTR)DLG_CFG_HARD_DISKS, hwndParent, win_settings_hard_disks_proc); + break; + case SETTINGS_PAGE_FLOPPY_DRIVES: + hwndChildDialog = CreateDialog(hinstance, (LPCWSTR)DLG_CFG_FLOPPY_DRIVES, hwndParent, win_settings_floppy_drives_proc); + break; + case SETTINGS_PAGE_OTHER_REMOVABLE_DEVICES: + hwndChildDialog = CreateDialog(hinstance, (LPCWSTR)DLG_CFG_OTHER_REMOVABLE_DEVICES, hwndParent, win_settings_other_removable_devices_proc); + break; + default: + fatal("Invalid child dialog ID\n"); return; - } - else - { - displayed_category = child_id; - } + } - SendMessage(hwndChildDialog, WM_SAVESETTINGS, 0, 0); - - DestroyWindow(hwndChildDialog); - - switch(child_id) - { - case SETTINGS_PAGE_MACHINE: - hwndChildDialog = CreateDialog(hinstance, (LPCWSTR)DLG_CFG_MACHINE, hwndParent, win_settings_machine_proc); - break; - case SETTINGS_PAGE_VIDEO: - hwndChildDialog = CreateDialog(hinstance, (LPCWSTR)DLG_CFG_VIDEO, hwndParent, win_settings_video_proc); - break; - case SETTINGS_PAGE_INPUT: - hwndChildDialog = CreateDialog(hinstance, (LPCWSTR)DLG_CFG_INPUT, hwndParent, win_settings_input_proc); - break; - case SETTINGS_PAGE_SOUND: - hwndChildDialog = CreateDialog(hinstance, (LPCWSTR)DLG_CFG_SOUND, hwndParent, win_settings_sound_proc); - break; - case SETTINGS_PAGE_NETWORK: - hwndChildDialog = CreateDialog(hinstance, (LPCWSTR)DLG_CFG_NETWORK, hwndParent, win_settings_network_proc); - break; - case SETTINGS_PAGE_PORTS: - hwndChildDialog = CreateDialog(hinstance, (LPCWSTR)DLG_CFG_PORTS, hwndParent, win_settings_ports_proc); - break; - case SETTINGS_PAGE_PERIPHERALS: - hwndChildDialog = CreateDialog(hinstance, (LPCWSTR)DLG_CFG_PERIPHERALS, hwndParent, win_settings_peripherals_proc); - break; - case SETTINGS_PAGE_HARD_DISKS: - hwndChildDialog = CreateDialog(hinstance, (LPCWSTR)DLG_CFG_HARD_DISKS, hwndParent, win_settings_hard_disks_proc); - break; - case SETTINGS_PAGE_FLOPPY_DRIVES: - hwndChildDialog = CreateDialog(hinstance, (LPCWSTR)DLG_CFG_FLOPPY_DRIVES, hwndParent, win_settings_floppy_drives_proc); - break; - case SETTINGS_PAGE_OTHER_REMOVABLE_DEVICES: - hwndChildDialog = CreateDialog(hinstance, (LPCWSTR)DLG_CFG_OTHER_REMOVABLE_DEVICES, hwndParent, win_settings_other_removable_devices_proc); - break; - default: - fatal("Invalid child dialog ID\n"); - return; - } - - ShowWindow(hwndChildDialog, SW_SHOWNORMAL); + ShowWindow(hwndChildDialog, SW_SHOWNORMAL); } -static BOOL win_settings_main_image_list_init(HWND hwndList) + +static BOOL +win_settings_main_insert_categories(HWND hwndList) { - HICON hiconItem; - HIMAGELIST hSmall; + LVITEM lvI; + int i = 0; - int i = 0; + lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; + lvI.stateMask = lvI.iSubItem = lvI.state = 0; - hSmall = ImageList_Create(GetSystemMetrics(SM_CXSMICON), - GetSystemMetrics(SM_CYSMICON), - ILC_MASK | ILC_COLOR32, 1, 1); + for (i = 0; i < 10; i++) { + lvI.pszText = plat_get_string(IDS_2065+i); + lvI.iItem = i; + lvI.iImage = i; - for (i = 0; i < 10; i++) - { - if (i == 4) - hiconItem = LoadIcon(hinstance, (LPCWSTR) 208); - else if (i == 7) - hiconItem = LoadIcon(hinstance, (LPCWSTR) 192); - else - hiconItem = LoadIcon(hinstance, (LPCWSTR) (256 + (uintptr_t) i)); - ImageList_AddIcon(hSmall, hiconItem); - DestroyIcon(hiconItem); - } + if (ListView_InsertItem(hwndList, &lvI) == -1) + return FALSE; + } - ListView_SetImageList(hwndList, hSmall, LVSIL_SMALL); - - return TRUE; + return TRUE; } -static BOOL win_settings_main_insert_categories(HWND hwndList) -{ - LVITEM lvI; - int i = 0; - - lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; - lvI.stateMask = lvI.iSubItem = lvI.state = 0; - - for (i = 0; i < 10; i++) - { - lvI.pszText = plat_get_string(IDS_2065+i); - lvI.iItem = i; - lvI.iImage = i; - - if (ListView_InsertItem(hwndList, &lvI) == -1) - return FALSE; - } - - return TRUE; -} #ifdef __amd64__ static LRESULT CALLBACK @@ -5134,85 +4335,67 @@ static BOOL CALLBACK #endif win_settings_main_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) { - HWND h; - int category; - int i = 0; - int j = 0; + HWND h; + int category, i = 0, j = 0; + const uint8_t cat_icons[11] = { 240, 241, 242, 243, 80, 244, 245, 64, 246, 247, 0 }; - hwndParentDialog = hdlg; + hwndParentDialog = hdlg; - switch (message) - { - case WM_INITDIALOG: - plat_pause(1); - win_settings_init(); - displayed_category = -1; - h = GetDlgItem(hdlg, IDC_SETTINGSCATLIST); - win_settings_main_image_list_init(h); - win_settings_main_insert_categories(h); - ListView_SetItemState(h, 0, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); -/* Leave this commented out until we do localization. */ -#if 0 - h = GetDlgItem(hdlg, IDC_COMBO_LANG); /* This is currently disabled, I am going to add localization options in the future. */ - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - h = GetDlgItem(hdlg, IDS_LANG_ENUS); /*was:2047 !*/ - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); -#endif - return TRUE; - case WM_NOTIFY: - if ((((LPNMHDR)lParam)->code == LVN_ITEMCHANGED) && (((LPNMHDR)lParam)->idFrom == IDC_SETTINGSCATLIST)) - { - category = -1; - for (i = 0; i < 10; i++) - { - h = GetDlgItem(hdlg, IDC_SETTINGSCATLIST); - j = ListView_GetItemState(h, i, LVIS_SELECTED); - if (j) - category = i; - } - if (category != -1) - win_settings_show_child(hdlg, category); + switch (message) { + case WM_INITDIALOG: + plat_pause(1); + win_settings_init(); + displayed_category = -1; + h = GetDlgItem(hdlg, IDC_SETTINGSCATLIST); + image_list_init(h, (const uint8_t *) cat_icons); + win_settings_main_insert_categories(h); + ListView_SetItemState(h, 0, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); + return TRUE; + case WM_NOTIFY: + if ((((LPNMHDR)lParam)->code == LVN_ITEMCHANGED) && (((LPNMHDR)lParam)->idFrom == IDC_SETTINGSCATLIST)) { + category = -1; + for (i = 0; i < 10; i++) { + h = GetDlgItem(hdlg, IDC_SETTINGSCATLIST); + j = ListView_GetItemState(h, i, LVIS_SELECTED); + if (j) + category = i; } - break; - case WM_COMMAND: - switch (LOWORD(wParam)) - { - case IDOK: - SendMessage(hwndChildDialog, WM_SAVESETTINGS, 0, 0); - i = settings_msgbox_reset(); - if (i > 0) - { - if (i == 2) - { - win_settings_save(); - } + if (category != -1) + win_settings_show_child(hdlg, category); + } + break; + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDOK: + SendMessage(hwndChildDialog, WM_SAVESETTINGS, 0, 0); + i = settings_msgbox_reset(); + if (i > 0) { + if (i == 2) + win_settings_save(); - DestroyWindow(hwndChildDialog); - EndDialog(hdlg, 0); - plat_pause(0); - return TRUE; - } - else - { - return FALSE; - } - case IDCANCEL: DestroyWindow(hwndChildDialog); - EndDialog(hdlg, 0); - plat_pause(0); - return TRUE; - } - break; - default: - return FALSE; - } + EndDialog(hdlg, 0); + plat_pause(0); + return TRUE; + } else + return FALSE; + case IDCANCEL: + DestroyWindow(hwndChildDialog); + EndDialog(hdlg, 0); + plat_pause(0); + return TRUE; + } + break; + default: + return FALSE; + } - return FALSE; + return FALSE; } -void win_settings_open(HWND hwnd) + +void +win_settings_open(HWND hwnd) { - DialogBox(hinstance, (LPCWSTR)DLG_CONFIG, hwnd, win_settings_main_proc); + DialogBox(hinstance, (LPCWSTR)DLG_CONFIG, hwnd, win_settings_main_proc); } diff --git a/src/win/win_stbar.c b/src/win/win_stbar.c index bfca21c5d..750b8837d 100644 --- a/src/win/win_stbar.c +++ b/src/win/win_stbar.c @@ -8,7 +8,7 @@ * * Implement the application's Status Bar. * - * Version: @(#)win_stbar.c 1.0.17 2018/03/26 + * Version: @(#)win_stbar.c 1.0.18 2018/05/25 * * Authors: Miran Grca, * Fred N. van Kempen, @@ -35,10 +35,10 @@ #include "../machine/machine.h" #include "../disk/hdd.h" #include "../disk/hdc.h" -#include "../disk/zip.h" #include "../floppy/fdd.h" #include "../scsi/scsi.h" #include "../cdrom/cdrom.h" +#include "../disk/zip.h" #include "../cdrom/cdrom_image.h" #include "../cdrom/cdrom_null.h" #include "../scsi/scsi_disk.h" @@ -64,7 +64,7 @@ static HMENU menuSBAR; static WCHAR **sbTips; static int *iStatusWidths; static int *sb_part_meanings; -static int *sb_part_icons; +static uint8_t *sb_part_icons; static int sb_parts = 0; static int sb_ready = 0; static uint8_t sb_map[256]; @@ -74,7 +74,7 @@ static uint8_t sb_map[256]; intptr_t fdd_type_to_icon(int type) { - int ret = 512; + int ret = 248; switch(type) { case 0: @@ -82,12 +82,12 @@ fdd_type_to_icon(int type) case 1: case 2: case 3: case 4: case 5: case 6: - ret = 128; + ret = 16; break; case 7: case 8: case 9: case 10: case 11: case 12: case 13: - ret = 144; + ret = 24; break; default: @@ -118,18 +118,18 @@ static void StatusBarCreateFloppySubmenu(HMENU m, int id) { AppendMenu(m, MF_STRING, IDM_FLOPPY_IMAGE_NEW | id, - plat_get_string(IDS_2161)); + plat_get_string(IDS_2096)); AppendMenu(m, MF_SEPARATOR, 0, 0); AppendMenu(m, MF_STRING, IDM_FLOPPY_IMAGE_EXISTING | id, - plat_get_string(IDS_2162)); + plat_get_string(IDS_2097)); AppendMenu(m, MF_STRING, IDM_FLOPPY_IMAGE_EXISTING_WP | id, - plat_get_string(IDS_2163)); + plat_get_string(IDS_2098)); AppendMenu(m, MF_SEPARATOR, 0, 0); AppendMenu(m, MF_STRING, IDM_FLOPPY_EXPORT_TO_86F | id, - plat_get_string(IDS_2172)); + plat_get_string(IDS_2080)); AppendMenu(m, MF_SEPARATOR, 0, 0); AppendMenu(m, MF_STRING, IDM_FLOPPY_EJECT | id, - plat_get_string(IDS_2164)); + plat_get_string(IDS_2093)); if (floppyfns[id][0] == 0x0000) { EnableMenuItem(m, IDM_FLOPPY_EJECT | id, MF_BYCOMMAND | MF_GRAYED); @@ -142,15 +142,15 @@ static void StatusBarCreateCdromSubmenu(HMENU m, int id) { AppendMenu(m, MF_STRING, IDM_CDROM_MUTE | id, - plat_get_string(IDS_2165)); + plat_get_string(IDS_2092)); AppendMenu(m, MF_SEPARATOR, 0, 0); AppendMenu(m, MF_STRING, IDM_CDROM_EMPTY | id, - plat_get_string(IDS_2166)); + plat_get_string(IDS_2091)); AppendMenu(m, MF_STRING, IDM_CDROM_RELOAD | id, - plat_get_string(IDS_2167)); + plat_get_string(IDS_2090)); AppendMenu(m, MF_SEPARATOR, 0, 0); AppendMenu(m, MF_STRING, IDM_CDROM_IMAGE | id, - plat_get_string(IDS_2168)); + plat_get_string(IDS_2089)); if (! cdrom_drives[id].sound_on) CheckMenuItem(m, IDM_CDROM_MUTE | id, MF_CHECKED); @@ -168,17 +168,17 @@ static void StatusBarCreateZIPSubmenu(HMENU m, int id) { AppendMenu(m, MF_STRING, IDM_ZIP_IMAGE_NEW | id, - plat_get_string(IDS_2161)); + plat_get_string(IDS_2096)); AppendMenu(m, MF_SEPARATOR, 0, 0); AppendMenu(m, MF_STRING, IDM_ZIP_IMAGE_EXISTING | id, - plat_get_string(IDS_2162)); + plat_get_string(IDS_2097)); AppendMenu(m, MF_STRING, IDM_ZIP_IMAGE_EXISTING_WP | id, - plat_get_string(IDS_2163)); + plat_get_string(IDS_2098)); AppendMenu(m, MF_SEPARATOR, 0, 0); AppendMenu(m, MF_STRING, IDM_ZIP_EJECT | id, - plat_get_string(IDS_2164)); + plat_get_string(IDS_2093)); AppendMenu(m, MF_STRING, IDM_ZIP_RELOAD | id, - plat_get_string(IDS_2167)); + plat_get_string(IDS_2090)); if (zip_drives[id].image_path[0] == 0x0000) { EnableMenuItem(m, IDM_ZIP_EJECT | id, MF_BYCOMMAND | MF_GRAYED); @@ -206,7 +206,7 @@ ui_sb_update_icon(int tag, int active) found = sb_map[tag]; if (found != 0xff) { sb_part_icons[found] &= ~1; - sb_part_icons[found] |= active; + sb_part_icons[found] |= (uint8_t) active; SendMessage(hwndSBAR, SB_SETICON, found, (LPARAM)hIcon[sb_part_icons[found]]); @@ -225,8 +225,8 @@ ui_sb_update_icon_state(int tag, int state) found = sb_map[tag]; if (found != 0xff) { - sb_part_icons[found] &= ~256; - sb_part_icons[found] |= (state ? 256 : 0); + sb_part_icons[found] &= ~128; + sb_part_icons[found] |= (state ? 128 : 0); SendMessage(hwndSBAR, SB_SETICON, found, (LPARAM)hIcon[sb_part_icons[found]]); @@ -245,10 +245,10 @@ StatusBarCreateFloppyTip(int part) mbstowcs(wtext, fdd_getname(fdd_get_type(drive)), strlen(fdd_getname(fdd_get_type(drive))) + 1); if (wcslen(floppyfns[drive]) == 0) { - _swprintf(tempTip, plat_get_string(IDS_2158), + _swprintf(tempTip, plat_get_string(IDS_2117), drive+1, wtext, plat_get_string(IDS_2057)); } else { - _swprintf(tempTip, plat_get_string(IDS_2158), + _swprintf(tempTip, plat_get_string(IDS_2117), drive+1, wtext, floppyfns[drive]); } @@ -305,10 +305,10 @@ StatusBarCreateZIPTip(int part) int type = zip_drives[drive].is_250 ? 250 : 100; if (wcslen(zip_drives[drive].image_path) == 0) { - _swprintf(tempTip, plat_get_string(IDS_2177), + _swprintf(tempTip, plat_get_string(IDS_2054), type, drive+1, szText, plat_get_string(IDS_2057)); } else { - _swprintf(tempTip, plat_get_string(IDS_2177), + _swprintf(tempTip, plat_get_string(IDS_2054), type, drive+1, szText, zip_drives[drive].image_path); } @@ -561,8 +561,8 @@ ui_sb_update_panes(void) memset(iStatusWidths, 0, sb_parts * sizeof(int)); sb_part_meanings = (int *)malloc(sb_parts * sizeof(int)); memset(sb_part_meanings, 0, sb_parts * sizeof(int)); - sb_part_icons = (int *)malloc(sb_parts * sizeof(int)); - memset(sb_part_icons, 0, sb_parts * sizeof(int)); + sb_part_icons = (uint8_t *)malloc(sb_parts * sizeof(uint8_t)); + memset(sb_part_icons, 0, sb_parts * sizeof(uint8_t)); sb_menu_handles = (HMENU *)malloc(sb_parts * sizeof(HMENU)); memset(sb_menu_handles, 0, sb_parts * sizeof(HMENU)); sbTips = (WCHAR **)malloc(sb_parts * sizeof(WCHAR *)); @@ -670,21 +670,21 @@ ui_sb_update_panes(void) for (i=0; i * Miran Grca, @@ -48,7 +48,7 @@ HWND hwndMain, /* application main window */ hwndRender; /* machine render window */ HMENU menuMain; /* application main menu */ -HICON hIcon[512]; /* icon data loaded from resources */ +HICON hIcon[256]; /* icon data loaded from resources */ RECT oldclip; /* mouse rect */ int infocus = 1; int rctrl_is_lalt = 0; @@ -59,7 +59,6 @@ WCHAR wopenfilestring[260]; /* Local data. */ static wchar_t wTitle[512]; -static RAWINPUTDEVICE device; static HHOOK hKeyboardHook; static int hook_enabled = 0; static int save_window_pos = 0; @@ -149,9 +148,7 @@ ResetAllMenus(void) CheckMenuItem(menuMain, IDM_VID_RESIZE, MF_UNCHECKED); CheckMenuItem(menuMain, IDM_VID_DDRAW+0, MF_UNCHECKED); CheckMenuItem(menuMain, IDM_VID_DDRAW+1, MF_UNCHECKED); -#ifdef USE_VNC CheckMenuItem(menuMain, IDM_VID_DDRAW+2, MF_UNCHECKED); -#endif #ifdef USE_VNC CheckMenuItem(menuMain, IDM_VID_DDRAW+3, MF_UNCHECKED); #endif @@ -382,11 +379,9 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) case IDM_VID_DDRAW: case IDM_VID_D3D: + case IDM_VID_SDL: #ifdef USE_VNC case IDM_VID_VNC: -#endif -#ifdef USE_RDP - case IDM_VID_RDP: #endif CheckMenuItem(hmenu, IDM_VID_DDRAW+vid_api, MF_UNCHECKED); plat_setvid(LOWORD(wParam) - IDM_VID_DDRAW); @@ -529,63 +524,9 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) svga_dump_vram(); break; #endif - -#if 0 - case IDM_CONFIG_LOAD: - plat_pause(1); - if (!file_dlg_st(hwnd, IDS_2160, "", 0) && - (ui_msgbox(MBX_QUESTION, (wchar_t *)IDS_2051) == IDYES)) { - pc_reload(wopenfilestring); - ResetAllMenus(); - } - plat_pause(0); - break; - - case IDM_CONFIG_SAVE: - plat_pause(1); - if (! file_dlg_st(hwnd, IDS_2160, "", 1)) { - config_write(wopenfilestring); - } - plat_pause(0); - break; -#endif } return(0); - case WM_INPUT: - keyboard_handle(lParam, infocus); - break; - - case WM_SETFOCUS: - infocus = 1; - if (! hook_enabled) { - hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, - LowLevelKeyboardProc, - GetModuleHandle(NULL), - 0); - hook_enabled = 1; - } - break; - - case WM_KILLFOCUS: - infocus = 0; - plat_mouse_capture(0); - if (hook_enabled) { - UnhookWindowsHookEx(hKeyboardHook); - hook_enabled = 0; - } - break; - - case WM_LBUTTONUP: - if (! video_fullscreen) - plat_mouse_capture(1); - break; - - case WM_MBUTTONUP: - if (mouse_get_buttons() < 3) - plat_mouse_capture(0); - break; - case WM_ENTERMENULOOP: break; @@ -703,6 +644,26 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) default: return(DefWindowProc(hwnd, message, wParam, lParam)); + + case WM_SETFOCUS: + infocus = 1; + if (! hook_enabled) { + hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, + LowLevelKeyboardProc, + GetModuleHandle(NULL), + 0); + hook_enabled = 1; + } + break; + + case WM_KILLFOCUS: + infocus = 0; + plat_mouse_capture(0); + if (hook_enabled) { + UnhookWindowsHookEx(hKeyboardHook); + hook_enabled = 0; + } + break; } return(0); @@ -721,6 +682,7 @@ ui_init(int nCmdShow) { WCHAR title[200]; WNDCLASSEX wincl; /* buffer for main window's class */ + RAWINPUTDEVICE ridev; /* RawInput device */ MSG messages; /* received-messages buffer */ HWND hwnd; /* handle for our window */ HACCEL haccel; /* handle to accelerator table */ @@ -746,8 +708,8 @@ ui_init(int nCmdShow) wincl.lpfnWndProc = MainWindowProcedure; wincl.style = CS_DBLCLKS; /* Catch double-clicks */ wincl.cbSize = sizeof(WNDCLASSEX); - wincl.hIcon = LoadIcon(hinstance, (LPCTSTR)100); - wincl.hIconSm = LoadIcon(hinstance, (LPCTSTR)100); + wincl.hIcon = LoadIcon(hinstance, (LPCTSTR)10); + wincl.hIconSm = LoadIcon(hinstance, (LPCTSTR)10); wincl.hCursor = NULL; wincl.lpszMenuName = NULL; wincl.cbClsExtra = 0; @@ -800,30 +762,34 @@ ui_init(int nCmdShow) /* Make the window visible on the screen. */ ShowWindow(hwnd, nCmdShow); - /* Load the accelerator table */ - haccel = LoadAccelerators(hinstance, ACCEL_NAME); - if (haccel == NULL) { + /* Initialize the RawInput (keyboard) module. */ + memset(&ridev, 0x00, sizeof(ridev)); + ridev.usUsagePage = 0x01; + ridev.usUsage = 0x06; + ridev.dwFlags = RIDEV_NOHOTKEYS; + ridev.hwndTarget = NULL; /* current focus window */ + if (! RegisterRawInputDevices(&ridev, 1, sizeof(ridev))) { MessageBox(hwndMain, - plat_get_string(IDS_2153), - plat_get_string(IDS_2050), - MB_OK | MB_ICONERROR); - return(3); - } - - /* Initialize the input (keyboard, mouse, game) module. */ - device.usUsagePage = 0x01; - device.usUsage = 0x06; - device.dwFlags = RIDEV_NOHOTKEYS; - device.hwndTarget = hwnd; - if (! RegisterRawInputDevices(&device, 1, sizeof(device))) { - MessageBox(hwndMain, - plat_get_string(IDS_2154), + plat_get_string(IDS_2114), plat_get_string(IDS_2050), MB_OK | MB_ICONERROR); return(4); } keyboard_getkeymap(); + /* Set up the main window for RawInput. */ + plat_set_input(hwndMain); + + /* Load the accelerator table */ + haccel = LoadAccelerators(hinstance, ACCEL_NAME); + if (haccel == NULL) { + MessageBox(hwndMain, + plat_get_string(IDS_2113), + plat_get_string(IDS_2050), + MB_OK | MB_ICONERROR); + return(3); + } + /* Initialize the mouse module. */ win_mouse_init(); @@ -1042,3 +1008,74 @@ plat_mouse_capture(int on) mouse_capture = 0; } } + + +/* Catch WM_INPUT messages for 'current focus' window. */ +static LONG_PTR input_orig_proc; +static HWND input_orig_hwnd = NULL; +#ifdef __amd64__ +static LRESULT CALLBACK +#else +static BOOL CALLBACK +#endif +input_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) { + case WM_INPUT: + keyboard_handle(lParam, infocus); + break; + + case WM_SETFOCUS: + infocus = 1; + if (! hook_enabled) { + hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, + LowLevelKeyboardProc, + GetModuleHandle(NULL), + 0); + hook_enabled = 1; + } + break; + + case WM_KILLFOCUS: + infocus = 0; + plat_mouse_capture(0); + if (hook_enabled) { + UnhookWindowsHookEx(hKeyboardHook); + hook_enabled = 0; + } + break; + + case WM_LBUTTONUP: + if (! video_fullscreen) + plat_mouse_capture(1); + break; + + case WM_MBUTTONUP: + if (mouse_get_buttons() < 3) + plat_mouse_capture(0); + break; + + default: + return(CallWindowProc((WNDPROC)input_orig_proc, + hwnd, message, wParam, lParam)); + } + + return(0); +} + + +/* Set up a handler for the 'currently active' window. */ +void +plat_set_input(HWND h) +{ + /* If needed, rest the old one first. */ + if (input_orig_hwnd != NULL) { + SetWindowLongPtr(input_orig_hwnd, GWL_WNDPROC, + (LONG_PTR)input_orig_proc); + } + + /* Redirect the window procedure so we can catch WM_INPUT. */ + input_orig_proc = GetWindowLongPtr(h, GWLP_WNDPROC); + input_orig_hwnd = h; + SetWindowLongPtr(h, GWL_WNDPROC, (LONG_PTR)&input_proc); +}