diff --git a/src/cdrom/cdrom.c b/src/cdrom/cdrom.c index 2b3a38b..87bf598 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.6 2018/03/17 + * Version: @(#)cdrom.c 1.0.8 2018/03/20 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -73,7 +73,7 @@ #define ABRT_ERR 0x04 /* Command aborted */ #define MCR_ERR 0x08 /* Media change request */ -cdrom_t cdrom[CDROM_NUM]; +cdrom_t *cdrom[CDROM_NUM]; cdrom_image_t cdrom_image[CDROM_NUM]; cdrom_ioctl_t cdrom_ioctl[CDROM_NUM]; cdrom_drive_t cdrom_drives[CDROM_NUM]; @@ -96,6 +96,52 @@ uint8_t scsi_cdrom_drives[16][8] = { { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } }; +/* + * List of usable CD-ROM speeds (from Wikipedia): + * + * Speed KiB/s Mbit/s RPM + * 1× 150 1.2288 200–500 + * 2× 300 2.4576 400-1,000 + * 4× 600 4.9152 800–2,000 + * 6x ? ? ? + * 8× 1,200 9.8304 1,600–4,000 + * 10× 1,500 12.288 2,000–5,000 + * 12× 1,800 14.7456 2,400–6,000 + * 16x ? ? ? + * 20× 1,200–3,000 up to 24.576 4,000 (CAV) + * 24x ? ? ? + * 32× 1,920–4,800 up to 39.3216 6,400 (CAV) + * 36× 2,160–5,400 up to 44.2368 7,200 (CAV) + * 40× 2,400–6,000 up to 49.152 8,000 (CAV) + * 44x ? ? ? + * 48× 2,880–7,200 up to 58.9824 9,600 (CAV) + * 52× 3,120–7,800 up to 63.8976 10,400 (CAV) + * 56× 3,360–8,400 up to 68.8128 11,200 (CAV) + * 72× 6,750–10,800 up to 88.4736 2,000 (multi-beam) + * + * We discard the latter two ones. + */ +const cdrom_speed_t cdrom_speeds[] = { + { 1, 140.0, 1446.0 }, + { 2, 160.0, 1000.0 }, + { 4, 112.0, 675.0 }, + { 6, 112.0, 675.0 }, + { 8, 112.0, 675.0 }, + { 10, 112.0, 675.0 }, + { 12, 75.0, 400.0 }, + { 16, 58.0, 350.0 }, + { 20, 50.0, 300.0 }, + { 24, 45.0, 270.0 }, + { 32, 45.0, 270.0 }, + { 36, 50.0, 300.0 }, + { 40, 50.0, 300.0 }, + { 44, 50.0, 300.0 }, + { 48, 50.0, 300.0 }, + { 52, 45.0, 270.0 }, + { -1, 0.0, 0.0 }, +}; + + #pragma pack(push,1) static struct { @@ -151,7 +197,7 @@ const uint8_t cdrom_command_flags[0x100] = 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 | ALLOW_UA, /* 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 @@ -255,7 +301,7 @@ static const mode_sense_pages_t cdrom_mode_sense_pages_default = { 0, 0 }, { 0, 0 }, { 0, 0 }, - { GPMODE_CAPABILITIES_PAGE, 0x14, 0x3B, 0, 0x71, 0x60, 0x29, 0, 0x02, 0xC2, 0, 2, 0, 0, 0x02, 0xC2, 0, 0, 0, 0, 0, 0 } + { GPMODE_CAPABILITIES_PAGE, 0x12, 0, 0, 1, 0, 0, 0, 0x02, 0xC2, 1, 0, 0, 0, 0x02, 0xC2, 0, 0, 0, 0 } } }; static const mode_sense_pages_t cdrom_mode_sense_pages_default_scsi = @@ -302,7 +348,7 @@ static const mode_sense_pages_t cdrom_mode_sense_pages_default_scsi = { 0, 0 }, { 0, 0 }, { 0, 0 }, - { GPMODE_CAPABILITIES_PAGE, 0x14, 0x3B, 0, 0x71, 0x60, 0x29, 0, 0x02, 0xC2, 0, 2, 0, 0, 0x02, 0xC2, 0, 0, 0, 0, 0, 0 } + { GPMODE_CAPABILITIES_PAGE, 0x12, 0, 0, 1, 0, 0, 0, 0x02, 0xC2, 1, 0, 0, 0, 0x02, 0xC2, 0, 0, 0, 0 } } }; static const mode_sense_pages_t cdrom_mode_sense_pages_changeable = @@ -349,7 +395,7 @@ static const mode_sense_pages_t cdrom_mode_sense_pages_changeable = { 0, 0 }, { 0, 0 }, { 0, 0 }, - { GPMODE_CAPABILITIES_PAGE, 0x14, 0x3B, 0, 0x71, 0x60, 0x29, 0, 0x02, 0xC2, 0, 2, 0, 0, 0x02, 0xC2, 0, 0, 0, 0, 0, 0 } + { GPMODE_CAPABILITIES_PAGE, 0x12, 0, 0, 1, 0, 0, 0, 0x02, 0xC2, 1, 0, 0, 0, 0x02, 0xC2, 0, 0, 0, 0 } } }; static mode_sense_pages_t cdrom_mode_sense_pages_saved[CDROM_NUM]; @@ -376,6 +422,19 @@ cdrom_log(const char *format, ...) } +int +cdrom_speed_idx(int realspeed) +{ + int idx; + + for (idx = 0; cdrom_speeds[idx].speed > 0; idx++) + if (cdrom_speeds[idx].speed == realspeed) + return(idx); + + return(-1); +} + + int find_cdrom_for_channel(uint8_t channel) { uint8_t i = 0; @@ -389,7 +448,7 @@ int find_cdrom_for_channel(uint8_t channel) void cdrom_init(int id, int cdb_len_setting); -void build_atapi_cdrom_map() +void build_atapi_cdrom_map(void) { uint8_t i = 0; @@ -413,7 +472,7 @@ int find_cdrom_for_scsi_id(uint8_t scsi_id, uint8_t scsi_lun) return 0xff; } -void build_scsi_cdrom_map() +void build_scsi_cdrom_map(void) { uint8_t i = 0; uint8_t j = 0; @@ -433,39 +492,57 @@ void build_scsi_cdrom_map() void cdrom_set_callback(uint8_t id) { if (cdrom_drives[id].bus_type != CDROM_BUS_SCSI) - ide_set_callback(cdrom_drives[id].ide_channel, cdrom[id].callback); + ide_set_callback(cdrom_drives[id].ide_channel, cdrom[id]->callback); } void cdrom_set_cdb_len(int id, int cdb_len) { - cdrom[id].cdb_len = cdb_len; + cdrom[id]->cdb_len = cdb_len; } void cdrom_reset_cdb_len(int id) { - cdrom[id].cdb_len = cdrom[id].cdb_len_setting ? 16 : 12; + cdrom[id]->cdb_len = cdrom[id]->cdb_len_setting ? 16 : 12; } void cdrom_set_signature(int id) { + cdrom_t *dev; + if (id >= CDROM_NUM) return; - cdrom[id].phase = 1; - cdrom[id].request_length = 0xEB14; + dev = cdrom[id]; + dev->phase = 1; + dev->request_length = 0xEB14; +} + +void cdrom_destroy_drives(void) +{ + int i; + + for (i = 0; i < CDROM_NUM; i++) { + if (cdrom[i] != NULL) { + free(cdrom[i]); + cdrom[i] = NULL; + } + } } void cdrom_init(int id, int cdb_len_setting) { + cdrom_t *dev; + if (id >= CDROM_NUM) return; - memset(&(cdrom[id]), 0, sizeof(cdrom_t)); - cdrom[id].requested_blocks = 1; + dev = cdrom[id]; + memset(dev, 0x00, sizeof(cdrom_t)); + dev->requested_blocks = 1; if (cdb_len_setting <= 1) - cdrom[id].cdb_len_setting = cdb_len_setting; + dev->cdb_len_setting = cdb_len_setting; cdrom_reset_cdb_len(id); - cdrom[id].cd_status = CD_STATUS_EMPTY; - cdrom[id].sense[0] = 0xf0; - cdrom[id].sense[7] = 10; + dev->cd_status = CD_STATUS_EMPTY; + dev->sense[0] = 0xf0; + dev->sense[7] = 10; cdrom_drives[id].bus_mode = 0; if (cdrom_drives[id].bus_type >= CDROM_BUS_ATAPI_PIO_AND_DMA) cdrom_drives[id].bus_mode |= 2; @@ -475,12 +552,13 @@ void cdrom_init(int id, int cdb_len_setting) if (cdrom_drives[id].bus_type < CDROM_BUS_SCSI) cdrom_set_signature(id); cdrom_drives[id].max_blocks_at_once = 85; - cdrom[id].status = READY_STAT | DSC_STAT; - cdrom[id].pos = 0; - cdrom[id].packet_status = 0xff; - cdrom_sense_key = cdrom_asc = cdrom_ascq = cdrom[id].unit_attention = 0; - cdrom[id].cdb_len_setting = 0; - cdrom[id].cdb_len = 12; + dev->status = READY_STAT | DSC_STAT; + dev->pos = 0; + dev->packet_status = 0xff; + cdrom_sense_key = cdrom_asc = cdrom_ascq = dev->unit_attention = 0; + dev->cdb_len_setting = 0; + dev->cdb_len = 12; + dev->cur_speed = cdrom_drives[id].speed_idx; } int cdrom_supports_pio(int id) @@ -496,6 +574,8 @@ int cdrom_supports_dma(int id) /* Returns: 0 for none, 1 for PIO, 2 for DMA. */ int cdrom_current_mode(int id) { + cdrom_t *dev = cdrom[id]; + if (!cdrom_supports_pio(id) && !cdrom_supports_dma(id)) return 0; if (cdrom_supports_pio(id) && !cdrom_supports_dma(id)) { @@ -505,8 +585,8 @@ int cdrom_current_mode(int id) if (!cdrom_supports_pio(id) && cdrom_supports_dma(id)) return 2; if (cdrom_supports_pio(id) && cdrom_supports_dma(id)) { - cdrom_log("CD-ROM %i: Drive supports both, setting to %s\n", id, (cdrom[id].features & 1) ? "DMA" : "PIO", id); - return (cdrom[id].features & 1) ? 2 : 1; + cdrom_log("CD-ROM %i: Drive supports both, setting to %s\n", id, (dev->features & 1) ? "DMA" : "PIO", id); + return (dev->features & 1) ? 2 : 1; } return 0; @@ -515,7 +595,9 @@ int cdrom_current_mode(int id) /* Translates ATAPI status (ERR_STAT flag) to SCSI status. */ int cdrom_CDROM_PHASE_to_scsi(uint8_t id) { - if (cdrom[id].status & ERR_STAT) + cdrom_t *dev = cdrom[id]; + + if (dev->status & ERR_STAT) return SCSI_STATUS_CHECK_CONDITION; else return SCSI_STATUS_OK; @@ -524,8 +606,10 @@ int cdrom_CDROM_PHASE_to_scsi(uint8_t id) /* Translates ATAPI phase (DRQ, I/O, C/D) to SCSI phase (MSG, C/D, I/O). */ int cdrom_atapi_phase_to_scsi(uint8_t id) { - if (cdrom[id].status & 8) { - switch (cdrom[id].phase & 3) { + cdrom_t *dev = cdrom[id]; + + if (dev->status & 8) { + switch (dev->phase & 3) { case 0: return 0; case 1: @@ -536,7 +620,7 @@ int cdrom_atapi_phase_to_scsi(uint8_t id) return 7; } } else { - if ((cdrom[id].phase & 3) == 3) + if ((dev->phase & 3) == 3) return 3; else return 4; @@ -668,6 +752,7 @@ uint8_t cdrom_mode_sense_read(uint8_t id, uint8_t page_control, uint8_t page, ui uint32_t cdrom_mode_sense(uint8_t id, uint8_t *buf, uint32_t pos, uint8_t type, uint8_t block_descriptor_len) { + cdrom_t *dev = cdrom[id]; uint8_t page_control = (type >> 6) & 3; int i = 0; @@ -690,13 +775,25 @@ uint32_t cdrom_mode_sense(uint8_t id, uint8_t *buf, uint32_t pos, uint8_t type, for (i = 0; i < 0x40; i++) { if ((type == GPMODE_ALL_PAGES) || (type == i)) { - if (cdrom_mode_sense_page_flags & (1LL << cdrom[id].current_page_code)) { + if (cdrom_mode_sense_page_flags & (1LL << dev->current_page_code)) { buf[pos++] = cdrom_mode_sense_read(id, page_control, i, 0); msplen = cdrom_mode_sense_read(id, page_control, i, 1); buf[pos++] = msplen; cdrom_log("CD-ROM %i: MODE SENSE: Page [%02X] length %i\n", id, i, msplen); - for (j = 0; j < msplen; j++) - buf[pos++] = cdrom_mode_sense_read(id, page_control, i, 2 + j); + for (j = 0; j < msplen; j++) { + if ((i == GPMODE_CAPABILITIES_PAGE) && (j >= 6) && (j <= 7)) { + if (j & 1) + buf[pos++] = ((cdrom_speeds[cdrom_drives[id].speed_idx].speed * 176) & 0xff); + else + buf[pos++] = ((cdrom_speeds[cdrom_drives[id].speed_idx].speed * 176) >> 8); + } else if ((i == GPMODE_CAPABILITIES_PAGE) && (j >= 12) && (j <= 13)) { + if (j & 1) + buf[pos++] = ((cdrom_speeds[dev->cur_speed].speed * 176) & 0xff); + else + buf[pos++] = ((cdrom_speeds[dev->cur_speed].speed * 176) >> 8); + } else + buf[pos++] = cdrom_mode_sense_read(id, page_control, i, 2 + j); + } } } } @@ -706,116 +803,173 @@ uint32_t cdrom_mode_sense(uint8_t id, uint8_t *buf, uint32_t pos, uint8_t type, void cdrom_update_request_length(uint8_t id, int len, int block_len) { + cdrom_t *dev = cdrom[id]; int bt; - cdrom[id].max_transfer_len = cdrom[id].request_length; + + dev->max_transfer_len = dev->request_length; /* For media access commands, make sure the requested DRQ length matches the block length. */ - switch (cdrom[id].current_cdb[0]) { + switch (dev->current_cdb[0]) { case 0x08: case 0x28: case 0xa8: case 0xb9: case 0xbe: - if (cdrom[id].max_transfer_len < block_len) - cdrom[id].max_transfer_len = block_len; - bt = (cdrom[id].requested_blocks * block_len); + if (dev->max_transfer_len < block_len) + dev->max_transfer_len = block_len; + bt = (dev->requested_blocks * block_len); if (len > bt) len = bt; default: - cdrom[id].packet_len = len; + dev->packet_len = len; break; } /* If the DRQ length is odd, and the total remaining length is bigger, make sure it's even. */ - if ((cdrom[id].max_transfer_len & 1) && (cdrom[id].max_transfer_len < len)) - cdrom[id].max_transfer_len &= 0xfffe; + if ((dev->max_transfer_len & 1) && (dev->max_transfer_len < len)) + dev->max_transfer_len &= 0xfffe; /* If the DRQ length is smaller or equal in size to the total remaining length, set it to that. */ - if (!cdrom[id].max_transfer_len) - cdrom[id].max_transfer_len = 65534; - if (len <= cdrom[id].max_transfer_len) - cdrom[id].max_transfer_len = len; - return; + if (!dev->max_transfer_len) + dev->max_transfer_len = 65534; + if (len <= dev->max_transfer_len) + dev->max_transfer_len = len; +} + + +#define MIN_SEEK 2000 +#define MAX_SEEK 333333 + +static double cdrom_seek_time(uint8_t id) +{ + cdrom_t *dev = cdrom[id]; + + uint32_t diff = dev->seek_diff; + double sd = (double) (MAX_SEEK - MIN_SEEK); + + if (diff < MIN_SEEK) + return 0.0; + if (diff > MAX_SEEK) + diff = MAX_SEEK; + + diff -= MIN_SEEK; + + return cdrom_speeds[cdrom_drives[id].speed_idx].seek1 + + ((cdrom_speeds[cdrom_drives[id].speed_idx].seek2 * ((double) diff)) / sd); +} + +static double cdrom_bus_speed(uint8_t id) +{ + cdrom_t *dev = cdrom[id]; + + if (cdrom_drives[id].bus_type == CDROM_BUS_SCSI) { + dev->callback = -1LL; /* Speed depends on SCSI controller */ + return 0.0; + } else if (cdrom_drives[id].bus_type == CDROM_BUS_ATAPI_PIO_AND_DMA) { + if (cdrom_current_mode(id) == 2) + return 66666666.666666666666666; /* 66 MB/s MDMA-2 speed */ + else + return 8333333.333333333333333; /* 8.3 MB/s PIO-2 speed */ + } else + return 3333333.333333333333333; /* 3.3 MB/s PIO-0 speed */ } static void cdrom_command_common(uint8_t id) { + cdrom_t *dev = cdrom[id]; double bytes_per_second, period; double dusec; - cdrom[id].status = BUSY_STAT; - cdrom[id].phase = 1; - cdrom[id].pos = 0; - if (cdrom[id].packet_status == CDROM_PHASE_COMPLETE) { + dev->status = BUSY_STAT; + dev->phase = 1; + dev->pos = 0; + dev->callback = 0LL; + if (dev->packet_status == CDROM_PHASE_COMPLETE) { cdrom_phase_callback(id); - cdrom[id].callback = 0LL; + dev->callback = 0LL; } else { - switch(cdrom[id].current_cdb[0]) { + switch(dev->current_cdb[0]) { + case GPCMD_REZERO_UNIT: + case 0x0b: + case 0x2b: + /* Seek time is in us. */ + period = cdrom_seek_time(id) * ((double) TIMER_USEC); + dev->callback += ((int64_t) period); + cdrom_set_callback(id); + return; + case 0x08: + case 0x28: + case 0xa8: + /* Seek time is in us. */ + period = cdrom_seek_time(id) * ((double) TIMER_USEC); + dev->callback += ((int64_t) period); case 0x25: case 0x42: case 0x43: case 0x44: - case 0x08: - case 0x28: case 0x51: case 0x52: - case 0xa8: case 0xad: case 0xb8: case 0xb9: case 0xbe: - bytes_per_second = 150.0 * 1024.0; - bytes_per_second *= (double) cdrom_drives[id].speed; + /* bytes_per_second = 150.0 * 1024.0; */ + bytes_per_second = (1000000.0 / 12000.0) * 2048.0; /* Account for seek time. */ + bytes_per_second *= (double)cdrom_speeds[dev->cur_speed].speed; break; default: - if (cdrom_drives[id].bus_type == CDROM_BUS_SCSI) { - cdrom[id].callback = -1LL; /* Speed depends on SCSI controller */ + bytes_per_second = cdrom_bus_speed(id); + if (bytes_per_second == 0.0) { + dev->callback = -1LL; /* Speed depends on SCSI controller */ return; - } else if (cdrom_drives[id].bus_type == CDROM_BUS_ATAPI_PIO_AND_DMA) { - if (cdrom_current_mode(id) == 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 */ - } else - bytes_per_second = 3333333.333333333333333; /* 3.3 MB/s PIO-0 speed */ - break; + } } period = 1000000.0 / bytes_per_second; dusec = (double) TIMER_USEC; - dusec = dusec * period * (double) (cdrom[id].packet_len); - cdrom[id].callback = ((int64_t) dusec); + dusec = dusec * period * (double) (dev->packet_len); + dev->callback = ((int64_t) dusec); } cdrom_set_callback(id); } static void cdrom_command_complete(uint8_t id) { - cdrom[id].packet_status = CDROM_PHASE_COMPLETE; + cdrom_t *dev = cdrom[id]; + + dev->packet_status = CDROM_PHASE_COMPLETE; cdrom_command_common(id); } static void cdrom_command_read(uint8_t id) { - cdrom[id].packet_status = CDROM_PHASE_DATA_IN; + cdrom_t *dev = cdrom[id]; + + dev->packet_status = CDROM_PHASE_DATA_IN; cdrom_command_common(id); - cdrom[id].total_read = 0; + dev->total_read = 0; } static void cdrom_command_read_dma(uint8_t id) { - cdrom[id].packet_status = CDROM_PHASE_DATA_IN_DMA; + cdrom_t *dev = cdrom[id]; + + dev->packet_status = CDROM_PHASE_DATA_IN_DMA; cdrom_command_common(id); - cdrom[id].total_read = 0; + dev->total_read = 0; } static void cdrom_command_write(uint8_t id) { - cdrom[id].packet_status = CDROM_PHASE_DATA_OUT; + cdrom_t *dev = cdrom[id]; + + dev->packet_status = CDROM_PHASE_DATA_OUT; cdrom_command_common(id); } static void cdrom_command_write_dma(uint8_t id) { - cdrom[id].packet_status = CDROM_PHASE_DATA_OUT_DMA; + cdrom_t *dev = cdrom[id]; + + dev->packet_status = CDROM_PHASE_DATA_OUT_DMA; cdrom_command_common(id); } @@ -826,8 +980,10 @@ static void cdrom_command_write_dma(uint8_t id) direction = Transfer direction (0 = read from host, 1 = write to host). */ static void cdrom_data_command_finish(uint8_t id, int len, int block_len, int alloc_len, int direction) { - cdrom_log("CD-ROM %i: Finishing command (%02X): %i, %i, %i, %i, %i\n", id, cdrom[id].current_cdb[0], len, block_len, alloc_len, direction, cdrom[id].request_length); - cdrom[id].pos=0; + cdrom_t *dev = cdrom[id]; + + cdrom_log("CD-ROM %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; if (alloc_len >= 0) { if (alloc_len < len) { len = alloc_len; @@ -835,14 +991,14 @@ static void cdrom_data_command_finish(uint8_t id, int len, int block_len, int al } if ((len == 0) || (cdrom_current_mode(id) == 0)) { if (cdrom_drives[id].bus_type != CDROM_BUS_SCSI) { - cdrom[id].packet_len = 0; + dev->packet_len = 0; } cdrom_command_complete(id); } else { if (cdrom_current_mode(id) == 2) { if (cdrom_drives[id].bus_type != CDROM_BUS_SCSI) { - cdrom[id].packet_len = alloc_len; + dev->packet_len = alloc_len; } if (direction == 0) @@ -859,12 +1015,14 @@ static void cdrom_data_command_finish(uint8_t id, int len, int block_len, int al } } - cdrom_log("CD-ROM %i: Status: %i, cylinder %i, packet length: %i, position: %i, phase: %i\n", id, cdrom[id].packet_status, cdrom[id].request_length, cdrom[id].packet_len, cdrom[id].pos, cdrom[id].phase); + cdrom_log("CD-ROM %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); } static void cdrom_sense_clear(int id, int command) { - cdrom[id].previous_command = command; + cdrom_t *dev = cdrom[id]; + + dev->previous_command = command; cdrom_sense_key = cdrom_asc = cdrom_ascq = 0; } @@ -881,30 +1039,34 @@ static void cdrom_set_phase(uint8_t id, uint8_t phase) static void cdrom_cmd_error(uint8_t id) { + cdrom_t *dev = cdrom[id]; + cdrom_set_phase(id, SCSI_PHASE_STATUS); - cdrom[id].error = ((cdrom_sense_key & 0xf) << 4) | ABRT_ERR; - if (cdrom[id].unit_attention) - cdrom[id].error |= MCR_ERR; - cdrom[id].status = READY_STAT | ERR_STAT; - cdrom[id].phase = 3; - cdrom[id].pos = 0; - cdrom[id].packet_status = 0x80; - cdrom[id].callback = 50LL * CDROM_TIME; + dev->error = ((cdrom_sense_key & 0xf) << 4) | ABRT_ERR; + if (dev->unit_attention) + dev->error |= MCR_ERR; + dev->status = READY_STAT | ERR_STAT; + dev->phase = 3; + dev->pos = 0; + dev->packet_status = 0x80; + dev->callback = 50LL * CDROM_TIME; cdrom_set_callback(id); cdrom_log("CD-ROM %i: ERROR: %02X/%02X/%02X\n", id, cdrom_sense_key, cdrom_asc, cdrom_ascq); } static void cdrom_unit_attention(uint8_t id) { + cdrom_t *dev = cdrom[id]; + cdrom_set_phase(id, SCSI_PHASE_STATUS); - cdrom[id].error = (SENSE_UNIT_ATTENTION << 4) | ABRT_ERR; - if (cdrom[id].unit_attention) - cdrom[id].error |= MCR_ERR; - cdrom[id].status = READY_STAT | ERR_STAT; - cdrom[id].phase = 3; - cdrom[id].pos = 0; - cdrom[id].packet_status = 0x80; - cdrom[id].callback = 50LL * CDROM_TIME; + dev->error = (SENSE_UNIT_ATTENTION << 4) | ABRT_ERR; + if (dev->unit_attention) + dev->error |= MCR_ERR; + dev->status = READY_STAT | ERR_STAT; + dev->phase = 3; + dev->pos = 0; + dev->packet_status = 0x80; + dev->callback = 50LL * CDROM_TIME; cdrom_set_callback(id); cdrom_log("CD-ROM %i: UNIT ATTENTION\n", id); } @@ -943,20 +1105,24 @@ static void cdrom_lba_out_of_range(uint8_t id) static void cdrom_invalid_field(uint8_t id) { + cdrom_t *dev = cdrom[id]; + cdrom_sense_key = SENSE_ILLEGAL_REQUEST; cdrom_asc = ASC_INV_FIELD_IN_CMD_PACKET; cdrom_ascq = 0; cdrom_cmd_error(id); - cdrom[id].status = 0x53; + dev->status = 0x53; } static void cdrom_invalid_field_pl(uint8_t id) { + cdrom_t *dev = cdrom[id]; + cdrom_sense_key = SENSE_ILLEGAL_REQUEST; cdrom_asc = ASC_INV_FIELD_IN_PARAMETER_LIST; cdrom_ascq = 0; cdrom_cmd_error(id); - cdrom[id].status = 0x53; + dev->status = 0x53; } static void cdrom_illegal_mode(uint8_t id) @@ -1077,10 +1243,11 @@ void cdrom_update_cdb(uint8_t *cdb, int lba_pos, int number_of_blocks) } } -#define cdbufferb cdrom[id].buffer +#define cdbufferb dev->buffer int cdrom_read_data(uint8_t id, int msf, int type, int flags, uint32_t *len) { + cdrom_t *dev = cdrom[id]; int ret = 0; uint32_t cdsize = 0; @@ -1092,36 +1259,36 @@ int cdrom_read_data(uint8_t id, int msf, int type, int flags, uint32_t *len) if (cdrom_drives[id].handler->pass_through) { cdsize = cdrom_drives[id].handler->size(id); - ret = cdrom_pass_through(id, len, cdrom[id].current_cdb, cdbufferb + cdrom[id].data_pos); - cdrom[id].data_pos += *len; + ret = cdrom_pass_through(id, len, dev->current_cdb, cdbufferb + dev->data_pos); + dev->data_pos += *len; if (!ret) return 0; - if (cdrom[id].sector_pos > (cdsize - 1)) { + if (dev->sector_pos > (cdsize - 1)) { /* cdrom_log("CD-ROM %i: Trying to read beyond the end of disc\n", id); */ cdrom_lba_out_of_range(id); return 0; } - cdrom[id].old_len = *len; + dev->old_len = *len; } else { - if (cdrom[id].sector_pos > (cdrom_drives[id].handler->size(id) - 1)) { + if (dev->sector_pos > (cdrom_drives[id].handler->size(id) - 1)) { /* cdrom_log("CD-ROM %i: Trying to read beyond the end of disc\n", id); */ cdrom_lba_out_of_range(id); return 0; } - cdrom[id].old_len = 0; + dev->old_len = 0; *len = 0; - for (i = 0; i < cdrom[id].requested_blocks; i++) { - ret = cdrom_drives[id].handler->readsector_raw(id, cdbufferb + cdrom[id].data_pos, cdrom[id].sector_pos + i, msf, type, flags, &temp_len); + for (i = 0; i < dev->requested_blocks; i++) { + ret = cdrom_drives[id].handler->readsector_raw(id, cdbufferb + dev->data_pos, dev->sector_pos + i, msf, type, flags, &temp_len); - last_valid_data_pos = cdrom[id].data_pos; + last_valid_data_pos = dev->data_pos; - cdrom[id].data_pos += temp_len; - cdrom[id].old_len += temp_len; + dev->data_pos += temp_len; + dev->old_len += temp_len; *len += temp_len; @@ -1139,48 +1306,49 @@ int cdrom_read_data(uint8_t id, int msf, int type, int flags, uint32_t *len) int cdrom_read_blocks(uint8_t id, uint32_t *len, int first_batch) { + cdrom_t *dev = cdrom[id]; int ret = 0; int msf = 0; - + int type = 0; int flags = 0; - - if (cdrom[id].current_cdb[0] == 0xb9) + + if (dev->current_cdb[0] == 0xb9) msf = 1; - - if ((cdrom[id].current_cdb[0] == 0xb9) || (cdrom[id].current_cdb[0] == 0xbe)) { - type = (cdrom[id].current_cdb[1] >> 2) & 7; - flags = cdrom[id].current_cdb[9] | (((uint32_t) cdrom[id].current_cdb[10]) << 8); + + if ((dev->current_cdb[0] == 0xb9) || (dev->current_cdb[0] == 0xbe)) { + type = (dev->current_cdb[1] >> 2) & 7; + flags = dev->current_cdb[9] | (((uint32_t) dev->current_cdb[10]) << 8); } else { type = 8; flags = 0x10; } - cdrom[id].data_pos = 0; - - if (!cdrom[id].sector_len) { + dev->data_pos = 0; + + if (!dev->sector_len) { cdrom_command_complete(id); return -1; } - cdrom_log("Reading %i blocks starting from %i...\n", cdrom[id].requested_blocks, cdrom[id].sector_pos); + cdrom_log("Reading %i blocks starting from %i...\n", dev->requested_blocks, dev->sector_pos); - cdrom_update_cdb(cdrom[id].current_cdb, cdrom[id].sector_pos, cdrom[id].requested_blocks); + cdrom_update_cdb(dev->current_cdb, dev->sector_pos, dev->requested_blocks); ret = cdrom_read_data(id, msf, type, flags, len); cdrom_log("Read %i bytes of blocks...\n", *len); - if (!ret || ((cdrom[id].old_len != *len) && !first_batch)) { - if ((cdrom[id].old_len != *len) && !first_batch) + if (!ret || ((dev->old_len != *len) && !first_batch)) { + if ((dev->old_len != *len) && !first_batch) cdrom_illegal_mode(id); return 0; } - cdrom[id].sector_pos += cdrom[id].requested_blocks; - cdrom[id].sector_len -= cdrom[id].requested_blocks; + dev->sector_pos += dev->requested_blocks; + dev->sector_len -= dev->requested_blocks; return 1; } @@ -1296,7 +1464,11 @@ static int cdrom_read_dvd_structure(uint8_t id, int format, const uint8_t *packe void cdrom_insert(uint8_t id) { - cdrom[id].unit_attention = 1; + cdrom_t *dev = cdrom[id]; + + dev->unit_attention = 1; + + cdrom_log("CD-ROM %i: Media insert\n", id); } /*SCSI Sense Initialization*/ @@ -1309,11 +1481,13 @@ void cdrom_sense_code_ok(uint8_t id) int cdrom_pre_execution_check(uint8_t id, uint8_t *cdb) { + cdrom_t *dev = cdrom[id]; + int ready = 0; if (cdrom_drives[id].bus_type == CDROM_BUS_SCSI) { - if (((cdrom[id].request_length >> 5) & 7) != cdrom_drives[id].scsi_device_lun) { - cdrom_log("CD-ROM %i: Attempting to execute a unknown command targeted at SCSI LUN %i\n", id, ((cdrom[id].request_length >> 5) & 7)); + if (((dev->request_length >> 5) & 7) != cdrom_drives[id].scsi_device_lun) { + cdrom_log("CD-ROM %i: Attempting to execute a unknown command targeted at SCSI LUN %i\n", id, ((dev->request_length >> 5) & 7)); cdrom_invalid_lun(id); return 0; } @@ -1352,25 +1526,25 @@ skip_ready_check: /* If the drive is not ready, there is no reason to keep the UNIT ATTENTION condition present, as we only use it to mark disc changes. */ - if (!ready && cdrom[id].unit_attention) - cdrom[id].unit_attention = 0; + if (!ready && dev->unit_attention) + dev->unit_attention = 0; /* If the UNIT ATTENTION condition is set and the command does not allow execution under it, error out and report the condition. */ - if (cdrom[id].unit_attention == 1) { + if (dev->unit_attention == 1) { /* Only increment the unit attention phase if the command can not pass through it. */ if (!(cdrom_command_flags[cdb[0]] & ALLOW_UA)) { /* cdrom_log("CD-ROM %i: Unit attention now 2\n", id); */ - cdrom[id].unit_attention = 2; + dev->unit_attention++; cdrom_log("CD-ROM %i: UNIT ATTENTION: Command %02X not allowed to pass through\n", id, cdb[0]); cdrom_unit_attention(id); return 0; } } - else if (cdrom[id].unit_attention == 2) { + else if (dev->unit_attention == 2) { if (cdb[0] != GPCMD_REQUEST_SENSE) { /* cdrom_log("CD-ROM %i: Unit attention now 0\n", id); */ - cdrom[id].unit_attention = 0; + dev->unit_attention = 0; } } @@ -1381,9 +1555,9 @@ skip_ready_check: /* Next it's time for NOT READY. */ if (!ready) - cdrom[id].media_status = MEC_MEDIA_REMOVAL; + dev->media_status = MEC_MEDIA_REMOVAL; else - cdrom[id].media_status = (cdrom[id].unit_attention) ? MEC_NEW_MEDIA : MEC_NO_CHANGE; + dev->media_status = (dev->unit_attention) ? MEC_NEW_MEDIA : MEC_NO_CHANGE; if ((cdrom_command_flags[cdb[0]] & CHECK_READY) && !ready) { cdrom_log("CD-ROM %i: Not ready (%02X)\n", id, cdb[0]); @@ -1399,72 +1573,86 @@ skip_ready_check: void cdrom_clear_callback(uint8_t channel) { uint8_t id = atapi_cdrom_drives[channel]; + cdrom_t *dev = cdrom[id]; if (id < CDROM_NUM) { - cdrom[id].callback = 0LL; + dev->callback = 0LL; cdrom_set_callback(id); } } static void cdrom_seek(uint8_t id, uint32_t pos) { + cdrom_t *dev = cdrom[id]; + /* cdrom_log("CD-ROM %i: Seek %08X\n", id, pos); */ - cdrom[id].seek_pos = pos; + dev->seek_pos = pos; if (cdrom_drives[id].handler->stop) cdrom_drives[id].handler->stop(id); } static void cdrom_rezero(uint8_t id) { + cdrom_t *dev = cdrom[id]; + if (cdrom_drives[id].handler->stop) cdrom_drives[id].handler->stop(id); - cdrom[id].sector_pos = cdrom[id].sector_len = 0; + dev->sector_pos = dev->sector_len = 0; cdrom_seek(id, 0); } void cdrom_reset(uint8_t id) { + cdrom_t *dev = cdrom[id]; + + if (!dev) + return; + cdrom_rezero(id); - cdrom[id].status = 0; - cdrom[id].callback = 0LL; + dev->status = 0; + dev->callback = 0LL; cdrom_set_callback(id); - cdrom[id].packet_status = 0xff; - cdrom[id].unit_attention = 0; + dev->packet_status = 0xff; + dev->unit_attention = 0; } int cdrom_playing_completed(uint8_t id) { - cdrom[id].prev_status = cdrom[id].cd_status; - cdrom[id].cd_status = cdrom_drives[id].handler->status(id); - if (((cdrom[id].prev_status == CD_STATUS_PLAYING) || (cdrom[id].prev_status == CD_STATUS_PAUSED)) && ((cdrom[id].cd_status != CD_STATUS_PLAYING) && (cdrom[id].cd_status != CD_STATUS_PAUSED))) + cdrom_t *dev = cdrom[id]; + + dev->prev_status = dev->cd_status; + dev->cd_status = cdrom_drives[id].handler->status(id); + if (((dev->prev_status == CD_STATUS_PLAYING) || (dev->prev_status == CD_STATUS_PAUSED)) && ((dev->cd_status != CD_STATUS_PLAYING) && (dev->cd_status != CD_STATUS_PAUSED))) return 1; else return 0; } void cdrom_request_sense(uint8_t id, uint8_t *buffer, uint8_t alloc_length) -{ +{ + cdrom_t *dev = cdrom[id]; + /*Will return 18 bytes of 0*/ if (alloc_length != 0) { memset(buffer, 0, alloc_length); - memcpy(buffer, cdrom[id].sense, alloc_length); + memcpy(buffer, dev->sense, alloc_length); } buffer[0] = 0x70; - if ((cdrom_sense_key > 0) && ((cdrom[id].cd_status < CD_STATUS_PLAYING) || (cdrom[id].cd_status == CD_STATUS_STOPPED)) && cdrom_playing_completed(id)) { + if ((cdrom_sense_key > 0) && ((dev->cd_status < CD_STATUS_PLAYING) || (dev->cd_status == CD_STATUS_STOPPED)) && cdrom_playing_completed(id)) { buffer[2]=SENSE_ILLEGAL_REQUEST; buffer[12]=ASC_AUDIO_PLAY_OPERATION; buffer[13]=ASCQ_AUDIO_PLAY_OPERATION_COMPLETED; } - else if ((cdrom_sense_key == 0) && (cdrom[id].cd_status >= CD_STATUS_PLAYING) && (cdrom[id].cd_status != CD_STATUS_STOPPED)) { + else if ((cdrom_sense_key == 0) && (dev->cd_status >= CD_STATUS_PLAYING) && (dev->cd_status != CD_STATUS_STOPPED)) { buffer[2]=SENSE_ILLEGAL_REQUEST; buffer[12]=ASC_AUDIO_PLAY_OPERATION; - buffer[13]=(cdrom[id].cd_status == CD_STATUS_PLAYING) ? ASCQ_AUDIO_PLAY_OPERATION_IN_PROGRESS : ASCQ_AUDIO_PLAY_OPERATION_PAUSED; + buffer[13]=(dev->cd_status == CD_STATUS_PLAYING) ? ASCQ_AUDIO_PLAY_OPERATION_IN_PROGRESS : ASCQ_AUDIO_PLAY_OPERATION_PAUSED; } else { - if (cdrom[id].unit_attention && (cdrom_sense_key == 0)) { + if (dev->unit_attention && (cdrom_sense_key == 0)) { buffer[2]=SENSE_UNIT_ATTENTION; buffer[12]=ASC_MEDIUM_MAY_HAVE_CHANGED; buffer[13]=0; @@ -1476,7 +1664,7 @@ void cdrom_request_sense(uint8_t id, uint8_t *buffer, uint8_t alloc_length) if (buffer[2] == SENSE_UNIT_ATTENTION) { /* If the last remaining sense is unit attention, clear that condition. */ - cdrom[id].unit_attention = 0; + dev->unit_attention = 0; } /* Clear the sense stuff as per the spec. */ @@ -1485,6 +1673,8 @@ void cdrom_request_sense(uint8_t id, uint8_t *buffer, uint8_t alloc_length) void cdrom_request_sense_for_scsi(uint8_t id, uint8_t *buffer, uint8_t alloc_length) { + cdrom_t *dev = cdrom[id]; + int ready = 0; if (cdrom_drives[id].handler->medium_changed(id)) @@ -1492,11 +1682,11 @@ void cdrom_request_sense_for_scsi(uint8_t id, uint8_t *buffer, uint8_t alloc_len ready = cdrom_drives[id].handler->ready(id); - if (!ready && cdrom[id].unit_attention) { + if (!ready && dev->unit_attention) { /* If the drive is not ready, there is no reason to keep the UNIT ATTENTION condition present, as we only use it to mark disc changes. */ - cdrom[id].unit_attention = 0; + dev->unit_attention = 0; } /* Do *NOT* advance the unit attention phase. */ @@ -1519,12 +1709,16 @@ void cdrom_set_buf_len(uint8_t id, int32_t *BufLen, uint32_t *src_len) void cdrom_buf_alloc(uint8_t id, uint32_t len) { + cdrom_t *dev = cdrom[id]; + cdrom_log("CD-ROM %i: Allocated buffer length: %i\n", id, len); cdbufferb = (uint8_t *) malloc(len); } void cdrom_buf_free(uint8_t id) { + cdrom_t *dev = cdrom[id]; + if (cdbufferb) { cdrom_log("CD-ROM %i: Freeing buffer...\n", id); free(cdbufferb); @@ -1534,6 +1728,8 @@ void cdrom_buf_free(uint8_t id) void cdrom_command(uint8_t id, uint8_t *cdb) { + cdrom_t *dev = cdrom[id]; + uint32_t len; int msf; int pos=0; @@ -1560,14 +1756,14 @@ void cdrom_command(uint8_t id, uint8_t *cdb) if (cdrom_drives[id].bus_type == CDROM_BUS_SCSI) { BufLen = &SCSIDevices[cdrom_drives[id].scsi_device_id][cdrom_drives[id].scsi_device_lun].BufferLength; - cdrom[id].status &= ~ERR_STAT; + dev->status &= ~ERR_STAT; } else { BufLen = &blen; - cdrom[id].error = 0; + dev->error = 0; } - cdrom[id].packet_len = 0; - cdrom[id].request_pos = 0; + dev->packet_len = 0; + dev->request_pos = 0; device_identify[7] = id + 0x30; @@ -1576,15 +1772,15 @@ void cdrom_command(uint8_t id, uint8_t *cdb) device_identify_ex[12] = EMU_VERSION[2]; device_identify_ex[13] = EMU_VERSION[3]; - cdrom[id].data_pos = 0; + dev->data_pos = 0; - memcpy(cdrom[id].current_cdb, cdb, cdrom[id].cdb_len); + memcpy(dev->current_cdb, cdb, dev->cdb_len); - cdrom[id].cd_status = cdrom_drives[id].handler->status(id); + dev->cd_status = cdrom_drives[id].handler->status(id); if (cdb[0] != 0) { - cdrom_log("CD-ROM %i: Command 0x%02X, Sense Key %02X, Asc %02X, Ascq %02X, Unit attention: %i\n", id, cdb[0], cdrom_sense_key, cdrom_asc, cdrom_ascq, cdrom[id].unit_attention); - cdrom_log("CD-ROM %i: Request length: %04X\n", id, cdrom[id].request_length); + cdrom_log("CD-ROM %i: Command 0x%02X, Sense Key %02X, Asc %02X, Ascq %02X, Unit attention: %i\n", id, cdb[0], cdrom_sense_key, cdrom_asc, cdrom_ascq, dev->unit_attention); + cdrom_log("CD-ROM %i: Request length: %04X\n", id, dev->request_length); cdrom_log("CD-ROM %i: CDB: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", id, cdb[0], cdb[1], cdb[2], cdb[3], cdb[4], cdb[5], cdb[6], cdb[7], @@ -1592,7 +1788,7 @@ void cdrom_command(uint8_t id, uint8_t *cdb) } msf = cdb[1] & 2; - cdrom[id].sector_len = 0; + dev->sector_len = 0; cdrom_set_phase(id, SCSI_PHASE_STATUS); @@ -1609,7 +1805,8 @@ void cdrom_command(uint8_t id, uint8_t *cdb) case GPCMD_REZERO_UNIT: if (cdrom_drives[id].handler->stop) cdrom_drives[id].handler->stop(id); - cdrom[id].sector_pos = cdrom[id].sector_len = 0; + dev->sector_pos = dev->sector_len = 0; + dev->seek_diff = dev->seek_pos; cdrom_seek(id, 0); cdrom_set_phase(id, SCSI_PHASE_STATUS); break; @@ -1627,6 +1824,12 @@ void cdrom_command(uint8_t id, uint8_t *cdb) case GPCMD_SET_SPEED: case GPCMD_SET_SPEED_ALT: + len = (cdb[3] | (cdb[2] << 8)) / 176; + dev->cur_speed = cdrom_speed_idx(len); + if (dev->cur_speed < 1) + dev->cur_speed = 0; + else if (dev->cur_speed > cdrom_drives[id].speed_idx) + dev->cur_speed = cdrom_drives[id].speed_idx; cdrom_set_phase(id, SCSI_PHASE_STATUS); cdrom_command_complete(id); break; @@ -1646,7 +1849,7 @@ void cdrom_command(uint8_t id, uint8_t *cdb) break; case GPCMD_READ_TOC_PMA_ATIP: - cdrom[id].toctimes++; + dev->toctimes++; cdrom_set_phase(id, SCSI_PHASE_DATA_IN); @@ -1657,7 +1860,7 @@ void cdrom_command(uint8_t id, uint8_t *cdb) cdrom_buf_alloc(id, 65536); if (cdrom_drives[id].handler->pass_through) { - ret = cdrom_pass_through(id, &len, cdrom[id].current_cdb, cdbufferb); + ret = cdrom_pass_through(id, &len, dev->current_cdb, cdbufferb); if (!ret) { cdrom_sense_key = cdrom_asc = cdrom_ascq = 0; goto cdrom_readtoc_fallback; @@ -1737,7 +1940,7 @@ cdrom_readtoc_fallback: return; case GPCMD_READ_CD_OLD: - cdrom[id].current_cdb[0] = 0xbe; /* IMPORTANT: Convert the command to new read CD for pass through purposes. */ + dev->current_cdb[0] = 0xbe; /* IMPORTANT: Convert the command to new read CD for pass through purposes. */ case GPCMD_READ_6: case GPCMD_READ_10: case GPCMD_READ_12: @@ -1748,59 +1951,59 @@ cdrom_readtoc_fallback: switch(cdb[0]) { case GPCMD_READ_6: - cdrom[id].sector_len = cdb[4]; - cdrom[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]); msf = 0; break; case GPCMD_READ_10: - cdrom[id].sector_len = (cdb[7] << 8) | cdb[8]; - cdrom[id].sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - cdrom_log("CD-ROM %i: Length: %i, LBA: %i\n", id, cdrom[id].sector_len, cdrom[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]; + cdrom_log("CD-ROM %i: Length: %i, LBA: %i\n", id, dev->sector_len, dev->sector_pos); msf = 0; break; case GPCMD_READ_12: - cdrom[id].sector_len = (((uint32_t) cdb[6]) << 24) | (((uint32_t) cdb[7]) << 16) | (((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]); - cdrom[id].sector_pos = (((uint32_t) cdb[2]) << 24) | (((uint32_t) cdb[3]) << 16) | (((uint32_t) cdb[4]) << 8) | ((uint32_t) cdb[5]); - cdrom_log("CD-ROM %i: Length: %i, LBA: %i\n", id, cdrom[id].sector_len, cdrom[id].sector_pos); + 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]); + cdrom_log("CD-ROM %i: Length: %i, LBA: %i\n", id, dev->sector_len, dev->sector_pos); msf = 0; break; case GPCMD_READ_CD_MSF: /* cdrom_log("CD-ROM %i: Read CD MSF: Start MSF %02X%02X%02X End MSF %02X%02X%02X Flags %02X\n", id, cdb[3], cdb[4], cdb[5], cdb[6], cdb[7], cdb[8], cdb[9]); */ alloc_length = 2856; - cdrom[id].sector_len = MSFtoLBA(cdb[6], cdb[7], cdb[8]); - cdrom[id].sector_pos = MSFtoLBA(cdb[3], cdb[4], cdb[5]); + dev->sector_len = MSFtoLBA(cdb[6], cdb[7], cdb[8]); + dev->sector_pos = MSFtoLBA(cdb[3], cdb[4], cdb[5]); - cdrom[id].sector_len -= cdrom[id].sector_pos; - cdrom[id].sector_len++; + dev->sector_len -= dev->sector_pos; + dev->sector_len++; msf = 1; break; case GPCMD_READ_CD_OLD: case GPCMD_READ_CD: /* cdrom_log("CD-ROM %i: Read CD: Start LBA %02X%02X%02X%02X Length %02X%02X%02X Flags %02X\n", id, cdb[2], cdb[3], cdb[4], cdb[5], cdb[6], cdb[7], cdb[8], cdb[9]); */ alloc_length = 2856; - cdrom[id].sector_len = (cdb[6] << 16) | (cdb[7] << 8) | cdb[8]; - cdrom[id].sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; + dev->sector_len = (cdb[6] << 16) | (cdb[7] << 8) | cdb[8]; + dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; msf = 0; break; } - if (!cdrom[id].sector_len) { + if (!dev->sector_len) { cdrom_set_phase(id, SCSI_PHASE_STATUS); /* cdrom_log("CD-ROM %i: All done - callback set\n", id); */ - cdrom[id].packet_status = CDROM_PHASE_COMPLETE; - cdrom[id].callback = 20LL * CDROM_TIME; + dev->packet_status = CDROM_PHASE_COMPLETE; + dev->callback = 20LL * CDROM_TIME; cdrom_set_callback(id); break; } - max_len = cdrom[id].sector_len; - cdrom[id].requested_blocks = max_len; /* If we're reading all blocks in one go for DMA, why not also for PIO, it should NOT + max_len = dev->sector_len; + dev->requested_blocks = max_len; /* If we're reading all blocks in one go for DMA, why not also for PIO, it should NOT matter anyway, this step should be identical and only the way the read dat is transferred to the host should be different. */ - cdrom[id].packet_len = max_len * alloc_length; - cdrom_buf_alloc(id, cdrom[id].packet_len); + dev->packet_len = max_len * alloc_length; + cdrom_buf_alloc(id, dev->packet_len); ret = cdrom_read_blocks(id, &alloc_length, 1); if (ret <= 0) { @@ -1808,15 +2011,15 @@ cdrom_readtoc_fallback: return; } - cdrom[id].requested_blocks = max_len; - cdrom[id].packet_len = alloc_length; + dev->requested_blocks = max_len; + dev->packet_len = alloc_length; - cdrom_set_buf_len(id, BufLen, &cdrom[id].packet_len); + cdrom_set_buf_len(id, BufLen, &dev->packet_len); - cdrom_data_command_finish(id, alloc_length, alloc_length / cdrom[id].requested_blocks, alloc_length, 0); + cdrom_data_command_finish(id, alloc_length, alloc_length / dev->requested_blocks, alloc_length, 0); - cdrom[id].all_blocks_total = cdrom[id].block_total; - if (cdrom[id].packet_status != CDROM_PHASE_COMPLETE) + dev->all_blocks_total = dev->block_total; + if (dev->packet_status != CDROM_PHASE_COMPLETE) ui_sb_update_icon(SB_CDROM | id, 1); else ui_sb_update_icon(SB_CDROM | id, 0); @@ -1829,18 +2032,18 @@ cdrom_readtoc_fallback: cdrom_buf_alloc(id, 8); if (cdrom_drives[id].handler->pass_through) { - ret = cdrom_pass_through(id, &len, cdrom[id].current_cdb, cdbufferb); + ret = cdrom_pass_through(id, &len, dev->current_cdb, cdbufferb); if (!ret) { cdrom_buf_free(id); return; } } else { - cdrom[id].sector_len = 1; - cdrom[id].sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4]<<8) | cdb[5]; + dev->sector_len = 1; + dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4]<<8) | cdb[5]; if (msf) - real_pos = cdrom_lba_to_msf_accurate(cdrom[id].sector_pos); + real_pos = cdrom_lba_to_msf_accurate(dev->sector_pos); else - real_pos = cdrom[id].sector_pos; + real_pos = dev->sector_pos; cdbufferb[0] = 1; /*2048 bytes user data*/ cdbufferb[1] = cdbufferb[2] = cdbufferb[3] = 0; cdbufferb[4] = (real_pos >> 24); @@ -1875,9 +2078,9 @@ cdrom_readtoc_fallback: cdrom_buf_alloc(id, 65536); } - cdrom[id].current_page_code = cdb[2] & 0x3F; + dev->current_page_code = cdb[2] & 0x3F; - if (!(cdrom_mode_sense_page_flags & (1LL << cdrom[id].current_page_code))) { + if (!(cdrom_mode_sense_page_flags & (1LL << dev->current_page_code))) { cdrom_invalid_field(id); cdrom_buf_free(id); return; @@ -1926,10 +2129,10 @@ cdrom_readtoc_fallback: cdrom_set_buf_len(id, BufLen, &len); - cdrom[id].total_length = len; - cdrom[id].do_page_save = cdb[1] & 1; + dev->total_length = len; + dev->do_page_save = cdb[1] & 1; - cdrom[id].current_page_pos = 0; + dev->current_page_pos = 0; cdrom_data_command_finish(id, len, len, len, 1); return; @@ -2075,7 +2278,7 @@ cdrom_readtoc_fallback: if (gesn_cdb->class & (1 << GESN_MEDIA)) { gesn_event_header->notification_class |= GESN_MEDIA; - cdbufferb[4] = cdrom[id].media_status; /* Bits 7-4 = Reserved, Bits 4-1 = Media Status */ + cdbufferb[4] = dev->media_status; /* Bits 7-4 = Reserved, Bits 4-1 = Media Status */ cdbufferb[5] = 1; /* Power Status (1 = Active) */ cdbufferb[6] = 0; cdbufferb[7] = 0; @@ -2103,7 +2306,7 @@ cdrom_readtoc_fallback: cdrom_buf_alloc(id, 65536); if (cdrom_drives[id].handler->pass_through) { - ret = cdrom_pass_through(id, &len, cdrom[id].current_cdb, cdbufferb); + ret = cdrom_pass_through(id, &len, dev->current_cdb, cdbufferb); if (!ret) { cdrom_buf_free(id); return; @@ -2146,7 +2349,7 @@ cdrom_readtoc_fallback: track |= (uint32_t) cdb[5]; if (cdrom_drives[id].handler->pass_through) { - ret = cdrom_pass_through(id, &len, cdrom[id].current_cdb, cdbufferb); + ret = cdrom_pass_through(id, &len, dev->current_cdb, cdbufferb); if (!ret) { cdrom_buf_free(id); return; @@ -2224,7 +2427,7 @@ cdrom_readtoc_fallback: if (!cdrom_drives[id].handler->is_track_audio) break; - if ((cdrom_drives[id].host_drive < 1) || (cdrom[id].cd_status <= CD_STATUS_DATA_ONLY) || !cdrom_drives[id].handler->is_track_audio(id, pos, msf)) { + if ((cdrom_drives[id].host_drive < 1) || (dev->cd_status <= CD_STATUS_DATA_ONLY) || !cdrom_drives[id].handler->is_track_audio(id, pos, msf)) { cdrom_illegal_mode(id); break; } @@ -2251,12 +2454,12 @@ cdrom_readtoc_fallback: cdrom_log("CD-ROM %i: Getting page %i (%s)\n", id, cdb[3], msf ? "MSF" : "LBA"); if ((cdrom_drives[id].handler->pass_through) && (cdb[3] != 1)) { - ret = cdrom_pass_through(id, &len, cdrom[id].current_cdb, cdbufferb); + ret = cdrom_pass_through(id, &len, dev->current_cdb, cdbufferb); if (!ret) { cdrom_buf_free(id); return; } - switch(cdrom[id].cd_status) { + switch(dev->cd_status) { case CD_STATUS_PLAYING: cdbufferb[1] = 0x11; break; @@ -2313,7 +2516,7 @@ cdrom_readtoc_fallback: cdbufferb[pos++] = cdb[3] & 3; /*Format code*/ if (cdb[3] == 1) { cdbufferb[1] = cdrom_drives[id].handler->getcurrentsubchannel(id, &cdbufferb[5], msf); - switch(cdrom[id].cd_status) { + switch(dev->cd_status) { case CD_STATUS_PLAYING: cdbufferb[1] = 0x11; break; @@ -2348,7 +2551,7 @@ cdrom_readtoc_fallback: cdrom_buf_alloc(id, alloc_length); if (cdrom_drives[id].handler->pass_through) { - ret = cdrom_pass_through(id, &len, cdrom[id].current_cdb, cdbufferb); + ret = cdrom_pass_through(id, &len, dev->current_cdb, cdbufferb); if (!ret) { cdrom_buf_free(id); return; @@ -2550,6 +2753,7 @@ atapi_out: pos = (cdb[2] << 24) | (cdb[3]<<16) | (cdb[4]<<8) | cdb[5]; break; } + dev->seek_diff = ABS((int) (pos - dev->seek_pos)); cdrom_seek(id, pos); cdrom_command_complete(id); break; @@ -2559,7 +2763,7 @@ atapi_out: cdrom_buf_alloc(id, 8); - if (cdrom_read_capacity(id, cdrom[id].current_cdb, cdbufferb, &len) == 0) { + if (cdrom_read_capacity(id, dev->current_cdb, cdbufferb, &len) == 0) { cdrom_buf_free(id); return; } @@ -2586,7 +2790,7 @@ atapi_out: break; } - /* cdrom_log("CD-ROM %i: Phase: %02X, request length: %i\n", cdrom[id].phase, cdrom[id].request_length); */ + /* cdrom_log("CD-ROM %i: Phase: %02X, request length: %i\n", dev->phase, dev->request_length); */ if (cdrom_atapi_phase_to_scsi(id) == SCSI_PHASE_STATUS) cdrom_buf_free(id); @@ -2595,6 +2799,7 @@ atapi_out: /* The command second phase function, needed for Mode Select. */ uint8_t cdrom_phase_data_out(uint8_t id) { + cdrom_t *dev = cdrom[id]; uint16_t block_desc_len; uint16_t pos; @@ -2607,20 +2812,20 @@ uint8_t cdrom_phase_data_out(uint8_t id) FILE *f; - switch(cdrom[id].current_cdb[0]) { + switch(dev->current_cdb[0]) { case GPCMD_MODE_SELECT_6: case GPCMD_MODE_SELECT_10: f = nvr_fopen(L"modeselect.bin", L"wb"); - fwrite(cdbufferb, 1, cdrom[id].total_length, f); + fwrite(cdbufferb, 1, dev->total_length, f); fclose(f); - if (cdrom[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 (cdrom_drives[id].bus_type == CDROM_BUS_SCSI) { - if (cdrom[id].current_cdb[0] == GPCMD_MODE_SELECT_6) { + if (dev->current_cdb[0] == GPCMD_MODE_SELECT_6) { block_desc_len = cdbufferb[2]; block_desc_len <<= 8; block_desc_len |= cdbufferb[3]; @@ -2665,10 +2870,10 @@ uint8_t cdrom_phase_data_out(uint8_t id) val = cdrom_mode_sense_pages_default_scsi.pages[page][0] & 0x80; else val = cdrom_mode_sense_pages_default.pages[page][0] & 0x80; - if (cdrom[id].do_page_save && val) + if (dev->do_page_save && val) cdrom_mode_sense_save(id); - if (pos >= cdrom[id].total_length) + if (pos >= dev->total_length) break; } @@ -2685,6 +2890,7 @@ uint8_t cdrom_phase_data_out(uint8_t id) /* This is the general ATAPI PIO request function. */ void cdrom_pio_request(uint8_t id, uint8_t out) { + cdrom_t *dev = cdrom[id]; int old_pos = 0; int ret = 0; @@ -2693,12 +2899,12 @@ void cdrom_pio_request(uint8_t id, uint8_t out) ide_irq_lower(&(ide_drives[cdrom_drives[id].ide_channel])); } - cdrom[id].status = BUSY_STAT; + dev->status = BUSY_STAT; - if (cdrom[id].pos >= cdrom[id].packet_len) { - cdrom_log("CD-ROM %i: %i bytes %s, command done\n", id, cdrom[id].pos, out ? "written" : "read"); + if (dev->pos >= dev->packet_len) { + cdrom_log("CD-ROM %i: %i bytes %s, command done\n", id, dev->pos, out ? "written" : "read"); - cdrom[id].pos = cdrom[id].request_pos = 0; + dev->pos = dev->request_pos = 0; if (out) { ret = cdrom_phase_data_out(id); /* If ret = 0 (phase 1 error), then we do not do anything else other than @@ -2710,22 +2916,22 @@ void cdrom_pio_request(uint8_t id, uint8_t out) cdrom_command_complete(id); cdrom_buf_free(id); } else { - cdrom_log("CD-ROM %i: %i bytes %s, %i bytes are still left\n", id, cdrom[id].pos, out ? "written" : "read", cdrom[id].packet_len - cdrom[id].pos); + cdrom_log("CD-ROM %i: %i bytes %s, %i bytes are still left\n", id, dev->pos, out ? "written" : "read", dev->packet_len - dev->pos); /* Make sure to keep pos, and reset request_pos to 0. */ /* Also make sure to not reset total_read. */ /* If less than (packet length) bytes are remaining, update packet length accordingly. */ - if ((cdrom[id].packet_len - cdrom[id].pos) < (cdrom[id].max_transfer_len)) - cdrom[id].max_transfer_len = cdrom[id].packet_len - cdrom[id].pos; - cdrom_log("CD-ROM %i: Packet length %i, request length %i\n", id, cdrom[id].packet_len, cdrom[id].max_transfer_len); + if ((dev->packet_len - dev->pos) < (dev->max_transfer_len)) + dev->max_transfer_len = dev->packet_len - dev->pos; + cdrom_log("CD-ROM %i: Packet length %i, request length %i\n", id, dev->packet_len, dev->max_transfer_len); - old_pos = cdrom[id].pos; - cdrom[id].packet_status = out ? CDROM_PHASE_DATA_OUT : CDROM_PHASE_DATA_IN; + old_pos = dev->pos; + dev->packet_status = out ? CDROM_PHASE_DATA_OUT : CDROM_PHASE_DATA_IN; cdrom_command_common(id); - cdrom[id].pos = old_pos; - cdrom[id].request_pos = 0; + dev->pos = old_pos; + dev->request_pos = 0; } } @@ -2734,12 +2940,14 @@ void cdrom_phase_callback(uint8_t id); int cdrom_read_from_ide_dma(uint8_t channel) { uint8_t id = atapi_cdrom_drives[channel]; + cdrom_t *dev; if (id > CDROM_NUM) return 0; + dev = cdrom[id]; if (ide_bus_master_write) { - if (ide_bus_master_write(channel >> 1, cdbufferb, cdrom[id].packet_len)) + if (ide_bus_master_write(channel >> 1, cdbufferb, dev->packet_len)) return 0; else return 1; @@ -2759,10 +2967,12 @@ int cdrom_read_from_scsi_dma(uint8_t scsi_id, uint8_t scsi_lun) { uint8_t id = scsi_cdrom_drives[scsi_id][scsi_lun]; int32_t *BufLen = &SCSIDevices[scsi_id][scsi_lun].BufferLength; + cdrom_t *dev; if (id > CDROM_NUM) return 0; + 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); return 1; @@ -2770,6 +2980,7 @@ int cdrom_read_from_scsi_dma(uint8_t scsi_id, uint8_t scsi_lun) int cdrom_read_from_dma(uint8_t id) { + cdrom_t *dev = cdrom[id]; int32_t *BufLen = &SCSIDevices[cdrom_drives[id].scsi_device_id][cdrom_drives[id].scsi_device_lun].BufferLength; int ret = 0; @@ -2785,15 +2996,15 @@ int cdrom_read_from_dma(uint8_t id) if (cdrom_drives[id].bus_type == CDROM_BUS_SCSI) cdrom_log("CD-ROM %i: SCSI Input data length: %i\n", id, *BufLen); else - cdrom_log("CD-ROM %i: ATAPI Input data length: %i\n", id, cdrom[id].packet_len); + cdrom_log("CD-ROM %i: ATAPI Input data length: %i\n", id, dev->packet_len); ret = cdrom_phase_data_out(id); if (ret || (cdrom_drives[id].bus_type == CDROM_BUS_SCSI)) { cdrom_buf_free(id); - cdrom[id].packet_status = CDROM_PHASE_COMPLETE; - cdrom[id].status = READY_STAT; - cdrom[id].phase = 3; + dev->packet_status = CDROM_PHASE_COMPLETE; + dev->status = READY_STAT; + dev->phase = 3; ui_sb_update_icon(SB_CDROM | id, 0); cdrom_irq_raise(id); if (ret) @@ -2807,12 +3018,14 @@ int cdrom_read_from_dma(uint8_t id) int cdrom_write_to_ide_dma(uint8_t channel) { uint8_t id = atapi_cdrom_drives[channel]; + cdrom_t *dev; if (id > CDROM_NUM) return 0; + dev = cdrom[id]; if (ide_bus_master_read) { - if (ide_bus_master_read(channel >> 1, cdbufferb, cdrom[id].packet_len)) + if (ide_bus_master_read(channel >> 1, cdbufferb, dev->packet_len)) return 0; else return 1; @@ -2825,10 +3038,12 @@ int cdrom_write_to_scsi_dma(uint8_t scsi_id, uint8_t scsi_lun) { uint8_t id = scsi_cdrom_drives[scsi_id][scsi_lun]; int32_t *BufLen = &SCSIDevices[scsi_id][scsi_lun].BufferLength; + cdrom_t *dev; if (id > CDROM_NUM) return 0; + 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); 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]); @@ -2838,6 +3053,7 @@ int cdrom_write_to_scsi_dma(uint8_t scsi_id, uint8_t scsi_lun) int cdrom_write_to_dma(uint8_t id) { + cdrom_t *dev = cdrom[id]; int ret = 0; if (cdrom_drives[id].bus_type == CDROM_BUS_SCSI) { @@ -2848,9 +3064,9 @@ int cdrom_write_to_dma(uint8_t id) if (ret || (cdrom_drives[id].bus_type == CDROM_BUS_SCSI)) { cdrom_buf_free(id); - cdrom[id].packet_status = CDROM_PHASE_COMPLETE; - cdrom[id].status = READY_STAT; - cdrom[id].phase = 3; + dev->packet_status = CDROM_PHASE_COMPLETE; + dev->status = READY_STAT; + dev->phase = 3; ui_sb_update_icon(SB_CDROM | id, 0); cdrom_irq_raise(id); if (ret) @@ -2864,31 +3080,33 @@ int cdrom_write_to_dma(uint8_t id) /* If the result is 1, issue an IRQ, otherwise not. */ void cdrom_phase_callback(uint8_t id) { - switch(cdrom[id].packet_status) { + cdrom_t *dev = cdrom[id]; + + switch(dev->packet_status) { case CDROM_PHASE_IDLE: cdrom_log("CD-ROM %i: CDROM_PHASE_IDLE\n", id); - cdrom[id].pos=0; - cdrom[id].phase = 1; - cdrom[id].status = READY_STAT | DRQ_STAT | (cdrom[id].status & ERR_STAT); + 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", id); - cdrom[id].status = BUSY_STAT | (cdrom[id].status &ERR_STAT); - memcpy(cdrom[id].atapi_cdb, cdbufferb, cdrom[id].cdb_len); - cdrom_command(id, cdrom[id].atapi_cdb); + dev->status = BUSY_STAT | (dev->status &ERR_STAT); + memcpy(dev->atapi_cdb, cdbufferb, dev->cdb_len); + cdrom_command(id, dev->atapi_cdb); return; case CDROM_PHASE_COMPLETE: cdrom_log("CD-ROM %i: CDROM_PHASE_COMPLETE\n", id); - cdrom[id].status = READY_STAT; - cdrom[id].phase = 3; - cdrom[id].packet_status = 0xFF; + dev->status = READY_STAT; + dev->phase = 3; + dev->packet_status = 0xFF; ui_sb_update_icon(SB_CDROM | id, 0); cdrom_irq_raise(id); return; case CDROM_PHASE_DATA_OUT: cdrom_log("CD-ROM %i: CDROM_PHASE_DATA_OUT\n", id); - cdrom[id].status = READY_STAT | DRQ_STAT | (cdrom[id].status & ERR_STAT); - cdrom[id].phase = 0; + dev->status = READY_STAT | DRQ_STAT | (dev->status & ERR_STAT); + dev->phase = 0; cdrom_irq_raise(id); return; case CDROM_PHASE_DATA_OUT_DMA: @@ -2897,8 +3115,8 @@ void cdrom_phase_callback(uint8_t id) return; case CDROM_PHASE_DATA_IN: cdrom_log("CD-ROM %i: CDROM_PHASE_DATA_IN\n", id); - cdrom[id].status = READY_STAT | DRQ_STAT | (cdrom[id].status & ERR_STAT); - cdrom[id].phase = 2; + dev->status = READY_STAT | DRQ_STAT | (dev->status & ERR_STAT); + dev->phase = 2; cdrom_irq_raise(id); return; case CDROM_PHASE_DATA_IN_DMA: @@ -2907,8 +3125,8 @@ void cdrom_phase_callback(uint8_t id) return; case CDROM_PHASE_ERROR: cdrom_log("CD-ROM %i: CDROM_PHASE_ERROR\n", id); - cdrom[id].status = READY_STAT | ERR_STAT; - cdrom[id].phase = 3; + dev->status = READY_STAT | ERR_STAT; + dev->phase = 3; cdrom_irq_raise(id); ui_sb_update_icon(SB_CDROM | id, 0); return; @@ -2920,14 +3138,15 @@ uint32_t cdrom_read(uint8_t channel, int length) { uint16_t *cdbufferw; uint32_t *cdbufferl; + uint32_t temp = 0; + cdrom_t *dev; uint8_t id = atapi_cdrom_drives[channel]; - uint32_t temp = 0; - if (id > CDROM_NUM) return 0; + dev = cdrom[id]; cdbufferw = (uint16_t *) cdbufferb; cdbufferl = (uint32_t *) cdbufferb; @@ -2939,34 +3158,34 @@ uint32_t cdrom_read(uint8_t channel, int length) (which is 1 sector = 2048 bytes). */ switch(length) { case 1: - temp = (cdrom[id].pos < cdrom[id].packet_len) ? cdbufferb[cdrom[id].pos] : 0; - cdrom[id].pos++; - cdrom[id].request_pos++; + temp = (dev->pos < dev->packet_len) ? cdbufferb[dev->pos] : 0; + dev->pos++; + dev->request_pos++; break; case 2: - temp = (cdrom[id].pos < cdrom[id].packet_len) ? cdbufferw[cdrom[id].pos >> 1] : 0; - cdrom[id].pos += 2; - cdrom[id].request_pos += 2; + temp = (dev->pos < dev->packet_len) ? cdbufferw[dev->pos >> 1] : 0; + dev->pos += 2; + dev->request_pos += 2; break; case 4: - temp = (cdrom[id].pos < cdrom[id].packet_len) ? cdbufferl[cdrom[id].pos >> 2] : 0; - cdrom[id].pos += 4; - cdrom[id].request_pos += 4; + temp = (dev->pos < dev->packet_len) ? cdbufferl[dev->pos >> 2] : 0; + dev->pos += 4; + dev->request_pos += 4; break; default: return 0; } - if (cdrom[id].packet_status == CDROM_PHASE_DATA_IN) { - if ((cdrom[id].request_pos >= cdrom[id].max_transfer_len) || (cdrom[id].pos >= cdrom[id].packet_len)) { + if (dev->packet_status == CDROM_PHASE_DATA_IN) { + 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(id, 0); } - // cdrom_log("CD-ROM %i: Returning: %02X (buffer position: %i, request position: %i)\n", id, temp, cdrom[id].pos, cdrom[id].request_pos); + // 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, cdrom[id].pos, cdrom[id].request_pos); + // cdrom_log("CD-ROM %i: Returning zero (buffer position: %i, request position: %i)\n", id, dev->pos, dev->request_pos); return 0; } } @@ -2976,15 +3195,17 @@ void cdrom_write(uint8_t channel, uint32_t val, int length) { uint16_t *cdbufferw; uint32_t *cdbufferl; + cdrom_t *dev; uint8_t id = atapi_cdrom_drives[channel]; if (id > CDROM_NUM) return; - if (cdrom[id].packet_status == CDROM_PHASE_IDLE) { + dev = cdrom[id]; + if (dev->packet_status == CDROM_PHASE_IDLE) { if (!cdbufferb) - cdrom_buf_alloc(id, cdrom[id].cdb_len); + cdrom_buf_alloc(id, dev->cdb_len); } cdbufferw = (uint16_t *) cdbufferb; @@ -2995,35 +3216,35 @@ void cdrom_write(uint8_t channel, uint32_t val, int length) switch(length) { case 1: - cdbufferb[cdrom[id].pos] = val & 0xff; - cdrom[id].pos++; - cdrom[id].request_pos++; + cdbufferb[dev->pos] = val & 0xff; + dev->pos++; + dev->request_pos++; break; case 2: - cdbufferw[cdrom[id].pos >> 1] = val & 0xffff; - cdrom[id].pos += 2; - cdrom[id].request_pos += 2; + cdbufferw[dev->pos >> 1] = val & 0xffff; + dev->pos += 2; + dev->request_pos += 2; break; case 4: - cdbufferl[cdrom[id].pos >> 2] = val; - cdrom[id].pos += 4; - cdrom[id].request_pos += 4; + cdbufferl[dev->pos >> 2] = val; + dev->pos += 4; + dev->request_pos += 4; break; default: return; } - if (cdrom[id].packet_status == CDROM_PHASE_DATA_OUT) { - if ((cdrom[id].request_pos >= cdrom[id].max_transfer_len) || (cdrom[id].pos >= cdrom[id].packet_len)) { + 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. */ cdrom_pio_request(id, 1); } return; - } else if (cdrom[id].packet_status == CDROM_PHASE_IDLE) { - if (cdrom[id].pos >= (uint32_t)cdrom[id].cdb_len) { - cdrom[id].pos=0; - cdrom[id].status = BUSY_STAT; - cdrom[id].packet_status = CDROM_PHASE_COMMAND; + } else if (dev->packet_status == CDROM_PHASE_IDLE) { + if (dev->pos >= (uint32_t)dev->cdb_len) { + dev->pos=0; + dev->status = BUSY_STAT; + dev->packet_status = CDROM_PHASE_COMMAND; timer_process(); cdrom_phase_callback(id); timer_update_outstanding(); @@ -3032,21 +3253,6 @@ void cdrom_write(uint8_t channel, uint32_t val, int length) } } -void cdrom_hard_reset(void) -{ - int i = 0; - - for (i=0; i= 'A') && (cdrom_drives[i].host_drive <= 'Z')) - ioctl_reset(i); - - cdrom_mode_sense_load(i); - } -} - - /* Peform a master init on the entire module. */ void cdrom_global_init(void) @@ -3067,21 +3273,32 @@ cdrom_global_init(void) void -cdrom_global_reset(void) +cdrom_hard_reset(void) { int c; + cdrom_destroy_drives(); + for (c=0; c='A') && (cdrom_drives[c].host_drive <= 'Z')) - ioctl_open(c, cdrom_drives[c].host_drive); - else - cdrom_null_open(c, cdrom_drives[c].host_drive); + if (cdrom_drives[c].host_drive == 200) { + image_open(c, cdrom_image[c].image_path); + image_reset(c); + } else if ((cdrom_drives[c].host_drive>='A') && (cdrom_drives[c].host_drive <= 'Z')) { + ioctl_open(c, cdrom_drives[c].host_drive); + ioctl_reset(c); + } else + cdrom_null_open(c, cdrom_drives[c].host_drive); + } + + cdrom_mode_sense_load(c); } } diff --git a/src/cdrom/cdrom.h b/src/cdrom/cdrom.h index 466ba9e..f866bf7 100644 --- a/src/cdrom/cdrom.h +++ b/src/cdrom/cdrom.h @@ -8,7 +8,7 @@ * * Definitions for the CDROM module.. * - * Version: @(#)cdrom.h 1.0.5 2018/03/17 + * Version: @(#)cdrom.h 1.0.7 2018/03/20 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -45,6 +45,9 @@ extern "C" { #define CDROM_NUM 4 +#define CDROM_SPEED_DEFAULT 8 + + #define CD_STATUS_EMPTY 0 #define CD_STATUS_DATA_ONLY 1 #define CD_STATUS_PLAYING 2 @@ -145,6 +148,7 @@ typedef struct { int callback; int data_pos; + uint32_t seek_diff; int cdb_len_setting; int cdb_len; @@ -174,6 +178,22 @@ typedef struct { int init_length; int16_t cd_buffer[BUF_SIZE]; + + uint8_t rcbuf[16]; + uint8_t sub_q_data_format[16]; + uint8_t sub_q_channel_data[256]; + int last_subchannel_pos; + + uint32_t cd_end; + uint32_t cdrom_capacity; + + int cd_buflen; + int cd_state; + + int handler_inited; + int disc_changed; + + int cur_speed; } cdrom_t; typedef struct { @@ -196,58 +216,44 @@ typedef struct { unsigned int sound_on; unsigned int atapi_dma; - uint8_t speed; + uint8_t speed_idx; /* index into table */ } cdrom_drive_t; typedef struct { int image_is_iso; - - uint32_t last_block; - uint32_t cdrom_capacity; - int image_inited; wchar_t image_path[1024]; - wchar_t prev_image_path[1024]; + wchar_t *prev_image_path; FILE* image; - int image_changed; - - int cd_state; - uint32_t cd_pos; - uint32_t cd_end; - int cd_buflen; } cdrom_image_t; typedef struct { - uint32_t last_block; - uint32_t cdrom_capacity; - int ioctl_inited; char ioctl_path[8]; - int tocvalid; - int cd_state; - uint32_t cd_end; - int16_t cd_buffer[BUF_SIZE]; - int cd_buflen; int actual_requested_blocks; int last_track_pos; int last_track_nr; int capacity_read; - uint8_t rcbuf[16]; - uint8_t sub_q_data_format[16]; - uint8_t sub_q_channel_data[256]; - int last_subchannel_pos; } cdrom_ioctl_t; +typedef struct { + int8_t speed; + double seek1; + double seek2; +} cdrom_speed_t; -extern cdrom_t cdrom[CDROM_NUM]; + +extern const cdrom_speed_t cdrom_speeds[]; + +extern cdrom_t *cdrom[CDROM_NUM]; extern cdrom_drive_t cdrom_drives[CDROM_NUM]; -extern uint8_t atapi_cdrom_drives[8]; -extern uint8_t scsi_cdrom_drives[16][8]; extern cdrom_image_t cdrom_image[CDROM_NUM]; extern cdrom_ioctl_t cdrom_ioctl[CDROM_NUM]; +extern uint8_t atapi_cdrom_drives[8]; +extern uint8_t scsi_cdrom_drives[16][8]; -#define cdrom_sense_error cdrom[id].sense[0] -#define cdrom_sense_key cdrom[id].sense[2] -#define cdrom_asc cdrom[id].sense[12] -#define cdrom_ascq cdrom[id].sense[13] +#define cdrom_sense_error cdrom[id]->sense[0] +#define cdrom_sense_key cdrom[id]->sense[2] +#define cdrom_asc cdrom[id]->sense[12] +#define cdrom_ascq cdrom[id]->sense[13] #define cdrom_drive cdrom_drives[id].host_drive extern int (*ide_bus_master_read)(int channel, uint8_t *data, int transfer_length); @@ -255,6 +261,8 @@ extern int (*ide_bus_master_write)(int channel, uint8_t *data, int transfer_leng extern void (*ide_bus_master_set_irq)(int channel); extern void ioctl_close(uint8_t id); +extern int cdrom_speed_idx(int realspeed); + extern uint32_t cdrom_mode_sense_get_channel(uint8_t id, int channel); extern uint32_t cdrom_mode_sense_get_volume(uint8_t id, int channel); extern void build_atapi_cdrom_map(void); @@ -267,6 +275,7 @@ extern uint32_t cdrom_read(uint8_t channel, int length); extern void cdrom_write(uint8_t channel, uint32_t val, int length); extern int cdrom_lba_to_msf_accurate(int lba); +extern void cdrom_destroy_drives(void); extern void cdrom_close(uint8_t id); extern void cdrom_reset(uint8_t id); @@ -274,6 +283,7 @@ extern void cdrom_set_signature(int id); extern void cdrom_request_sense_for_scsi(uint8_t id, uint8_t *buffer, uint8_t alloc_length); extern void cdrom_update_cdb(uint8_t *cdb, int lba_pos, int number_of_blocks); extern void cdrom_insert(uint8_t id); +extern void cdrom_new_image(uint8_t id); extern int find_cdrom_for_scsi_id(uint8_t scsi_id, uint8_t scsi_lun); extern int cdrom_read_capacity(uint8_t id, uint8_t *cdb, uint8_t *buffer, uint32_t *len); diff --git a/src/cdrom/cdrom_dosbox.cpp b/src/cdrom/cdrom_dosbox.cpp index 44c090f..e1a15e3 100644 --- a/src/cdrom/cdrom_dosbox.cpp +++ b/src/cdrom/cdrom_dosbox.cpp @@ -8,7 +8,7 @@ * * CD-ROM image file handling module. * - * Version: @(#)cdrom_dosbox.cpp 1.0.3 2018/03/09 + * Version: @(#)cdrom_dosbox.cpp 1.0.5 2018/03/19 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -79,33 +79,35 @@ CDROM_Interface_Image::BinaryFile::BinaryFile(const char *filename, bool &error) { memset(fn, 0, sizeof(fn)); strcpy(fn, filename); - error = false; + file = fopen64(fn, "rb"); + if (file == NULL) + error = true; + else + error = false; } CDROM_Interface_Image::BinaryFile::~BinaryFile() { + if (file != NULL) { + fclose(file); + file = NULL; + } memset(fn, 0, sizeof(fn)); } bool CDROM_Interface_Image::BinaryFile::read(Bit8u *buffer, uint64_t seek, size_t count) { - file = fopen64(fn, "rb"); if (file == NULL) return 0; fseeko64(file, seek, SEEK_SET); fread(buffer, 1, count, file); - fclose(file); return 1; } uint64_t CDROM_Interface_Image::BinaryFile::getLength() { - uint64_t ret = 0; - file = fopen64(fn, "rb"); if (file == NULL) return 0; fseeko64(file, 0, SEEK_END); - ret = ftello64(file); - fclose(file); - return ret; + return ftello64(file); } CDROM_Interface_Image::CDROM_Interface_Image() @@ -378,6 +380,7 @@ bool CDROM_Interface_Image::LoadCueSheet(char *cuefile) ifstream in; in.open(cuefile, ios::in); if (in.fail()) return false; + int last_attr = 0x00; while(!in.eof()) { // get next line @@ -448,7 +451,8 @@ bool CDROM_Interface_Image::LoadCueSheet(char *cuefile) track.attr = DATA_TRACK; track.mode2 = true; } else success = false; - + last_attr = track.attr; + canAddTrack = true; } else if (command == "INDEX") { @@ -456,7 +460,7 @@ bool CDROM_Interface_Image::LoadCueSheet(char *cuefile) line >> index; uint64_t frame; success = GetCueFrame(frame, line); - + if (index == 1) track.start = frame; else if (index == 0) prestart = frame; // ignore other indices @@ -500,7 +504,8 @@ bool CDROM_Interface_Image::LoadCueSheet(char *cuefile) track.number++; track.track_number = 0xAA; // track.attr = 0;//sync with load iso - track.attr = 0x16; /* Was 0x00 but I believe 0x16 is appropriate. */ + // track.attr = 0x16; /* Was 0x00 but I believe 0x16 is appropriate. */ + track.attr = last_attr | 0x02; track.start = 0; track.length = 0; track.file = NULL; diff --git a/src/cdrom/cdrom_image.cpp b/src/cdrom/cdrom_image.cpp index 8f7831a..2c6a568 100644 --- a/src/cdrom/cdrom_image.cpp +++ b/src/cdrom/cdrom_image.cpp @@ -8,7 +8,7 @@ * * CD-ROM image support. * - * Version: @(#)cdrom_image.cpp 1.0.4 2018/03/17 + * Version: @(#)cdrom_image.cpp 1.0.5 2018/03/18 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -98,51 +98,59 @@ void image_close(uint8_t id); void image_audio_callback(uint8_t id, int16_t *output, int len) { - if (!cdrom_drives[id].sound_on || (cdrom_image[id].cd_state != CD_PLAYING) || cdrom_image[id].image_is_iso) + cdrom_t *dev = cdrom[id]; + + return; /*FIXME: why? */ + + if (!cdrom_drives[id].sound_on || (dev->cd_state != CD_PLAYING) || cdrom_image[id].image_is_iso) { cdrom_image_log("image_audio_callback(i): Not playing\n", id); - if (cdrom_ioctl[id].cd_state == CD_PLAYING) + if (dev->cd_state == CD_PLAYING) { - cdrom[id].seek_pos += (len >> 11); + dev->seek_pos += (len >> 11); } memset(output, 0, len * 2); return; } - while (cdrom_image[id].cd_buflen < len) + while (dev->cd_buflen < len) { - if (cdrom[id].seek_pos < cdrom_image[id].cd_end) + if (dev->seek_pos < dev->cd_end) { - if (!cdimg[id]->ReadSector((unsigned char*)&cdrom[id].cd_buffer[cdrom_image[id].cd_buflen], true, cdrom[id].seek_pos)) + if (!cdimg[id]->ReadSector((unsigned char*)&dev->cd_buffer[dev->cd_buflen], true, dev->seek_pos)) { - memset(&cdrom[id].cd_buffer[cdrom_image[id].cd_buflen], 0, (BUF_SIZE - cdrom_image[id].cd_buflen) * 2); - cdrom_image[id].cd_state = CD_STOPPED; - cdrom_image[id].cd_buflen = len; + memset(&dev->cd_buffer[dev->cd_buflen], 0, (BUF_SIZE - dev->cd_buflen) * 2); + dev->cd_state = CD_STOPPED; + dev->cd_buflen = len; } else { - cdrom[id].seek_pos++; - cdrom_image[id].cd_buflen += (RAW_SECTOR_SIZE / 2); + dev->seek_pos++; + dev->cd_buflen += (RAW_SECTOR_SIZE / 2); } } else { - memset(&cdrom[id].cd_buffer[cdrom_image[id].cd_buflen], 0, (BUF_SIZE - cdrom_image[id].cd_buflen) * 2); - cdrom_image[id].cd_state = CD_STOPPED; - cdrom_image[id].cd_buflen = len; + memset(&dev->cd_buffer[dev->cd_buflen], 0, (BUF_SIZE - dev->cd_buflen) * 2); + dev->cd_state = CD_STOPPED; + dev->cd_buflen = len; } } - memcpy(output, cdrom[id].cd_buffer, len * 2); - memmove(cdrom[id].cd_buffer, &cdrom[id].cd_buffer[len], (BUF_SIZE - len) * 2); - cdrom_image[id].cd_buflen -= len; + memcpy(output, dev->cd_buffer, len * 2); + memmove(dev->cd_buffer, &dev->cd_buffer[len], (BUF_SIZE - len) * 2); + dev->cd_buflen -= len; } void image_audio_stop(uint8_t id) { - cdrom_image[id].cd_state = CD_STOPPED; + cdrom_t *dev = cdrom[id]; + + dev->cd_state = CD_STOPPED; } static void image_playaudio(uint8_t id, uint32_t pos, uint32_t len, int ismsf) { + cdrom_t *dev = cdrom[id]; + if (!cdimg[id]) return; int number; unsigned char attr; @@ -152,8 +160,8 @@ static void image_playaudio(uint8_t id, uint32_t pos, uint32_t len, int ismsf) if (attr == DATA_TRACK) { cdrom_image_log("Can't play data track\n"); - cdrom[id].seek_pos = 0; - cdrom_image[id].cd_state = CD_STOPPED; + dev->seek_pos = 0; + dev->cd_state = CD_STOPPED; return; } cdrom_image_log("Play audio - %08X %08X %i\n", pos, len, ismsf); @@ -173,7 +181,7 @@ static void image_playaudio(uint8_t id, uint32_t pos, uint32_t len, int ismsf) if (pos == 0xffffff) { cdrom_image_log("Playing from current position (MSF)\n"); - pos = cdrom[id].seek_pos; + pos = dev->seek_pos; } else { @@ -192,34 +200,40 @@ static void image_playaudio(uint8_t id, uint32_t pos, uint32_t len, int ismsf) if (pos == 0xffffffff) { cdrom_image_log("Playing from current position\n"); - pos = cdrom[id].seek_pos; + pos = dev->seek_pos; } len += pos; } - cdrom[id].seek_pos = pos; - cdrom_image[id].cd_end = len; - cdrom_image[id].cd_state = CD_PLAYING; - cdrom_image[id].cd_buflen = 0; + dev->seek_pos = pos; + dev->cd_end = len; + dev->cd_state = CD_PLAYING; + dev->cd_buflen = 0; } static void image_pause(uint8_t id) { + cdrom_t *dev = cdrom[id]; + if (!cdimg[id] || cdrom_image[id].image_is_iso) return; - if (cdrom_image[id].cd_state == CD_PLAYING) - cdrom_image[id].cd_state = CD_PAUSED; + if (dev->cd_state == CD_PLAYING) + dev->cd_state = CD_PAUSED; } static void image_resume(uint8_t id) { + cdrom_t *dev = cdrom[id]; + if (!cdimg[id] || cdrom_image[id].image_is_iso) return; - if (cdrom_image[id].cd_state == CD_PAUSED) - cdrom_image[id].cd_state = CD_PLAYING; + if (dev->cd_state == CD_PAUSED) + dev->cd_state = CD_PLAYING; } static void image_stop(uint8_t id) { + cdrom_t *dev = cdrom[id]; + if (!cdimg[id] || cdrom_image[id].image_is_iso) return; - cdrom_image[id].cd_state = CD_STOPPED; + dev->cd_state = CD_STOPPED; } static int image_ready(uint8_t id) @@ -235,12 +249,6 @@ static int image_ready(uint8_t id) return 1; } - if (cdrom_image[id].image_changed) - { - cdrom_image[id].image_changed = 0; - return 1; - } - return 1; } @@ -285,22 +293,18 @@ static int image_medium_changed(uint8_t id) return 1; } - if (cdrom_image[id].image_changed) - { - cdrom_image[id].image_changed = 0; - return 1; - } - return 0; } static uint8_t image_getcurrentsubchannel(uint8_t id, uint8_t *b, int msf) { - if (!cdimg[id]) return 0; + cdrom_t *dev = cdrom[id]; uint8_t ret; int pos=0; - uint32_t cdpos = cdrom[id].seek_pos; + if (!cdimg[id]) return 0; + + uint32_t cdpos = dev->seek_pos; TMSF relPos, absPos; unsigned char attr, track, index; cdimg[id]->GetAudioSub(cdpos, attr, track, index, relPos, absPos); @@ -311,9 +315,9 @@ static uint8_t image_getcurrentsubchannel(uint8_t id, uint8_t *b, int msf) } else { - if (cdrom_image[id].cd_state == CD_PLAYING) + if (dev->cd_state == CD_PLAYING) ret = 0x11; - else if (cdrom_image[id].cd_state == CD_PAUSED) + else if (dev->cd_state == CD_PAUSED) ret = 0x12; else ret = 0x13; @@ -856,7 +860,9 @@ read_mode2_xa_form2: static uint32_t image_size(uint8_t id) { - return cdrom_image[id].cdrom_capacity; + cdrom_t *dev = cdrom[id]; + + return dev->cdrom_capacity; } static int image_readtoc(uint8_t id, unsigned char *b, unsigned char starttrack, int msf, int maxlen, int single) @@ -990,10 +996,8 @@ static int image_readtoc_raw(uint8_t id, unsigned char *b, int maxlen) cdimg[id]->GetAudioTracks(first_track, last_track, tmsf); - if (maxlen >= 3) b[2] = first_track; - if (maxlen >= 4) b[3] = last_track; - - if (maxlen <= 4) return len; + b[2] = first_track; + b[3] = last_track; for (track = first_track; track <= last_track; track++) { @@ -1033,11 +1037,13 @@ static int image_readtoc_raw(uint8_t id, unsigned char *b, int maxlen) static int image_status(uint8_t id) { + cdrom_t *dev = cdrom[id]; + if (!cdimg[id]) return CD_STATUS_EMPTY; if (cdrom_image[id].image_is_iso) return CD_STATUS_DATA_ONLY; if (cdimg[id]->HasAudioTracks()) { - switch(cdrom_image[id].cd_state) + switch(dev->cd_state) { case CD_PLAYING: return CD_STATUS_PLAYING; @@ -1058,7 +1064,9 @@ void image_reset(UNUSED(uint8_t id)) void image_close(uint8_t id) { - cdrom_image[id].cd_state = CD_STOPPED; + cdrom_t *dev = cdrom[id]; + + dev->cd_state = CD_STOPPED; if (cdimg[id]) { delete cdimg[id]; @@ -1071,18 +1079,9 @@ static char afn[1024]; int image_open(uint8_t id, wchar_t *fn) { - if (wcscmp(fn, cdrom_image[id].image_path) != 0) - { - cdrom_image[id].image_changed = 1; - } + cdrom_t *dev = cdrom[id]; - /* Make sure image_changed stays when changing from an image to another image. */ - if (!cdrom_image[id].image_inited && (cdrom_drives[id].host_drive != 200)) cdrom_image[id].image_changed = 0; - - if (!cdrom_image[id].image_inited || cdrom_image[id].image_changed) - { - wcscpy(cdrom_image[id].image_path, fn); - } + wcscpy(cdrom_image[id].image_path, fn); if (! wcscasecmp(plat_get_extension(fn), L"ISO")) { @@ -1094,6 +1093,7 @@ int image_open(uint8_t id, wchar_t *fn) } cdimg[id] = new CDROM_Interface_Image(); + memset(afn, 0, sizeof(afn)); wcstombs(afn, fn, sizeof(afn)); if (!cdimg[id]->SetDevice(afn, false)) { @@ -1101,24 +1101,20 @@ int image_open(uint8_t id, wchar_t *fn) cdrom_set_null_handler(id); return 1; } - cdrom_image[id].cd_state = CD_STOPPED; - cdrom[id].seek_pos = 0; - cdrom_image[id].cd_buflen = 0; - cdrom_image[id].cdrom_capacity = image_get_last_block(id, 0, 0, 4096, 0) + 1; + dev->cd_state = CD_STOPPED; + dev->seek_pos = 0; + dev->cd_buflen = 0; + dev->cdrom_capacity = image_get_last_block(id, 0, 0, 4096, 0) + 1; cdrom_drives[id].handler = &image_cdrom; - if (!cdrom_image[id].image_inited || cdrom_image[id].image_changed) - { - if (!cdrom_image[id].image_inited) - cdrom_image[id].image_inited = 1; - } - return 0; } static void image_exit(uint8_t id) { - cdrom_image[id].image_inited = 0; + cdrom_t *dev = cdrom[id]; + + dev->handler_inited = 0; } /* TODO: Check for what data type a mixed CD is. */ diff --git a/src/config.c b/src/config.c index c940496..5fe5add 100644 --- a/src/config.c +++ b/src/config.c @@ -12,7 +12,7 @@ * it on Windows XP, and possibly also Vista. Use the * -DANSI_CFG for use on these systems. * - * Version: @(#)config.c 1.0.5 2018/03/15 + * Version: @(#)config.c 1.0.7 2018/03/20 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -580,7 +580,7 @@ load_input_devices(void) else mouse_type = 0; - joystick_type = config_get_int(cat, "joystick_type", 7); + joystick_type = config_get_int(cat, "joystick_type", 0); for (c=0; cname); if (devices[c]->close != NULL) devices[c]->close(device_priv[c]); devices[c] = device_priv[c] = NULL; diff --git a/src/disk/hdc.c b/src/disk/hdc.c index 946df71..2fb47a7 100644 --- a/src/disk/hdc.c +++ b/src/disk/hdc.c @@ -8,7 +8,7 @@ * * Common code to handle all sorts of disk controllers. * - * Version: @(#)hdc.c 1.0.2 2018/03/15 + * Version: @(#)hdc.c 1.0.3 2018/03/18 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -42,6 +42,7 @@ #include "../machine/machine.h" #include "../device.h" #include "hdc.h" +#include "hdc_ide.h" char *hdc_name; /* configured HDC name */ @@ -176,6 +177,15 @@ hdc_reset(void) /* If we have a valid controller, add its device. */ if (hdc_current > 1) device_add(controllers[hdc_current].device); + + /* Reconfire and reset the IDE layer. */ + ide_ter_disable(); + ide_qua_disable(); + if (ide_enable[2]) + ide_ter_init(); + if (ide_enable[3]) + ide_qua_init(); + ide_reset_hard(); } @@ -212,10 +222,3 @@ hdc_available(int hdc) { return(device_available(controllers[hdc].device)); } - - -int -hdc_current_is_mfm(void) -{ - return(controllers[hdc_current].is_mfm); -} diff --git a/src/disk/hdc.h b/src/disk/hdc.h index b888fd0..b996127 100644 --- a/src/disk/hdc.h +++ b/src/disk/hdc.h @@ -79,7 +79,6 @@ extern char *hdc_get_internal_name(int hdc); extern const device_t *hdc_get_device(int hdc); extern int hdc_get_flags(int hdc); extern int hdc_available(int hdc); -extern int hdc_current_is_mfm(void); #endif /*EMU_HDC_H*/ diff --git a/src/disk/hdc_ide.c b/src/disk/hdc_ide.c index cd9c015..cecbe2c 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.10 2018/03/17 + * Version: @(#)hdc_ide.c 1.0.11 2018/03/18 * * Authors: Miran Grca, * Sarah Walker, @@ -66,16 +66,16 @@ /* Bits of 'atastat' */ -#define ERR_STAT 0x01 -#define DRQ_STAT 0x08 /* Data request */ -#define DSC_STAT 0x10 -#define SERVICE_STAT 0x10 -#define READY_STAT 0x40 -#define BUSY_STAT 0x80 +#define ERR_STAT 0x01 +#define DRQ_STAT 0x08 /* Data request */ +#define DSC_STAT 0x10 +#define SERVICE_STAT 0x10 +#define READY_STAT 0x40 +#define BUSY_STAT 0x80 /* Bits of 'error' */ -#define ABRT_ERR 0x04 /* Command aborted */ -#define MCR_ERR 0x08 /* Media change request */ +#define ABRT_ERR 0x04 /* Command aborted */ +#define MCR_ERR 0x08 /* Media change request */ /* ATA Commands */ #define WIN_NOP 0x00 @@ -92,31 +92,32 @@ #define WIN_SEEK 0x70 #define WIN_DRIVE_DIAGNOSTICS 0x90 /* Execute Drive Diagnostics */ #define WIN_SPECIFY 0x91 /* Initialize Drive Parameters */ -#define WIN_PACKETCMD 0xA0 /* Send a packet command. */ -#define WIN_PIDENTIFY 0xA1 /* Identify ATAPI device */ -#define WIN_READ_MULTIPLE 0xC4 -#define WIN_WRITE_MULTIPLE 0xC5 -#define WIN_SET_MULTIPLE_MODE 0xC6 -#define WIN_READ_DMA 0xC8 -#define WIN_READ_DMA_ALT 0xC9 -#define WIN_WRITE_DMA 0xCA -#define WIN_WRITE_DMA_ALT 0xCB -#define WIN_STANDBYNOW1 0xE0 -#define WIN_IDLENOW1 0xE1 -#define WIN_SETIDLE1 0xE3 -#define WIN_CHECKPOWERMODE1 0xE5 -#define WIN_SLEEP1 0xE6 -#define WIN_IDENTIFY 0xEC /* Ask drive to identify itself */ -#define WIN_SET_FEATURES 0xEF -#define WIN_READ_NATIVE_MAX 0xF8 +#define WIN_PACKETCMD 0xa0 /* Send a packet command. */ +#define WIN_PIDENTIFY 0xa1 /* Identify ATAPI device */ +#define WIN_READ_MULTIPLE 0xc4 +#define WIN_WRITE_MULTIPLE 0xc5 +#define WIN_SET_MULTIPLE_MODE 0xc6 +#define WIN_READ_DMA 0xc8 +#define WIN_READ_DMA_ALT 0xc9 +#define WIN_WRITE_DMA 0xca +#define WIN_WRITE_DMA_ALT 0xcb +#define WIN_STANDBYNOW1 0xe0 +#define WIN_IDLENOW1 0xe1 +#define WIN_SETIDLE1 0xe3 +#define WIN_CHECKPOWERMODE1 0xe5 +#define WIN_SLEEP1 0xe6 +#define WIN_IDENTIFY 0xec /* Ask drive to identify itself */ +#define WIN_SET_FEATURES 0xef +#define WIN_READ_NATIVE_MAX 0xf8 + +#define FEATURE_SET_TRANSFER_MODE 0x03 +#define FEATURE_ENABLE_IRQ_OVERLAPPED 0x5d +#define FEATURE_ENABLE_IRQ_SERVICE 0x5e +#define FEATURE_DISABLE_REVERT 0x66 +#define FEATURE_ENABLE_REVERT 0xcc +#define FEATURE_DISABLE_IRQ_OVERLAPPED 0xdd +#define FEATURE_DISABLE_IRQ_SERVICE 0xde -#define FEATURE_SET_TRANSFER_MODE 0x03 -#define FEATURE_ENABLE_IRQ_OVERLAPPED 0x5d -#define FEATURE_ENABLE_IRQ_SERVICE 0x5e -#define FEATURE_DISABLE_REVERT 0x66 -#define FEATURE_ENABLE_REVERT 0xcc -#define FEATURE_DISABLE_IRQ_OVERLAPPED 0xdd -#define FEATURE_DISABLE_IRQ_SERVICE 0xde enum { @@ -658,8 +659,8 @@ void ide_set_signature(IDE *ide) else if (ide_drive_is_cdrom(ide)) { cdrom_set_signature(cdrom_id); - ide->secount = cdrom[cdrom_id].phase; - ide->cylinder = cdrom[cdrom_id].request_length; + ide->secount = cdrom[cdrom_id]->phase; + ide->cylinder = cdrom[cdrom_id]->request_length; } else { @@ -852,7 +853,7 @@ void ide_reset(void) } else if ((d < 8) && ide_drive_is_cdrom(&ide_drives[d])) { - cdrom[atapi_cdrom_drives[d]].status = READY_STAT | DSC_STAT; + cdrom[atapi_cdrom_drives[d]]->status = READY_STAT | DSC_STAT; } ide_drives[d].atastat = READY_STAT | DSC_STAT; ide_drives[d].service = 0; @@ -1053,7 +1054,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) else if (ide_drive_is_cdrom(ide)) { ide_log("ATAPI transfer mode: %s\n", (val & 1) ? "DMA" : "PIO"); - cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].features = val; + cdrom[atapi_cdrom_drives[cur_ide[ide_board]]]->features = val; } ide->cylprecomp = val; @@ -1063,7 +1064,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) } else if (ide_drive_is_cdrom(ide_other)) { - cdrom[atapi_cdrom_drives[cur_ide[ide_board] ^ 1]].features = val; + cdrom[atapi_cdrom_drives[cur_ide[ide_board] ^ 1]]->features = val; } ide_other->cylprecomp = val; return; @@ -1077,7 +1078,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) else if (ide_drive_is_cdrom(ide)) { ide_log("Sector count write: %i\n", val); - cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].phase = val; + cdrom[atapi_cdrom_drives[cur_ide[ide_board]]]->phase = val; } ide->secount = val; @@ -1089,7 +1090,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) else if (ide_drive_is_cdrom(ide_other)) { ide_log("Other sector count write: %i\n", val); - cdrom[atapi_cdrom_drives[cur_ide[ide_board] ^ 1]].phase = val; + cdrom[atapi_cdrom_drives[cur_ide[ide_board] ^ 1]]->phase = val; } ide_other->secount = val; return; @@ -1109,8 +1110,8 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) } else if (ide_drive_is_cdrom(ide)) { - cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].request_length &= 0xFF00; - cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].request_length |= val; + cdrom[atapi_cdrom_drives[cur_ide[ide_board]]]->request_length &= 0xFF00; + cdrom[atapi_cdrom_drives[cur_ide[ide_board]]]->request_length |= val; } ide->cylinder = (ide->cylinder & 0xFF00) | val; ide->lba_addr = (ide->lba_addr & 0xFFF00FF) | (val << 8); @@ -1122,8 +1123,8 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) } else if (ide_drive_is_cdrom(ide_other)) { - cdrom[atapi_cdrom_drives[cur_ide[ide_board] ^ 1]].request_length &= 0xFF00; - cdrom[atapi_cdrom_drives[cur_ide[ide_board] ^ 1]].request_length |= val; + cdrom[atapi_cdrom_drives[cur_ide[ide_board] ^ 1]]->request_length &= 0xFF00; + cdrom[atapi_cdrom_drives[cur_ide[ide_board] ^ 1]]->request_length |= val; } ide_other->cylinder = (ide_other->cylinder&0xFF00) | val; ide_other->lba_addr = (ide_other->lba_addr&0xFFF00FF) | (val << 8); @@ -1137,8 +1138,8 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) } else if (ide_drive_is_cdrom(ide)) { - cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].request_length &= 0xFF; - cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].request_length |= (val << 8); + cdrom[atapi_cdrom_drives[cur_ide[ide_board]]]->request_length &= 0xFF; + cdrom[atapi_cdrom_drives[cur_ide[ide_board]]]->request_length |= (val << 8); } ide->cylinder = (ide->cylinder & 0xFF) | (val << 8); ide->lba_addr = (ide->lba_addr & 0xF00FFFF) | (val << 16); @@ -1150,8 +1151,8 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) } else if (ide_drive_is_cdrom(ide_other)) { - cdrom[atapi_cdrom_drives[cur_ide[ide_board] ^ 1]].request_length &= 0xFF; - cdrom[atapi_cdrom_drives[cur_ide[ide_board] ^ 1]].request_length |= (val << 8); + cdrom[atapi_cdrom_drives[cur_ide[ide_board] ^ 1]]->request_length &= 0xFF; + cdrom[atapi_cdrom_drives[cur_ide[ide_board] ^ 1]]->request_length |= (val << 8); } ide_other->cylinder = (ide_other->cylinder & 0xFF) | (val << 8); ide_other->lba_addr = (ide_other->lba_addr & 0xF00FFFF) | (val << 16); @@ -1183,11 +1184,11 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) } else if (ide_drive_is_cdrom(ide)) { - cdrom[atapi_cdrom_drives[ide->channel]].status = READY_STAT | DSC_STAT; - cdrom[atapi_cdrom_drives[ide->channel]].error = 1; - cdrom[atapi_cdrom_drives[ide->channel]].phase = 1; - cdrom[atapi_cdrom_drives[ide->channel]].request_length = 0xEB14; - cdrom[atapi_cdrom_drives[ide->channel]].callback = 0LL; + cdrom[atapi_cdrom_drives[ide->channel]]->status = READY_STAT | DSC_STAT; + cdrom[atapi_cdrom_drives[ide->channel]]->error = 1; + cdrom[atapi_cdrom_drives[ide->channel]]->phase = 1; + cdrom[atapi_cdrom_drives[ide->channel]]->request_length = 0xEB14; + cdrom[atapi_cdrom_drives[ide->channel]]->callback = 0LL; ide->cylinder = 0xEB14; } @@ -1202,11 +1203,11 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) } else if (ide_drive_is_cdrom(ide_other)) { - cdrom[atapi_cdrom_drives[ide_other->channel]].status = READY_STAT | DSC_STAT; - cdrom[atapi_cdrom_drives[ide_other->channel]].error = 1; - cdrom[atapi_cdrom_drives[ide_other->channel]].phase = 1; - cdrom[atapi_cdrom_drives[ide_other->channel]].request_length = 0xEB14; - cdrom[atapi_cdrom_drives[ide_other->channel]].callback = 0LL; + cdrom[atapi_cdrom_drives[ide_other->channel]]->status = READY_STAT | DSC_STAT; + cdrom[atapi_cdrom_drives[ide_other->channel]]->error = 1; + cdrom[atapi_cdrom_drives[ide_other->channel]]->phase = 1; + cdrom[atapi_cdrom_drives[ide_other->channel]]->request_length = 0xEB14; + cdrom[atapi_cdrom_drives[ide_other->channel]]->callback = 0LL; ide->cylinder = 0xEB14; } @@ -1244,7 +1245,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) } else if (ide_drive_is_cdrom(ide)) { - cdrom[atapi_cdrom_drives[ide->channel]].error = 0; + cdrom[atapi_cdrom_drives[ide->channel]]->error = 0; } if (((val >= WIN_RESTORE) && (val <= 0x1F)) || ((val >= WIN_SEEK) && (val <= 0x7F))) { @@ -1254,7 +1255,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) } else if (ide_drive_is_cdrom(ide)) { - cdrom[atapi_cdrom_drives[ide->channel]].status = READY_STAT; + cdrom[atapi_cdrom_drives[ide->channel]]->status = READY_STAT; } else { @@ -1267,7 +1268,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) } if (ide_drive_is_cdrom(ide)) { - cdrom[atapi_cdrom_drives[ide->channel]].callback = 100LL*IDE_TIME; + cdrom[atapi_cdrom_drives[ide->channel]]->callback = 100LL*IDE_TIME; } idecallback[ide_board]=40000LL * TIMER_USEC /*100LL*IDE_TIME*/; timer_update_outstanding(); @@ -1282,7 +1283,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) } else if (ide_drive_is_cdrom(ide)) { - cdrom[atapi_cdrom_drives[ide->channel]].status = BUSY_STAT; + cdrom[atapi_cdrom_drives[ide->channel]]->status = BUSY_STAT; } else { @@ -1295,7 +1296,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) } else if (ide_drive_is_cdrom(ide)) { - cdrom[atapi_cdrom_drives[ide->channel]].callback = 100LL*IDE_TIME; + cdrom[atapi_cdrom_drives[ide->channel]]->callback = 100LL*IDE_TIME; } idecallback[ide_board]=100LL*IDE_TIME; timer_update_outstanding(); @@ -1319,7 +1320,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) } else if (ide_drive_is_cdrom(ide)) { - cdrom[atapi_cdrom_drives[ide->channel]].status = BUSY_STAT; + cdrom[atapi_cdrom_drives[ide->channel]]->status = BUSY_STAT; } else { @@ -1332,7 +1333,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) } else if (ide_drive_is_cdrom(ide)) { - cdrom[atapi_cdrom_drives[ide->channel]].callback = 200LL*IDE_TIME; + cdrom[atapi_cdrom_drives[ide->channel]]->callback = 200LL*IDE_TIME; } idecallback[ide_board]=200LL*IDE_TIME; timer_update_outstanding(); @@ -1355,8 +1356,8 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) } else if (ide_drive_is_cdrom(ide)) { - cdrom[atapi_cdrom_drives[ide->channel]].status = DRQ_STAT | DSC_STAT | READY_STAT; - cdrom[atapi_cdrom_drives[ide->channel]].pos = 0; + cdrom[atapi_cdrom_drives[ide->channel]]->status = DRQ_STAT | DSC_STAT | READY_STAT; + cdrom[atapi_cdrom_drives[ide->channel]]->pos = 0; } else { @@ -1373,7 +1374,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) } else if (ide_drive_is_cdrom(ide)) { - cdrom[atapi_cdrom_drives[ide->channel]].status = BUSY_STAT; + cdrom[atapi_cdrom_drives[ide->channel]]->status = BUSY_STAT; } else { @@ -1386,7 +1387,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) } else if (ide_drive_is_cdrom(ide)) { - cdrom[atapi_cdrom_drives[ide->channel]].callback = 200LL*IDE_TIME; + cdrom[atapi_cdrom_drives[ide->channel]]->callback = 200LL*IDE_TIME; } idecallback[ide_board]=200LL*IDE_TIME; timer_update_outstanding(); @@ -1400,7 +1401,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) } else if (ide_drive_is_cdrom(ide)) { - cdrom[atapi_cdrom_drives[ide->channel]].status = BUSY_STAT; + cdrom[atapi_cdrom_drives[ide->channel]]->status = BUSY_STAT; } else { @@ -1413,7 +1414,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) } else if (ide_drive_is_cdrom(ide)) { - cdrom[atapi_cdrom_drives[ide->channel]].callback = 200LL*IDE_TIME; + cdrom[atapi_cdrom_drives[ide->channel]]->callback = 200LL*IDE_TIME; } idecallback[ide_board]=200LL*IDE_TIME; timer_update_outstanding(); @@ -1438,7 +1439,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) } else if (ide_drive_is_cdrom(ide)) { - cdrom[atapi_cdrom_drives[ide->channel]].status = BUSY_STAT; + cdrom[atapi_cdrom_drives[ide->channel]]->status = BUSY_STAT; } else { @@ -1451,7 +1452,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) } else if (ide_drive_is_cdrom(ide)) { - cdrom[atapi_cdrom_drives[ide->channel]].callback = 30LL*IDE_TIME; + cdrom[atapi_cdrom_drives[ide->channel]]->callback = 30LL*IDE_TIME; } idecallback[ide_board]=30LL*IDE_TIME; timer_update_outstanding(); @@ -1461,14 +1462,14 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) if (ide_drive_is_zip(ide)) zip[atapi_zip_drives[ide->channel]].status = BUSY_STAT; else if (ide_drive_is_cdrom(ide)) - cdrom[atapi_cdrom_drives[ide->channel]].status = BUSY_STAT; + cdrom[atapi_cdrom_drives[ide->channel]]->status = BUSY_STAT; else ide->atastat = BUSY_STAT; if (ide_drive_is_zip(ide_other)) zip[atapi_zip_drives[ide_other->channel]].status = BUSY_STAT; else if (ide_drive_is_cdrom(ide_other)) - cdrom[atapi_cdrom_drives[ide_other->channel]].status = BUSY_STAT; + cdrom[atapi_cdrom_drives[ide_other->channel]]->status = BUSY_STAT; else ide_other->atastat = BUSY_STAT; @@ -1476,7 +1477,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) if (ide_drive_is_zip(ide)) zip[atapi_zip_drives[ide->channel]].callback = 200LL * IDE_TIME; else if (ide_drive_is_cdrom(ide)) - cdrom[atapi_cdrom_drives[ide->channel]].callback = 200LL * IDE_TIME; + cdrom[atapi_cdrom_drives[ide->channel]]->callback = 200LL * IDE_TIME; idecallback[ide_board] = 200LL * IDE_TIME; timer_update_outstanding(); return; @@ -1492,7 +1493,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) if (ide_drive_is_zip(ide)) zip[atapi_zip_drives[ide->channel]].status = BUSY_STAT; else if (ide_drive_is_cdrom(ide)) - cdrom[atapi_cdrom_drives[ide->channel]].status = BUSY_STAT; + cdrom[atapi_cdrom_drives[ide->channel]]->status = BUSY_STAT; else ide->atastat = BUSY_STAT; timer_process(); @@ -1509,7 +1510,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) } else if (ide_drive_is_cdrom(ide)) { - cdrom[atapi_cdrom_drives[ide->channel]].status = BUSY_STAT; + cdrom[atapi_cdrom_drives[ide->channel]]->status = BUSY_STAT; } else { @@ -1522,7 +1523,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) } else if (ide_drive_is_cdrom(ide)) { - cdrom[atapi_cdrom_drives[ide->channel]].callback = 200LL*IDE_TIME; + cdrom[atapi_cdrom_drives[ide->channel]]->callback = 200LL*IDE_TIME; } idecallback[ide_board]=200LL*IDE_TIME; timer_update_outstanding(); @@ -1535,14 +1536,14 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) zip[atapi_zip_drives[ide->channel]].packet_status = ZIP_PHASE_IDLE; zip[atapi_zip_drives[ide->channel]].pos=0; zip[atapi_zip_drives[ide->channel]].phase = 1; - zip[atapi_zip_drives[ide->channel]].status = READY_STAT | DRQ_STAT | (zip[cur_ide[ide_board]].status & ERR_STAT); + zip[atapi_zip_drives[ide->channel]].status = READY_STAT | DRQ_STAT | (zip[atapi_zip_drives[ide->channel]].status & ERR_STAT); } else if (ide_drive_is_cdrom(ide)) { - cdrom[atapi_cdrom_drives[ide->channel]].packet_status = CDROM_PHASE_IDLE; - cdrom[atapi_cdrom_drives[ide->channel]].pos=0; - cdrom[atapi_cdrom_drives[ide->channel]].phase = 1; - cdrom[atapi_cdrom_drives[ide->channel]].status = READY_STAT | DRQ_STAT | (cdrom[cur_ide[ide_board]].status & ERR_STAT); + cdrom[atapi_cdrom_drives[ide->channel]]->packet_status = CDROM_PHASE_IDLE; + cdrom[atapi_cdrom_drives[ide->channel]]->pos=0; + cdrom[atapi_cdrom_drives[ide->channel]]->phase = 1; + cdrom[atapi_cdrom_drives[ide->channel]]->status = READY_STAT | DRQ_STAT | (cdrom[atapi_cdrom_drives[ide->channel]]->status & ERR_STAT); } else { @@ -1564,8 +1565,8 @@ ide_bad_command: } else if (ide_drive_is_cdrom(ide)) { - cdrom[atapi_cdrom_drives[ide->channel]].status = READY_STAT | ERR_STAT | DSC_STAT; - cdrom[atapi_cdrom_drives[ide->channel]].error = ABRT_ERR; + cdrom[atapi_cdrom_drives[ide->channel]]->status = READY_STAT | ERR_STAT | DSC_STAT; + cdrom[atapi_cdrom_drives[ide->channel]]->error = ABRT_ERR; } else { @@ -1587,7 +1588,7 @@ ide_bad_command: } else if (ide_drive_is_cdrom(ide)) { - cdrom[atapi_cdrom_drives[ide->channel]].callback = 0LL; + cdrom[atapi_cdrom_drives[ide->channel]]->callback = 0LL; } idecallback[ide_board]=500LL*IDE_TIME; timer_update_outstanding(); @@ -1606,7 +1607,7 @@ ide_bad_command: } else if (ide_drive_is_cdrom(ide)) { - cdrom[atapi_cdrom_drives[ide->channel]].status = BUSY_STAT; + cdrom[atapi_cdrom_drives[ide->channel]]->status = BUSY_STAT; } ide->atastat = ide_other->atastat = BUSY_STAT; } @@ -1690,8 +1691,8 @@ uint32_t ide_read_data(int ide_board, int length) } else if (ide_drive_is_cdrom(ide)) { - cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].status = READY_STAT | DSC_STAT; - cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].packet_status = CDROM_PHASE_IDLE; + cdrom[atapi_cdrom_drives[cur_ide[ide_board]]]->status = READY_STAT | DSC_STAT; + cdrom[atapi_cdrom_drives[cur_ide[ide_board]]]->packet_status = CDROM_PHASE_IDLE; } if (ide->command == WIN_READ || ide->command == WIN_READ_NORETRY || ide->command == WIN_READ_MULTIPLE) { @@ -1753,7 +1754,7 @@ uint8_t readide(int ide_board, uint16_t addr) } else if (ide_drive_is_cdrom(ide)) { - temp = cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].error; + temp = cdrom[atapi_cdrom_drives[cur_ide[ide_board]]]->error; } else { @@ -1782,7 +1783,7 @@ uint8_t readide(int ide_board, uint16_t addr) } else if (ide_drive_is_cdrom(ide)) { - temp = cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].phase; + temp = cdrom[atapi_cdrom_drives[cur_ide[ide_board]]]->phase; } else { @@ -1807,7 +1808,7 @@ uint8_t readide(int ide_board, uint16_t addr) } else if (ide_drive_is_cdrom(ide)) { - temp = cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].request_length & 0xff; + temp = cdrom[atapi_cdrom_drives[cur_ide[ide_board]]]->request_length & 0xff; } else { @@ -1829,7 +1830,7 @@ uint8_t readide(int ide_board, uint16_t addr) } else if (ide_drive_is_cdrom(ide)) { - temp = cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].request_length >> 8; + temp = cdrom[atapi_cdrom_drives[cur_ide[ide_board]]]->request_length >> 8; } else { @@ -1858,7 +1859,7 @@ uint8_t readide(int ide_board, uint16_t addr) } else if (ide_drive_is_cdrom(ide)) { - temp = (cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].status & ~DSC_STAT) | (ide->service ? SERVICE_STAT : 0); + temp = (cdrom[atapi_cdrom_drives[cur_ide[ide_board]]]->status & ~DSC_STAT) | (ide->service ? SERVICE_STAT : 0); } else { @@ -1880,7 +1881,7 @@ uint8_t readide(int ide_board, uint16_t addr) } else if (ide_drive_is_cdrom(ide)) { - temp = (cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].status & ~DSC_STAT) | (ide->service ? SERVICE_STAT : 0); + temp = (cdrom[atapi_cdrom_drives[cur_ide[ide_board]]]->status & ~DSC_STAT) | (ide->service ? SERVICE_STAT : 0); } else { @@ -1962,10 +1963,10 @@ void callbackide(int ide_board) else if (ide_drive_is_cdrom(ide)) { cdrom_id = atapi_cdrom_drives[cur_ide[ide_board]]; - cdrom[cdrom_id].status = READY_STAT | DSC_STAT; - cdrom[cdrom_id].error = 1; - cdrom[cdrom_id].phase = 1; - cdrom[cdrom_id].request_length=0xEB14; + cdrom[cdrom_id]->status = READY_STAT | DSC_STAT; + cdrom[cdrom_id]->error = 1; + cdrom[cdrom_id]->phase = 1; + cdrom[cdrom_id]->request_length=0xEB14; ide->cylinder = 0xEB14; if (cdrom_drives[cdrom_id].handler->stop) { @@ -1988,10 +1989,10 @@ void callbackide(int ide_board) else if (ide_drive_is_cdrom(ide_other)) { cdrom_id_other = atapi_cdrom_drives[cur_ide[ide_board] ^ 1]; - cdrom[cdrom_id_other].status = READY_STAT | DSC_STAT; - cdrom[cdrom_id_other].error = 1; - cdrom[cdrom_id_other].phase = 1; - cdrom[cdrom_id_other].request_length=0xEB14; + cdrom[cdrom_id_other]->status = READY_STAT | DSC_STAT; + cdrom[cdrom_id_other]->error = 1; + cdrom[cdrom_id_other]->phase = 1; + cdrom[cdrom_id_other]->request_length=0xEB14; ide_other->cylinder = 0xEB14; if (cdrom_drives[cdrom_id_other].handler->stop) { @@ -2048,9 +2049,9 @@ void callbackide(int ide_board) } else if (ide_drive_is_cdrom(ide)) { - cdrom[cdrom_id].status = READY_STAT | DSC_STAT; - cdrom[cdrom_id].error = 1; - cdrom[cdrom_id].phase = 1; + cdrom[cdrom_id]->status = READY_STAT | DSC_STAT; + cdrom[cdrom_id]->error = 1; + cdrom[cdrom_id]->phase = 1; cdrom_reset(cdrom_id); } ide_irq_raise(ide); @@ -2070,7 +2071,7 @@ void callbackide(int ide_board) } else if (ide_drive_is_cdrom(ide)) { - cdrom[cdrom_id].status = READY_STAT | DSC_STAT; + cdrom[cdrom_id]->status = READY_STAT | DSC_STAT; } else { @@ -2088,8 +2089,8 @@ void callbackide(int ide_board) } else if (ide_drive_is_cdrom(ide)) { - cdrom[cdrom_id].phase = 0xFF; - cdrom[cdrom_id].status = READY_STAT | DSC_STAT; + cdrom[cdrom_id]->phase = 0xFF; + cdrom[cdrom_id]->status = READY_STAT | DSC_STAT; } ide->secount = 0xFF; ide->atastat = READY_STAT | DSC_STAT; @@ -2381,8 +2382,8 @@ void callbackide(int ide_board) } else if (ide_drive_is_cdrom(ide)) { - cdrom[cdrom_id].status = 0; - cdrom[cdrom_id].error = 1; + cdrom[cdrom_id]->status = 0; + cdrom[cdrom_id]->error = 1; ide_irq_raise(ide); } else @@ -2402,8 +2403,8 @@ void callbackide(int ide_board) } else if (ide_drive_is_cdrom(ide_other)) { - cdrom[cdrom_id_other].status = 0; - cdrom[cdrom_id_other].error = 1; + cdrom[cdrom_id_other]->status = 0; + cdrom[cdrom_id_other]->error = 1; } else { @@ -2446,10 +2447,10 @@ void callbackide(int ide_board) { ide_atapi_identify(ide); ide->pos = 0; - cdrom[cdrom_id].phase = 2; - cdrom[cdrom_id].pos = 0; - cdrom[cdrom_id].error = 0; - cdrom[cdrom_id].status = DRQ_STAT | READY_STAT | DSC_STAT; + cdrom[cdrom_id]->phase = 2; + cdrom[cdrom_id]->pos = 0; + cdrom[cdrom_id]->error = 0; + cdrom[cdrom_id]->status = DRQ_STAT | READY_STAT | DSC_STAT; ide_irq_raise(ide); return; } @@ -2482,8 +2483,8 @@ void callbackide(int ide_board) zip[zip_id].pos = 0; } else if (ide_drive_is_cdrom(ide)) { - cdrom[cdrom_id].status = READY_STAT | DSC_STAT; - cdrom[cdrom_id].pos = 0; + cdrom[cdrom_id]->status = READY_STAT | DSC_STAT; + cdrom[cdrom_id]->pos = 0; } ide->atastat = READY_STAT | DSC_STAT; ide_irq_raise(ide); @@ -2545,9 +2546,9 @@ abort_cmd: } else if (ide_drive_is_cdrom(ide)) { - cdrom[cdrom_id].status = READY_STAT | ERR_STAT | DSC_STAT; - cdrom[cdrom_id].error = ABRT_ERR; - cdrom[cdrom_id].pos = 0; + cdrom[cdrom_id]->status = READY_STAT | ERR_STAT | DSC_STAT; + cdrom[cdrom_id]->error = ABRT_ERR; + cdrom[cdrom_id]->pos = 0; } else { @@ -2888,7 +2889,7 @@ ide_sainit(const device_t *info) break; } - return((void *)info); + return(ide_drives); } diff --git a/src/disk/zip.c b/src/disk/zip.c index f072200..46c1ff2 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.5 2018/03/17 + * Version: @(#)zip.c 1.0.6 2018/03/18 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -973,13 +973,12 @@ static void zip_command_common(uint8_t id) bytes_per_second = 8333333.333333333333333; /* 8.3 MB/s PIO-2 speed */ } else bytes_per_second = 3333333.333333333333333; /* 3.3 MB/s PIO-0 speed */ - - } - period = 1000000.0 / bytes_per_second; - dusec = (double) TIMER_USEC; - dusec = dusec * period * (double) (zip[id].packet_len); - zip[id].callback = ((int64_t) dusec); + period = 1000000.0 / bytes_per_second; + dusec = (double) TIMER_USEC; + dusec = dusec * period * (double) (zip[id].packet_len); + zip[id].callback = ((int64_t) dusec); + } zip_set_callback(id); } @@ -2538,14 +2537,6 @@ void zip_write(uint8_t channel, uint32_t val, int length) } } -void zip_hard_reset(void) -{ - int i = 0; - - for (i=0; i * @@ -217,7 +217,6 @@ 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 void zip_global_init(void); -extern void zip_global_reset(void); extern void zip_hard_reset(void); extern int zip_load(uint8_t id, wchar_t *fn); diff --git a/src/emu.h b/src/emu.h index 6dabe77..eac2883 100644 --- a/src/emu.h +++ b/src/emu.h @@ -8,7 +8,7 @@ * * Main include file for the application. * - * Version: @(#)emu.h 1.0.7 2018/03/15 + * Version: @(#)emu.h 1.0.9 2018/03/19 * * Author: Fred N. van Kempen, * @@ -81,6 +81,7 @@ #endif #define MIN(a, b) ((a) < (b) ? (a) : (b)) +#define ABS(x) ((x) > 0 ? (x) : -(x)) #ifdef __cplusplus @@ -132,6 +133,7 @@ extern int sound_is_float, /* (C) sound uses FP values */ GUS, /* (C) sound option */ SSI2001, /* (C) sound option */ voodoo_enabled; /* (C) video option */ +extern int joystick_type; /* (C) joystick type */ extern int mem_size; /* (C) memory size */ extern int cpu_manufacturer, /* (C) cpu manufacturer */ cpu, /* (C) cpu type */ diff --git a/src/floppy/fdd.c b/src/floppy/fdd.c index 1e1ba16..4515172 100644 --- a/src/floppy/fdd.c +++ b/src/floppy/fdd.c @@ -8,7 +8,7 @@ * * Implementation of the floppy drive emulation. * - * Version: @(#)fdd.c 1.0.5 2018/03/16 + * Version: @(#)fdd.c 1.0.6 2018/03/19 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -58,75 +58,63 @@ #include "fdc.h" -extern int driveempty[4]; +/* FIXME: these should be compined. */ +DRIVE drives[FDD_NUM]; +wchar_t floppyfns[4][512]; +int fdd_cur_track[FDD_NUM]; +int writeprot[FDD_NUM], fwriteprot[FDD_NUM]; +int64_t fdd_poll_time[FDD_NUM] = { 16LL, 16LL, 16LL, 16LL }; +int drive_type[FDD_NUM]; +int drive_empty[FDD_NUM] = {1, 1, 1, 1}; +int fdd_changed[FDD_NUM]; +int64_t motoron[FDD_NUM]; +d86f_handler_t d86f_handler[FDD_NUM]; -wchar_t floppyfns[4][512]; +int defaultwriteprot = 0; +int curdrive = 0; +int motorspin; +int fdc_indexcount = 52; -int64_t fdd_poll_time[FDD_NUM] = { 16LL, 16LL, 16LL, 16LL }; +static fdc_t *fdd_fdc; -int fdd_cur_track[FDD_NUM]; -int writeprot[FDD_NUM], fwriteprot[FDD_NUM]; -DRIVE drives[FDD_NUM]; -int drive_type[FDD_NUM]; - -int curdrive = 0; - -int defaultwriteprot = 0; - -int fdc_ready; - -int drive_empty[FDD_NUM] = {1, 1, 1, 1}; -int fdd_changed[FDD_NUM]; - -int motorspin; -int64_t motoron[FDD_NUM]; - -int fdc_indexcount = 52; - -fdc_t *fdd_fdc; - -d86f_handler_t d86f_handler[FDD_NUM]; - -static const struct -{ - wchar_t *ext; - void (*load)(int drive, wchar_t *fn); - void (*close)(int drive); - int size; -} loaders[]= -{ - {L"001", img_load, img_close, -1}, - {L"002", img_load, img_close, -1}, - {L"003", img_load, img_close, -1}, - {L"004", img_load, img_close, -1}, - {L"005", img_load, img_close, -1}, - {L"006", img_load, img_close, -1}, - {L"007", img_load, img_close, -1}, - {L"008", img_load, img_close, -1}, - {L"009", img_load, img_close, -1}, - {L"010", img_load, img_close, -1}, - {L"12", img_load, img_close, -1}, - {L"144", img_load, img_close, -1}, - {L"360", img_load, img_close, -1}, - {L"720", img_load, img_close, -1}, - {L"86F", d86f_load, d86f_close, -1}, - {L"BIN", img_load, img_close, -1}, - {L"CQ", img_load, img_close, -1}, - {L"CQM", img_load, img_close, -1}, - {L"DSK", img_load, img_close, -1}, - {L"FDI", fdi_load, fdi_close, -1}, - {L"FDF", img_load, img_close, -1}, - {L"FLP", img_load, img_close, -1}, - {L"HDM", img_load, img_close, -1}, - {L"IMA", img_load, img_close, -1}, - {L"IMD", imd_load, imd_close, -1}, - {L"IMG", img_load, img_close, -1}, - {L"JSON", json_load, json_close, -1}, - {L"TD0", td0_load, td0_close, -1}, - {L"VFD", img_load, img_close, -1}, - {L"XDF", img_load, img_close, -1}, - {0,0,0} +static const struct { + wchar_t *ext; + void (*load)(int drive, wchar_t *fn); + void (*close)(int drive); + int size; +} loaders[]= { + { L"001", img_load, img_close, -1 }, + { L"002", img_load, img_close, -1 }, + { L"003", img_load, img_close, -1 }, + { L"004", img_load, img_close, -1 }, + { L"005", img_load, img_close, -1 }, + { L"006", img_load, img_close, -1 }, + { L"007", img_load, img_close, -1 }, + { L"008", img_load, img_close, -1 }, + { L"009", img_load, img_close, -1 }, + { L"010", img_load, img_close, -1 }, + { L"12", img_load, img_close, -1 }, + { L"144", img_load, img_close, -1 }, + { L"360", img_load, img_close, -1 }, + { L"720", img_load, img_close, -1 }, + { L"86F", d86f_load, d86f_close, -1 }, + { L"BIN", img_load, img_close, -1 }, + { L"CQ", img_load, img_close, -1 }, + { L"CQM", img_load, img_close, -1 }, + { L"DSK", img_load, img_close, -1 }, + { L"FDI", fdi_load, fdi_close, -1 }, + { L"FDF", img_load, img_close, -1 }, + { L"FLP", img_load, img_close, -1 }, + { L"HDM", img_load, img_close, -1 }, + { L"IMA", img_load, img_close, -1 }, + { L"IMD", imd_load, imd_close, -1 }, + { L"IMG", img_load, img_close, -1 }, + { L"JSON", json_load, json_close, -1 }, + { L"TD0", td0_load, td0_close, -1 }, + { L"VFD", img_load, img_close, -1 }, + { L"XDF", img_load, img_close, -1 }, + { NULL, NULL, NULL, -1 } }; static int driveloaders[4]; @@ -707,22 +695,3 @@ void fdd_set_fdc(void *fdc) { fdd_fdc = (fdc_t *) fdc; } - -void fdd_init(void) -{ - drives[0].poll = drives[1].poll = drives[2].poll = drives[3].poll = 0; - drives[0].seek = drives[1].seek = drives[2].seek = drives[3].seek = 0; - drives[0].readsector = drives[1].readsector = drives[2].readsector = drives[3].readsector = 0; - fdd_reset(); - - img_init(); - d86f_init(); - td0_init(); - imd_init(); - json_init(); - - fdd_load(0, floppyfns[0]); - fdd_load(1, floppyfns[1]); - fdd_load(2, floppyfns[2]); - fdd_load(3, floppyfns[3]); -} diff --git a/src/floppy/fdd.h b/src/floppy/fdd.h index 7610cee..9cf7fda 100644 --- a/src/floppy/fdd.h +++ b/src/floppy/fdd.h @@ -8,7 +8,7 @@ * * Definitions for the floppy drive emulation. * - * Version: @(#)fdd.h 1.0.3 2018/03/17 + * Version: @(#)fdd.h 1.0.4 2018/03/19 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -48,6 +48,33 @@ extern "C" { #endif +typedef struct { + void (*seek)(int drive, int track); + void (*readsector)(int drive, int sector, int track, int side, + int density, int sector_size); + void (*writesector)(int drive, int sector, int track, int side, + int density, int sector_size); + void (*comparesector)(int drive, int sector, int track, int side, + int density, int sector_size); + void (*readaddress)(int drive, int side, int density); + void (*format)(int drive, int side, int density, uint8_t fill); + int (*hole)(int drive); + double (*byteperiod)(int drive); + void (*stop)(int drive); + void (*poll)(int drive); +} DRIVE; + + +extern DRIVE drives[FDD_NUM]; +extern wchar_t floppyfns[FDD_NUM][512]; +extern int driveempty[FDD_NUM]; +extern int64_t fdd_poll_time[FDD_NUM]; +extern int ui_writeprot[FDD_NUM]; + +extern int fdd_time; +extern int64_t floppytime; + + extern int fdd_swap; @@ -84,35 +111,6 @@ extern int fdd_get_from_internal_name(char *s); extern int fdd_current_track(int drive); -typedef struct { - void (*seek)(int drive, int track); - void (*readsector)(int drive, int sector, int track, int side, - int density, int sector_size); - void (*writesector)(int drive, int sector, int track, int side, - int density, int sector_size); - void (*comparesector)(int drive, int sector, int track, int side, - int density, int sector_size); - void (*readaddress)(int drive, int side, int density); - void (*format)(int drive, int side, int density, uint8_t fill); - int (*hole)(int drive); - double (*byteperiod)(int drive); - void (*stop)(int drive); - void (*poll)(int drive); -} DRIVE; - - -extern DRIVE drives[FDD_NUM]; -extern wchar_t floppyfns[FDD_NUM][512]; -extern int driveempty[FDD_NUM]; -extern int64_t fdd_poll_time[FDD_NUM]; -extern int ui_writeprot[FDD_NUM]; - -extern int curdrive; - -extern int fdd_time; -extern int64_t floppytime; - - extern void fdd_load(int drive, wchar_t *fn); extern void fdd_new(int drive, char *fn); extern void fdd_close(int drive); diff --git a/src/floppy/fdd_common.c b/src/floppy/fdd_common.c index ca532d5..b775e36 100644 --- a/src/floppy/fdd_common.c +++ b/src/floppy/fdd_common.c @@ -8,7 +8,7 @@ * * Shared code for all the floppy modules. * - * Version: @(#)fdd_common.c 1.0.2 2018/03/16 + * Version: @(#)fdd_common.c 1.0.3 2018/03/19 * * Author: Fred N. van Kempen, * @@ -41,6 +41,14 @@ #include "fdd.h" #include "fdd_common.h" +/* Temporary until the rewrite is done. */ +#include "fdd_86f.h" +#include "fdd_fdi.h" +#include "fdd_imd.h" +#include "fdd_img.h" +#include "fdd_json.h" +#include "fdd_td0.h" + const uint8_t fdd_holes[6] = { 0, 0, 0, 1, 1, 2 }; @@ -456,3 +464,41 @@ fdd_interleave(int sector, int skew, int spt) return(adjusted_r); } + + +void +floppy_init(void) +{ + int i; + + /* Initialize all the image formats. */ + img_init(); + d86f_init(); + td0_init(); + imd_init(); + json_init(); + + /* Reset all drives. */ + for (i = 0; i < FDD_NUM; i++) { + drives[i].poll = 0; + drives[i].seek = 0; + drives[i].readsector = 0; + } + + /* Perform the reset. */ + fdd_reset(); + + /* Mount all configured drives. */ + for (i = 0; i < FDD_NUM; i++) + fdd_load(i, floppyfns[i]); +} + + +void +floppy_close(void) +{ + int i; + + for (i = 0; i < FDD_NUM; i++) + fdd_close(i); +} diff --git a/src/floppy/fdd_common.h b/src/floppy/fdd_common.h index 02ff783..92a2831 100644 --- a/src/floppy/fdd_common.h +++ b/src/floppy/fdd_common.h @@ -8,7 +8,7 @@ * * Shared code for all the floppy modules. * - * Version: @(#)fdd_common.h 1.0.2 2018/03/16 + * Version: @(#)fdd_common.h 1.0.3 2018/03/19 * * Author: Fred N. van Kempen, * @@ -49,5 +49,8 @@ extern int fdd_sector_code_size(uint8_t code); extern int fdd_bps_valid(uint16_t bps); extern int fdd_interleave(int sector, int skew, int spt); +extern void floppy_init(void); +extern void floppy_close(void); + #endif /*FDD_COMMON_H*/ diff --git a/src/floppy/fdd_imd.c b/src/floppy/fdd_imd.c index 244ced3..1453995 100644 --- a/src/floppy/fdd_imd.c +++ b/src/floppy/fdd_imd.c @@ -8,7 +8,7 @@ * * Implementation of the IMD floppy image format. * - * Version: @(#)fdd_imd.c 1.0.5 2018/03/17 + * Version: @(#)fdd_imd.c 1.0.6 2018/03/18 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -590,6 +590,7 @@ imd_load(int drive, wchar_t *fn) uint32_t raw_tsize = 0; uint32_t minimum_gap3 = 0; uint32_t minimum_gap4 = 0; + uint8_t converted_rate; d86f_unregister(drive); @@ -748,30 +749,42 @@ imd_load(int drive, wchar_t *fn) /* Not leaving even GAP1: 146 : 73 */ raw_tsize = get_raw_tsize(dev->tracks[track][side].side_flags, 0); minimum_gap3 = 12 * track_spt; - if ((raw_tsize - track_total + (mfm ? 146 : 73)) < (minimum_gap3 + minimum_gap4)) { - /* If we can't fit the sectors with a reasonable minimum gap at perfect RPM, let's try 2% slower. */ - raw_tsize = get_raw_tsize(dev->tracks[track][side].side_flags, 1); - /* Set disk flags so that rotation speed is 2% slower. */ - dev->disk_flags |= (3 << 5); + if ((dev->tracks[track][side].side_flags == 0x0A) || (dev->tracks[track][side].side_flags == 0x29)) + converted_rate = 2; + else if (dev->tracks[track][side].side_flags == 0x28) + converted_rate = 4; + else + converted_rate = dev->tracks[track][side].side_flags & 0x03; + + if (gap3_sizes[converted_rate][sector_size][track_spt] == 0x00) { if ((raw_tsize - track_total + (mfm ? 146 : 73)) < (minimum_gap3 + minimum_gap4)) { - /* If we can't fit the sectors with a reasonable minimum gap even at 2% slower RPM, abort. */ - pclog("IMD: Unable to fit the %i sectors in a track\n", track_spt); - fclose(dev->f); - free(dev); - imd[drive] = NULL; - memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); - return; + /* If we can't fit the sectors with a reasonable minimum gap at perfect RPM, let's try 2% slower. */ + raw_tsize = get_raw_tsize(dev->tracks[track][side].side_flags, 1); + /* Set disk flags so that rotation speed is 2% slower. */ + dev->disk_flags |= (3 << 5); + if ((raw_tsize - track_total + (mfm ? 146 : 73)) < (minimum_gap3 + minimum_gap4)) { + /* If we can't fit the sectors with a reasonable minimum gap even at 2% slower RPM, abort. */ + pclog("IMD: Unable to fit the %i sectors in a track\n", track_spt); + fclose(dev->f); + free(dev); + imd[drive] = NULL; + memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); + return; + } } - } - dev->tracks[track][side].gap3_len = (raw_tsize - track_total - minimum_gap4 + (mfm ? 146 : 73)) / track_spt; + dev->tracks[track][side].gap3_len = (raw_tsize - track_total - minimum_gap4 + (mfm ? 146 : 73)) / track_spt; + } else if (gap3_sizes[converted_rate][sector_size][track_spt] != 0x00) + dev->tracks[track][side].gap3_len = gap3_sizes[converted_rate][sector_size][track_spt]; - dev->track_count++; + if (track > dev->track_count) + dev->track_count = track; if (last_offset >= fsize) break; } /* If more than 43 tracks, then the tracks are thin (96 tpi). */ + dev->track_count++; dev->track_width = 0; if (dev->track_count > 43) dev->track_width = 1; diff --git a/src/floppy/fdd_td0.c b/src/floppy/fdd_td0.c index 2693ecd..d4e3d66 100644 --- a/src/floppy/fdd_td0.c +++ b/src/floppy/fdd_td0.c @@ -8,7 +8,7 @@ * * Implementation of the Teledisk floppy image format. * - * Version: @(#)fdd_td0.c 1.0.4 2018/03/17 + * Version: @(#)fdd_td0.c 1.0.5 2018/03/18 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -784,7 +784,8 @@ td0_initialize(int drive) track_size += (pre_sector + size + 2); } - track_count = track; + if (track > track_count) + track_count = track; if (track_spt != 255) { dev->track_spt[track][head] = track_spt; diff --git a/src/game/gameport.c b/src/game/gameport.c index 7e574c9..c609b8d 100644 --- a/src/game/gameport.c +++ b/src/game/gameport.c @@ -8,7 +8,7 @@ * * Implementation of a generic Game Port. * - * Version: @(#)gameport.c 1.0.3 2018/03/15 + * Version: @(#)gameport.c 1.0.4 2018/03/19 * * Authors: Miran Grca, * Sarah Walker, @@ -68,9 +68,6 @@ typedef struct _gameport_ { } gameport_t; -int joystick_type; - - static const joystick_if_t joystick_none = { "No joystick", NULL, @@ -84,8 +81,8 @@ static const joystick_if_t joystick_none = { 0 }; - static const joystick_if_t *joystick_list[] = { + &joystick_none, &joystick_standard, &joystick_standard_4button, &joystick_standard_6button, @@ -93,7 +90,6 @@ static const joystick_if_t *joystick_list[] = { &joystick_ch_flightstick_pro, &joystick_sw_pad, &joystick_tm_fcs, - &joystick_none, NULL }; static gameport_t *gameport_global = NULL; @@ -268,7 +264,7 @@ gameport_init(const device_t *info) { gameport_t *p = NULL; - if (joystick_type == 7) { + if (joystick_type == JOYSTICK_TYPE_NONE) { p = NULL; return(p); } @@ -287,7 +283,7 @@ gameport_201_init(const device_t *info) { gameport_t *p; - if (joystick_type == 7) { + if (joystick_type == JOYSTICK_TYPE_NONE) { p = NULL; return(p); } diff --git a/src/game/gameport.h b/src/game/gameport.h index 3db9996..4d40576 100644 --- a/src/game/gameport.h +++ b/src/game/gameport.h @@ -1,148 +1,148 @@ -/* - * VARCem Virtual ARchaeological Computer EMulator. - * 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 VARCem Project. - * - * Definitions for the generic game port handlers. - * - * NOTE: This module needs a good cleanup someday. - * - * Version: @(#)gameport.h 1.0.3 2018/03/15 - * - * Authors: Miran Grca, - * Sarah Walker, - * - * Copyright 2016-2018 Miran Grca. - * Copyright 2008-2017 Sarah Walker. - * - * 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. - */ -#ifndef EMU_GAMEPORT_H -# define EMU_GAMEPORT_H - - -#define MAX_PLAT_JOYSTICKS 8 -#define MAX_JOYSTICKS 4 - -#define POV_X 0x80000000 -#define POV_Y 0x40000000 - -#define AXIS_NOT_PRESENT -99999 - -#define JOYSTICK_PRESENT(n) (joystick_state[n].plat_joystick_nr != 0) - - -typedef struct { - char name[64]; - - int a[8]; - int b[32]; - int p[4]; - - struct { - char name[32]; - int id; - } axis[8]; - - struct { - char name[32]; - int id; - } button[32]; - - struct { - char name[32]; - int id; - } pov[4]; - - int nr_axes; - int nr_buttons; - int nr_povs; -} plat_joystick_t; - -typedef struct { - int axis[8]; - int button[32]; - int pov[4]; - - int plat_joystick_nr; - int axis_mapping[8]; - int button_mapping[32]; - int pov_mapping[4][2]; -} joystick_t; - -typedef struct { - const char *name; - - void *(*init)(void); - void (*close)(void *p); - uint8_t (*read)(void *p); - void (*write)(void *p); - int (*read_axis)(void *p, int axis); - void (*a0_over)(void *p); - - int axis_count, - button_count, - pov_count; - int max_joysticks; - const char *axis_names[8]; - const char *button_names[32]; - const char *pov_names[4]; -} joystick_if_t; - - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef EMU_DEVICE_H -extern const device_t gameport_device; -extern const device_t gameport_201_device; -#endif - -extern plat_joystick_t plat_joystick_state[MAX_PLAT_JOYSTICKS]; -extern joystick_t joystick_state[MAX_JOYSTICKS]; -extern int joysticks_present; - -extern int joystick_type; - - -extern void joystick_init(void); -extern void joystick_close(void); -extern void joystick_process(void); - -extern char *joystick_get_name(int js); -extern int joystick_get_max_joysticks(int js); -extern int joystick_get_axis_count(int js); -extern int joystick_get_button_count(int js); -extern int joystick_get_pov_count(int js); -extern char *joystick_get_axis_name(int js, int id); -extern char *joystick_get_button_name(int js, int id); -extern char *joystick_get_pov_name(int js, int id); - -extern void gameport_update_joystick_type(void); - -#ifdef __cplusplus -} -#endif - - -#endif /*EMU_GAMEPORT_H*/ +/* + * VARCem Virtual ARchaeological Computer EMulator. + * 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 VARCem Project. + * + * Definitions for the generic game port handlers. + * + * NOTE: This module needs a good cleanup someday. + * + * Version: @(#)gameport.h 1.0.4 2018/03/19 + * + * Authors: Miran Grca, + * Sarah Walker, + * + * Copyright 2016-2018 Miran Grca. + * Copyright 2008-2017 Sarah Walker. + * + * 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. + */ +#ifndef EMU_GAMEPORT_H +# define EMU_GAMEPORT_H + + +#define JOYSTICK_TYPE_NONE 0 /* no joystick defined */ + +#define MAX_PLAT_JOYSTICKS 8 +#define MAX_JOYSTICKS 4 + +#define POV_X 0x80000000 +#define POV_Y 0x40000000 + +#define AXIS_NOT_PRESENT -99999 + +#define JOYSTICK_PRESENT(n) (joystick_state[n].plat_joystick_nr != 0) + + +typedef struct { + char name[64]; + + int a[8]; + int b[32]; + int p[4]; + + struct { + char name[32]; + int id; + } axis[8]; + + struct { + char name[32]; + int id; + } button[32]; + + struct { + char name[32]; + int id; + } pov[4]; + + int nr_axes; + int nr_buttons; + int nr_povs; +} plat_joystick_t; + +typedef struct { + int axis[8]; + int button[32]; + int pov[4]; + + int plat_joystick_nr; + int axis_mapping[8]; + int button_mapping[32]; + int pov_mapping[4][2]; +} joystick_t; + +typedef struct { + const char *name; + + void *(*init)(void); + void (*close)(void *p); + uint8_t (*read)(void *p); + void (*write)(void *p); + int (*read_axis)(void *p, int axis); + void (*a0_over)(void *p); + + int axis_count, + button_count, + pov_count; + int max_joysticks; + const char *axis_names[8]; + const char *button_names[32]; + const char *pov_names[4]; +} joystick_if_t; + + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef EMU_DEVICE_H +extern const device_t gameport_device; +extern const device_t gameport_201_device; +#endif + +extern plat_joystick_t plat_joystick_state[MAX_PLAT_JOYSTICKS]; +extern joystick_t joystick_state[MAX_JOYSTICKS]; +extern int joysticks_present; + + +extern void joystick_init(void); +extern void joystick_close(void); +extern void joystick_process(void); + +extern char *joystick_get_name(int js); +extern int joystick_get_max_joysticks(int js); +extern int joystick_get_axis_count(int js); +extern int joystick_get_button_count(int js); +extern int joystick_get_pov_count(int js); +extern char *joystick_get_axis_name(int js, int id); +extern char *joystick_get_button_name(int js, int id); +extern char *joystick_get_pov_name(int js, int id); + +extern void gameport_update_joystick_type(void); + +#ifdef __cplusplus +} +#endif + + +#endif /*EMU_GAMEPORT_H*/ diff --git a/src/keyboard_at.c b/src/keyboard_at.c index d655228..58cc218 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.7 2018/03/15 + * Version: @(#)keyboard_at.c 1.0.8 2018/03/18 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -616,27 +616,23 @@ kbdlog(const char *fmt, ...) static void kbd_setmap(atkbd_t *kbd) { - const scancode *map = NULL; - switch (keyboard_mode & 3) { case 1: default: - map = scancode_set1; + keyboard_set_table(scancode_set1); break; case 2: - map = scancode_set2; + keyboard_set_table(scancode_set2); break; case 3: - map = scancode_set3; + keyboard_set_table(scancode_set3); break; } if (keyboard_mode & 0x20) - map = scancode_set1; - - keyboard_set_table(map); + keyboard_set_table(scancode_set1); } @@ -997,11 +993,6 @@ kbd_cmd_write(atkbd_t *kbd, uint8_t val) kbdlog("ATkbd: mouse interrupt is now %s\n", (val & 0x02) ? "enabled" : "disabled"); } - -#if 0 - /* Reset scancode map. */ - kbd_setmap(kbd); -#endif } diff --git a/src/machine/m_amstrad.c b/src/machine/m_amstrad.c index 3a866a3..868f4a2 100644 --- a/src/machine/m_amstrad.c +++ b/src/machine/m_amstrad.c @@ -32,7 +32,7 @@ * BIOSES: I need to re-do the bios.txt format so we can load non-BIOS * ROM files for a given machine, such as font roms here.. * - * Version: @(#)m_amstrad.c 1.0.3 2018/03/15 + * Version: @(#)m_amstrad.c 1.0.5 2018/03/19 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -1229,12 +1229,12 @@ machine_amstrad_init(const machine_t *model) ams = (amstrad_t *)malloc(sizeof(amstrad_t)); memset(ams, 0x00, sizeof(amstrad_t)); - nvr_at_init(1); - machine_common_init(model); nmi_init(); + device_add(&amstrad_nvr_device); + lpt2_remove_ams(); io_sethandler(0x0379, 2, @@ -1309,6 +1309,6 @@ machine_amstrad_init(const machine_t *model) mouse_reset(); mouse_set_poll(ms_poll, ams); - if (joystick_type != 7) + if (joystick_type != JOYSTICK_TYPE_NONE) device_add(&gameport_device); } diff --git a/src/machine/m_at.c b/src/machine/m_at.c index cfe1261..851eeb1 100644 --- a/src/machine/m_at.c +++ b/src/machine/m_at.c @@ -8,7 +8,7 @@ * * Standard PC/AT implementation. * - * Version: @(#)m_at.c 1.0.2 2018/03/15 + * Version: @(#)m_at.c 1.0.3 2018/03/19 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -68,9 +68,9 @@ machine_at_common_init(const machine_t *model) if (lpt_enabled) lpt2_remove(); - nvr_at_init(8); + device_add(&at_nvr_device); - if (joystick_type != 7) + if (joystick_type != JOYSTICK_TYPE_NONE) device_add(&gameport_device); } diff --git a/src/machine/m_europc.c b/src/machine/m_europc.c index 0f72318..6355694 100644 --- a/src/machine/m_europc.c +++ b/src/machine/m_europc.c @@ -66,7 +66,7 @@ * bit 1: b8000 memory available * 0000:046a: 00 jim 250 01 jim 350 * - * Version: @(#)europc.c 1.0.3 2018/03/15 + * Version: @(#)m_europc.c 1.0.4 2018/03/19 * * Author: Fred N. van Kempen, * @@ -621,7 +621,7 @@ europc_boot(const device_t *info) b = (sys->nvr.regs[MRTC_CONF_C] & 0xfc); if (mouse_type == MOUSE_TYPE_LOGIBUS) { b |= 0x01; /* enable port as MOUSE */ - } else if (joystick_type != 7) { + } else if (joystick_type != JOYSTICK_TYPE_NONE) { b |= 0x02; /* enable port as joysticks */ device_add(&gameport_device); } diff --git a/src/machine/m_olivetti_m24.c b/src/machine/m_olivetti_m24.c index a7cfae5..3ca2c16 100644 --- a/src/machine/m_olivetti_m24.c +++ b/src/machine/m_olivetti_m24.c @@ -8,7 +8,7 @@ * * Emulation of the Olivetti M24. * - * Version: @(#)m_olivetti_m24.c 1.0.3 2018/03/15 + * Version: @(#)m_olivetti_m24.c 1.0.4 2018/03/19 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -832,7 +832,6 @@ machine_olim24_init(const machine_t *model) memset(m24, 0x00, sizeof(olim24_t)); machine_common_init(model); - device_add(&fdc_xt_device); io_sethandler(0x0066, 2, m24_read,NULL,NULL, NULL,NULL,NULL, m24); @@ -870,11 +869,13 @@ machine_olim24_init(const machine_t *model) mouse_reset(); mouse_set_poll(ms_poll, m24); - if (joystick_type != 7) + if (joystick_type != JOYSTICK_TYPE_NONE) device_add(&gameport_device); /* FIXME: make sure this is correct?? */ - nvr_at_init(8); + device_add(&at_nvr_device); + + device_add(&fdc_xt_device); nmi_init(); } diff --git a/src/machine/m_ps1.c b/src/machine/m_ps1.c index dcf78fc..3122370 100644 --- a/src/machine/m_ps1.c +++ b/src/machine/m_ps1.c @@ -28,7 +28,7 @@ * boot. Sometimes, they do, and then it shows an "Incorrect * DOS" error message?? --FvK * - * Version: @(#)m_ps1.c 1.0.3 2018/03/15 + * Version: @(#)m_ps1.c 1.0.5 2018/03/19 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -564,7 +564,7 @@ ps1_common_init(const machine_t *model) dma16_init(); pic2_init(); - nvr_at_init(8); + device_add(&at_nvr_device); if (romset != ROM_IBMPS1_2011) device_add(&ide_isa_device); @@ -582,7 +582,7 @@ ps1_common_init(const machine_t *model) } /* Audio uses ports 200h and 202-207h, so only initialize gameport on 201h. */ - if (joystick_type != 7) + if (joystick_type != JOYSTICK_TYPE_NONE) device_add(&gameport_201_device); } diff --git a/src/machine/m_ps2_isa.c b/src/machine/m_ps2_isa.c index eae5e71..414fcb2 100644 --- a/src/machine/m_ps2_isa.c +++ b/src/machine/m_ps2_isa.c @@ -8,7 +8,7 @@ * * Implementation of ISA-based PS/2 machines. * - * Version: @(#)m_ps2_isa.c 1.0.2 2018/03/15 + * Version: @(#)m_ps2_isa.c 1.0.3 2018/03/19 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -194,7 +194,7 @@ machine_ps2_m30_286_init(const machine_t *model) pit_set_out_func(&pit, 1, pit_refresh_timer_at); dma16_init(); device_add(&keyboard_ps2_device); - nvr_at_init(8); + device_add(&at_nvr_device); pic2_init(); ps2board_init(); device_add(&ps1vga_device); diff --git a/src/machine/m_ps2_mca.c b/src/machine/m_ps2_mca.c index 598f089..e31b1ad 100644 --- a/src/machine/m_ps2_mca.c +++ b/src/machine/m_ps2_mca.c @@ -8,7 +8,7 @@ * * Implementation of MCA-based PS/2 machines. * - * Version: @(#)m_ps2_mca.c 1.0.3 2018/03/16 + * Version: @(#)m_ps2_mca.c 1.0.4 2018/03/19 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -1260,16 +1260,18 @@ static void machine_ps2_common_init(const machine_t *model) { machine_common_init(model); - device_add(&fdc_at_device); dma16_init(); - ps2_dma_init(); - device_add(&keyboard_ps2_mca_device); - nvr_at_init(8); pic2_init(); - + ps2_dma_init(); pit_ps2_init(); + device_add(&at_nvr_device); + + device_add(&keyboard_ps2_mca_device); + + device_add(&fdc_at_device); + nmi_mask = 0x80; } diff --git a/src/machine/m_tandy.c b/src/machine/m_tandy.c index 243b892..cfd2ff7 100644 --- a/src/machine/m_tandy.c +++ b/src/machine/m_tandy.c @@ -8,7 +8,7 @@ * * Emulation of Tandy models 1000, 1000HX and 1000SL2. * - * Version: @(#)m_tandy.c 1.0.2 2018/03/15 + * Version: @(#)m_tandy.c 1.0.3 2018/03/19 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -1766,7 +1766,7 @@ machine_tandy1k_init(const machine_t *model) device_add(&eep_device); } - if (joystick_type != 7) + if (joystick_type != JOYSTICK_TYPE_NONE) device_add(&gameport_device); eep_data_out = 0x0000; diff --git a/src/machine/m_xt.c b/src/machine/m_xt.c index e817f27..9b06769 100644 --- a/src/machine/m_xt.c +++ b/src/machine/m_xt.c @@ -8,7 +8,7 @@ * * Implementation of standard IBM PC/XT class machine. * - * Version: @(#)m_xt.c 1.0.2 2018/03/15 + * Version: @(#)m_xt.c 1.0.3 2018/03/19 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -62,6 +62,6 @@ machine_xt_init(const machine_t *model) device_add(&keyboard_xt_device); device_add(&fdc_xt_device); nmi_init(); - if (joystick_type != 7) + if (joystick_type != JOYSTICK_TYPE_NONE) device_add(&gameport_device); } diff --git a/src/machine/m_xt_compaq.c b/src/machine/m_xt_compaq.c index fb7815c..022154a 100644 --- a/src/machine/m_xt_compaq.c +++ b/src/machine/m_xt_compaq.c @@ -8,7 +8,7 @@ * * Emulation of various Compaq XT-class PC's. * - * Version: @(#)m_xt_compaq.c 1.0.3 2018/03/15 + * Version: @(#)m_xt_compaq.c 1.0.4 2018/03/19 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -66,7 +66,7 @@ machine_xt_compaq_init(const machine_t *model) device_add(&keyboard_xt_device); device_add(&fdc_xt_device); nmi_init(); - if (joystick_type != 7) + if (joystick_type != JOYSTICK_TYPE_NONE) device_add(&gameport_device); switch(model->id) { diff --git a/src/machine/m_xt_t1000.c b/src/machine/m_xt_t1000.c index 3a523b3..f93cf75 100644 --- a/src/machine/m_xt_t1000.c +++ b/src/machine/m_xt_t1000.c @@ -48,10 +48,7 @@ * hold a single BCD digit. Hence everything has 'ones' and * 'tens' digits. * - * NOTE: Still need to figure out a way to load/save ConfigSys and - * HardRAM stuff. Needs to be linked in to the NVR code. - * - * Version: @(#)m_xt_t1000.c 1.0.4 2018/03/15 + * Version: @(#)m_xt_t1000.c 1.0.5 2018/03/18 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -141,7 +138,9 @@ typedef struct { mem_mapping_t rom_mapping; /* CONFIG.SYS drive. */ - uint8_t config[160]; + wchar_t cfgsys_fn[128]; + uint16_t cfgsys_len; + uint8_t *cfgsys; /* System control registers */ uint8_t sys_ctl[16]; @@ -153,6 +152,7 @@ typedef struct { uint8_t nvr_tick; int nvr_addr; uint8_t nvr_active; + mem_mapping_t nvr_mapping; /* T1200 NVRAM mapping */ /* EMS data */ uint8_t ems_reg[4]; @@ -598,6 +598,80 @@ read_ctl(uint16_t addr, void *priv) } +/* Load contents of "CONFIG.SYS" device from file. */ +static void +cfgsys_load(t1000_t *dev) +{ + char temp[128]; + FILE *f; + + /* Set up the file's name. */ + sprintf(temp, "%s_cfgsys.nvr", machine_get_internal_name()); + mbstowcs(dev->cfgsys_fn, temp, sizeof_w(dev->cfgsys_fn)); + + /* Now attempt to load the file. */ + memset(dev->cfgsys, 0x1a, dev->cfgsys_len); + f = plat_fopen(nvr_path(dev->cfgsys_fn), L"rb"); + if (f != NULL) { + pclog("NVR: loaded CONFIG.SYS from '%ls'\n", dev->cfgsys_fn); + (void)fread(dev->cfgsys, dev->cfgsys_len, 1, f); + fclose(f); + } + else pclog("NVR: initialized CONFIG.SYS for '%ls'\n", dev->cfgsys_fn); +} + + +/* Write the contents of "CONFIG.SYS" to file. */ +static void +cfgsys_save(t1000_t *dev) +{ + FILE *f; + + /* Avoids writing empty files. */ + if (dev->cfgsys_len < 160) return; + + f = plat_fopen(nvr_path(dev->cfgsys_fn), L"wb"); + if (f != NULL) { + pclog("NVR: saved CONFIG.SYS to '%ls'\n", dev->cfgsys_fn); + (void)fwrite(dev->cfgsys, dev->cfgsys_len, 1, f); + fclose(f); + } +} + + +#if NOTUSED +/* All RAM beyond 512K is non-volatile */ +static void +emsboard_load(t1000_t *dev) +{ + FILE *f; + + if (mem_size > 512) { + f = plat_fopen(nvr_path(L"t1000_ems.nvr"), L"rb"); + if (f != NULL) { + fread(&ram[512 * 1024], 1024, (mem_size - 512), f); + fclose(f); + } + } +} + + +static void +emsboard_save(t1000_t *dev) +{ + FILE *f; + + if (mem_size > 512) { + f = plat_fopen(nvr_path(L"t1000_ems.nvr"), L"wb"); + if (f != NULL) { + fwrite(&ram[512 * 1024], 1024, (mem_size - 512), f); + fclose(f); + } + } +} +#endif + + static void t1200_turbo_set(uint8_t value) { @@ -662,7 +736,7 @@ t1000_read_nvram(uint16_t addr, void *priv) switch (addr) { case 0xc2: /* Read next byte from NVRAM */ if (sys->nvr_addr >= 0 && sys->nvr_addr < 160) - tmp = sys->config[sys->nvr_addr]; + tmp = sys->cfgsys[sys->nvr_addr]; sys->nvr_addr++; break; @@ -696,9 +770,9 @@ t1000_write_nvram(uint16_t addr, uint8_t val, void *priv) case 0xc1: /* Write next byte to NVRAM */ if (sys->nvr_addr >= 0 && sys->nvr_addr < 160) { - if (sys->config[sys->nvr_addr] != val) + if (sys->cfgsys[sys->nvr_addr] != val) nvr_dosave = 1; - sys->config[sys->nvr_addr] = val; + sys->cfgsys[sys->nvr_addr] = val; } sys->nvr_addr++; break; @@ -836,9 +910,12 @@ machine_xt_t1000_init(const machine_t *model) } /* Non-volatile RAM for CONFIG.SYS */ + t1000.cfgsys_len = 160; + t1000.cfgsys = (uint8_t *)malloc(t1000.cfgsys_len); io_sethandler(0xc0, 4, t1000_read_nvram,NULL,NULL, t1000_write_nvram,NULL,NULL, &t1000); + cfgsys_load(&t1000); /* ROM drive */ io_sethandler(0xc8, 1, @@ -862,6 +939,27 @@ machine_xt_t1000_init(const machine_t *model) } +static +uint8_t t1200_nvram_read(uint32_t addr, void *priv) +{ + t1000_t *sys = (t1000_t *)priv; + + return(sys->cfgsys[addr & 0x7ff]); +} + + +static void +t1200_nvram_write(uint32_t addr, uint8_t value, void *priv) +{ + t1000_t *sys = (t1000_t *)priv; + + if (sys->cfgsys[addr & 0x7ff] != value) + nvr_dosave = 1; + + sys->cfgsys[addr & 0x7ff] = value; +} + + const device_t * t1200_get_device(void) { @@ -898,6 +996,16 @@ machine_xt_t1200_init(const machine_t *model) machine_common_init(model); + /* Non-volatile RAM for CONFIG.SYS */ + t1000.cfgsys_len = 2048; + t1000.cfgsys = (uint8_t *)malloc(t1000.cfgsys_len); + mem_mapping_add(&t1000.nvr_mapping, + 0x000f0000, t1000.cfgsys_len, + t1200_nvram_read,NULL,NULL, + t1200_nvram_write,NULL,NULL, + NULL, 0, &t1000); + cfgsys_load(&t1000); + pit_set_out_func(&pit, 1, pit_refresh_timer_xt); device_add(&keyboard_xt_device); t1000.fdc = device_add(&fdc_xt_device); @@ -909,6 +1017,13 @@ machine_xt_t1200_init(const machine_t *model) } +void +machine_xt_t1x00_close(void) +{ + cfgsys_save(&t1000); +} + + void t1000_syskey(uint8_t andmask, uint8_t ormask, uint8_t xormask) { @@ -916,63 +1031,3 @@ t1000_syskey(uint8_t andmask, uint8_t ormask, uint8_t xormask) t1000.syskeys |= ormask; t1000.syskeys ^= xormask; } - - -#if 0 -void -t1000_configsys_load(void) -{ - FILE *f; - - memset(config_sys, 0x1a, sizeof(config_sys)); - f = plat_fopen(nvr_path(L"t1000_config.nvr"), L"rb"); - if (f != NULL) { - fread(config_sys, sizeof(config_sys), 1, f); - fclose(f); - } -} - - -void -t1000_configsys_save(void) -{ - FILE *f; - - f = plat_fopen(nvr_path(L"t1000_config.nvr"), L"wb"); - if (f != NULL) { - fwrite(config_sys, sizeof(config_sys), 1, f); - fclose(f); - } -} - - -/* All RAM beyond 512k is non-volatile */ -void -t1000_emsboard_load(void) -{ - FILE *f; - - if (mem_size > 512) { - f = plat_fopen(nvr_path(L"t1000_ems.nvr"), L"rb"); - if (f != NULL) { - fread(&ram[512 * 1024], 1024, (mem_size - 512), f); - fclose(f); - } - } -} - - -void -t1000_emsboard_save(void) -{ - FILE *f; - - if (mem_size > 512) { - f = plat_fopen(nvr_path(L"t1000_ems.nvr"), L"wb"); - if (f != NULL) { - fwrite(&ram[512 * 1024], 1024, (mem_size - 512), f); - fclose(f); - } - } -} -#endif diff --git a/src/machine/m_xt_xi8088.c b/src/machine/m_xt_xi8088.c index 27e3bc1..59873ba 100644 --- a/src/machine/m_xt_xi8088.c +++ b/src/machine/m_xt_xi8088.c @@ -8,7 +8,7 @@ * * Implementation of the Xi8088 open-source machine. * - * Version: @(#)m_xt_xi8088.c 1.0.2 2018/03/15 + * Version: @(#)m_xt_xi8088.c 1.0.3 2018/03/19 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -47,8 +47,8 @@ #include "../dma.h" #include "../mem.h" #include "../nmi.h" -#include "../nvr.h" #include "../device.h" +#include "../nvr.h" #include "../keyboard.h" #include "../lpt.h" #include "../game/gameport.h" @@ -146,41 +146,49 @@ static const device_config_t xi8088_config[] = }; -const device_t xi8088_device = -{ - "Xi8088", - 0, 0, - xi8088_init, NULL, NULL, - NULL, - NULL, - NULL, - NULL, - xi8088_config +const device_t xi8088_device = { + "Xi8088", + 0, 0, + xi8088_init, NULL, NULL, + NULL, + NULL, + NULL, + NULL, + xi8088_config }; const device_t * xi8088_get_device(void) { - return &xi8088_device; + return(&xi8088_device); } void machine_xt_xi8088_init(const machine_t *model) { - if (biosmask < 0x010000) - xi8088_bios_128kb_set(0); - else - xi8088_bios_128kb_set(1); + if (biosmask < 0x010000) + xi8088_bios_128kb_set(0); + else + xi8088_bios_128kb_set(1); - /* TODO: set UMBs? See if PCem always sets when we have > 640KB ram and avoids conflicts when a peripheral uses the same memory space */ - machine_common_init(model); - device_add(&fdc_xt_device); - device_add(&keyboard_ps2_device); - nmi_init(); - nvr_at_init(8); - pic2_init(); - if (joystick_type != 7) - device_add(&gameport_device); + /* + * TODO: set UMBs? + * See if PCem always sets when we have > 640KB ram and avoids + * conflicts when a peripheral uses the same memory space + */ + machine_common_init(model); + + nmi_init(); + pic2_init(); + + device_add(&at_nvr_device); + + device_add(&keyboard_ps2_device); + + if (joystick_type != JOYSTICK_TYPE_NONE) + device_add(&gameport_device); + + device_add(&fdc_xt_device); } diff --git a/src/machine/machine.c b/src/machine/machine.c index 49e30ad..48c6a74 100644 --- a/src/machine/machine.c +++ b/src/machine/machine.c @@ -8,7 +8,7 @@ * * Handling of the emulated machines. * - * Version: @(#)machine.c 1.0.7 2018/03/16 + * Version: @(#)machine.c 1.0.9 2018/03/19 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -91,6 +91,15 @@ machine_init(void) } +/* Close down the machine (saving stuff, etc.) */ +void +machine_close(void) +{ + if (machines[machine].close != NULL) + machines[machine].close(); +} + + /* Check if the machine's ROM files are present. */ int machine_available(int id) diff --git a/src/machine/machine.h b/src/machine/machine.h index 317b9da..2d13c09 100644 --- a/src/machine/machine.h +++ b/src/machine/machine.h @@ -8,7 +8,7 @@ * * Handling of the emulated machines. * - * Version: @(#)machine.h 1.0.10 2018/03/15 + * Version: @(#)machine.h 1.0.11 2018/03/18 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -220,7 +220,7 @@ typedef struct _machine_ { #else const void *get_device; #endif - void (*nvr_close)(void); + void (*close)(void); } machine_t; @@ -242,6 +242,7 @@ extern int machine_get_machine_from_internal_name(char *s); extern int machine_available(int id); extern int machine_detect(void); extern void machine_init(void); +extern void machine_close(void); #ifdef EMU_DEVICE_H extern const device_t *machine_getdevice(int machine); #endif @@ -347,6 +348,7 @@ extern void machine_xt_laserxt_init(const machine_t *); extern void machine_xt_t1000_init(const machine_t *); extern void machine_xt_t1200_init(const machine_t *); +extern void machine_xt_t1x00_close(void); extern void machine_xt_xi8088_init(const machine_t *); diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index dc1d32f..5a25df3 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.11 2018/03/15 + * Version: @(#)machine_table.c 1.0.13 2018/03/19 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -65,126 +65,126 @@ const machine_t machines[] = { { "[8088] Schneider EuroPC", ROM_EUROPC, "schneider_europc", L"schneider/europc", {{"Siemens", cpus_europc}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_HDC | MACHINE_VIDEO | MACHINE_MOUSE, 512, 640, 128, 16, machine_europc_init, NULL, NULL }, { "[8088] Tandy 1000", ROM_TANDY, "tandy_1000", L"tandy/t1000", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA, 128, 640, 128, 0, machine_tandy1k_init, tandy1k_get_device, NULL }, { "[8088] Tandy 1000 HX", ROM_TANDY1000HX, "tandy_1000hx", L"tandy/t1000hx", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA, 256, 640, 128, 0, machine_tandy1k_init, tandy1k_hx_get_device, NULL }, - { "[8088] Toshiba 1000", ROM_T1000, "toshiba_t1000", L"toshiba/t1000", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_VIDEO, 512, 1280, 768, 0, machine_xt_t1000_init, NULL, NULL }, + { "[8088] Toshiba 1000", ROM_T1000, "toshiba_t1000", L"toshiba/t1000", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_VIDEO, 512, 1280, 768, 64, machine_xt_t1000_init, NULL, machine_xt_t1x00_close }, #if defined(DEV_BRANCH) && defined(USE_LASERXT) { "[8088] VTech Laser Turbo XT", ROM_LTXT, "vtech_ltxt", L"vtech/ltxt", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 512, 512, 256, 0, machine_xt_laserxt_init, NULL, NULL }, #endif - { "[8088] Xi8088", ROM_XI8088, "malinov_xi8088", L"malinov/xi8088", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA /*| MACDHINE_AT*/ | MACHINE_PS2, 64, 1024, 128, 128, machine_xt_xi8088_init, NULL, nvr_at_close }, - { "[8086] Amstrad PC1512", ROM_PC1512, "amstrad_pc1512", L"amstrad/pc1512", {{"", cpus_pc1512}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VIDEO | MACHINE_MOUSE, 512, 640, 128, 64, machine_amstrad_init, NULL, nvr_at_close }, - { "[8086] Amstrad PC1640", ROM_PC1640, "amstrad_pc1640", L"amstrad/pc1640", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VIDEO | MACHINE_MOUSE, 640, 640, 0, 64, machine_amstrad_init, NULL, nvr_at_close }, - { "[8086] Amstrad PC2086", ROM_PC2086, "amstrad_pc2086", L"amstrad/pc2086", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_VIDEO | MACHINE_MOUSE, 640, 640, 0, 64, machine_amstrad_init, NULL, nvr_at_close }, - { "[8086] Amstrad PC3086", ROM_PC3086, "amstrad_pc3086", L"amstrad/pc3086", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_VIDEO | MACHINE_MOUSE, 640, 640, 0, 64, machine_amstrad_init, NULL, nvr_at_close }, - { "[8086] Amstrad PC20(0)", ROM_PC200, "amstrad_pc200", L"amstrad/pc200", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_VIDEO | MACHINE_MOUSE, 512, 640, 128, 64, machine_amstrad_init, NULL, nvr_at_close }, + { "[8088] Xi8088", ROM_XI8088, "malinov_xi8088", L"malinov/xi8088", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA /*| MACDHINE_AT*/ | MACHINE_PS2, 64, 1024, 128, 128, machine_xt_xi8088_init, NULL, NULL }, + { "[8086] Amstrad PC1512", ROM_PC1512, "amstrad_pc1512", L"amstrad/pc1512", {{"", cpus_pc1512}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VIDEO | MACHINE_MOUSE, 512, 640, 128, 64, machine_amstrad_init, NULL, NULL }, + { "[8086] Amstrad PC1640", ROM_PC1640, "amstrad_pc1640", L"amstrad/pc1640", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VIDEO | MACHINE_MOUSE, 640, 640, 0, 64, machine_amstrad_init, NULL, NULL }, + { "[8086] Amstrad PC2086", ROM_PC2086, "amstrad_pc2086", L"amstrad/pc2086", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_VIDEO | MACHINE_MOUSE, 640, 640, 0, 64, machine_amstrad_init, NULL, NULL }, + { "[8086] Amstrad PC3086", ROM_PC3086, "amstrad_pc3086", L"amstrad/pc3086", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_VIDEO | MACHINE_MOUSE, 640, 640, 0, 64, machine_amstrad_init, NULL, NULL }, + { "[8086] Amstrad PC20(0)", ROM_PC200, "amstrad_pc200", L"amstrad/pc200", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_VIDEO | MACHINE_MOUSE, 512, 640, 128, 64, machine_amstrad_init, NULL, NULL }, { "[8086] Olivetti M24", ROM_OLIM24, "olivetti_m24", L"olivetti/m24", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_VIDEO | MACHINE_MOUSE, 128, 640, 128, 0, machine_olim24_init, NULL, NULL }, { "[8086] Tandy 1000 SL/2", ROM_TANDY1000SL2, "tandy_1000sl2", L"tandy/t1000sl2", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA, 512, 768, 128, 0, machine_tandy1k_init, NULL, NULL }, - { "[8086] Toshiba 1200", ROM_T1200, "toshiba_t1200", L"toshiba/t1200", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_VIDEO, 1024, 2048,1024, 0, machine_xt_t1200_init, NULL, NULL }, + { "[8086] Toshiba 1200", ROM_T1200, "toshiba_t1200", L"toshiba/t1200", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_VIDEO, 1024, 2048,1024, 64, machine_xt_t1200_init, NULL, machine_xt_t1x00_close }, #if defined(DEV_BRANCH) && defined(USE_LASERXT) { "[8086] VTech Laser XT3", ROM_LXT3, "vtech_lxt3", L"vtech/lxt3", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 256, 512, 256, 0, machine_xt_laserxt_init, NULL, NULL }, #endif - { "[286 ISA] AMI 286 clone", ROM_AMI286, "ami_286", L"generic/ami/286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT, 512,16384, 128, 128, machine_at_neat_ami_init, NULL, nvr_at_close }, - { "[286 ISA] Award 286 clone", ROM_AWARD286, "award_286", L"generic/award/286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT, 512,16384, 128, 128, machine_at_scat_init, NULL, nvr_at_close }, - { "[286 ISA] Commodore PC 30 III", ROM_CMDPC30, "commodore_pc30", L"commodore/pc30", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT, 640,16384, 128, 128, machine_at_cmdpc_init, NULL, nvr_at_close }, - { "[286 ISA] Compaq Portable II", ROM_PORTABLEII, "compaq_portable2", L"compaq/portable2", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT, 640,16384, 128, 128, machine_at_compaq_init, NULL, nvr_at_close }, + { "[286 ISA] AMI 286 clone", ROM_AMI286, "ami_286", L"generic/ami/286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT, 512,16384, 128, 128, machine_at_neat_ami_init, NULL, NULL }, + { "[286 ISA] Award 286 clone", ROM_AWARD286, "award_286", L"generic/award/286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT, 512,16384, 128, 128, machine_at_scat_init, NULL, NULL }, + { "[286 ISA] Commodore PC 30 III", ROM_CMDPC30, "commodore_pc30", L"commodore/pc30", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT, 640,16384, 128, 128, machine_at_cmdpc_init, NULL, NULL }, + { "[286 ISA] Compaq Portable II", ROM_PORTABLEII, "compaq_portable2", L"compaq/portable2", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT, 640,16384, 128, 128, machine_at_compaq_init, NULL, NULL }, #if defined(DEV_BRANCH) && defined(USE_PORTABLE3) - { "[286 ISA] Compaq Portable III", ROM_PORTABLEIII, "compaq_portable3", L"compaq/portable3", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_AT | MACHINE_VIDEO, 640,16384, 128, 128, machine_at_compaq_init, NULL, nvr_at_close }, + { "[286 ISA] Compaq Portable III", ROM_PORTABLEIII, "compaq_portable3", L"compaq/portable3", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_AT | MACHINE_VIDEO, 640,16384, 128, 128, machine_at_compaq_init, NULL, NULL }, #endif - { "[286 ISA] GW-286CT GEAR", ROM_GW286CT, "gw286ct", L"unknown/gw286ct", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT, 512,16384, 128, 128, machine_at_scat_init, NULL, nvr_at_close }, - { "[286 ISA] Hyundai Super-286TR", ROM_SUPER286TR, "hyundai_super286tr", L"hyundai/super286tr", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT, 512,16384, 128, 128, machine_at_scat_init, NULL, nvr_at_close }, - { "[286 ISA] IBM AT", ROM_IBMAT, "ibm_at", L"ibm/at", {{"", cpus_ibmat}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT, 256,15872, 128, 64, machine_at_ibm_init, NULL, nvr_at_close }, - { "[286 ISA] IBM PS/1 model 2011", ROM_IBMPS1_2011, "ibm_ps1_2011", L"ibm/ps1_2011", {{"", cpus_ps1_m2011}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC_PS2, 512,16384, 512, 128, machine_ps1_m2011_init, NULL, nvr_at_close }, - { "[286 ISA] IBM PS/2 model 30-286", ROM_IBMPS2_M30_286, "ibm_ps2_m30_286", L"ibm/ps2_m30_286", {{"", cpus_ps2_m30_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC_PS2, 1, 16, 1, 128, machine_ps2_m30_286_init, NULL, nvr_at_close }, - { "[286 ISA] IBM XT Model 286", ROM_IBMXT286, "ibm_xt286", L"ibm/xt286", {{"", cpus_ibmxt286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT, 256,15872, 128, 64, machine_at_ibm_init, NULL, nvr_at_close }, - { "[286 ISA] Samsung SPC-4200P", ROM_SPC4200P, "samsung_spc4200p", L"samsung/spc4200p", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_PS2, 512, 2048, 128, 128, machine_at_scat_init, NULL, nvr_at_close }, - { "[286 ISA] Samsung SPC-4216P", ROM_SPC4216P, "samsung_spc4216p", L"samsung/spc4216p", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_PS2, 1, 5, 1, 128, machine_at_scat_init, NULL, nvr_at_close }, - { "[286 ISA] Toshiba 3100e", ROM_T3100E, "toshiba_t3100e", L"toshiba/t3100e", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1024, 5120, 256, 64, machine_at_t3100e_init, NULL, nvr_at_close }, + { "[286 ISA] GW-286CT GEAR", ROM_GW286CT, "gw286ct", L"unknown/gw286ct", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT, 512,16384, 128, 128, machine_at_scat_init, NULL, NULL }, + { "[286 ISA] Hyundai Super-286TR", ROM_SUPER286TR, "hyundai_super286tr", L"hyundai/super286tr", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT, 512,16384, 128, 128, machine_at_scat_init, NULL, NULL }, + { "[286 ISA] IBM AT", ROM_IBMAT, "ibm_at", L"ibm/at", {{"", cpus_ibmat}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT, 256,15872, 128, 64, machine_at_ibm_init, NULL, NULL }, + { "[286 ISA] IBM PS/1 model 2011", ROM_IBMPS1_2011, "ibm_ps1_2011", L"ibm/ps1_2011", {{"", cpus_ps1_m2011}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC_PS2, 512,16384, 512, 128, machine_ps1_m2011_init, NULL, NULL }, + { "[286 ISA] IBM PS/2 model 30-286", ROM_IBMPS2_M30_286, "ibm_ps2_m30_286", L"ibm/ps2_m30_286", {{"", cpus_ps2_m30_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC_PS2, 1, 16, 1, 128, machine_ps2_m30_286_init, NULL, NULL }, + { "[286 ISA] IBM XT Model 286", ROM_IBMXT286, "ibm_xt286", L"ibm/xt286", {{"", cpus_ibmxt286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT, 256,15872, 128, 64, machine_at_ibm_init, NULL, NULL }, + { "[286 ISA] Samsung SPC-4200P", ROM_SPC4200P, "samsung_spc4200p", L"samsung/spc4200p", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_PS2, 512, 2048, 128, 128, machine_at_scat_init, NULL, NULL }, + { "[286 ISA] Samsung SPC-4216P", ROM_SPC4216P, "samsung_spc4216p", L"samsung/spc4216p", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_PS2, 1, 5, 1, 128, machine_at_scat_init, NULL, NULL }, + { "[286 ISA] Toshiba 3100e", ROM_T3100E, "toshiba_t3100e", L"toshiba/t3100e", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1024, 5120, 256, 64, machine_at_t3100e_init, NULL, NULL }, - { "[286 MCA] IBM PS/2 model 50", ROM_IBMPS2_M50, "ibm_ps2_m50", L"ibm/ps2_m50", {{"", cpus_ps2_m30_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC_PS2, 1, 10, 1, 64, machine_ps2_model_50_init, NULL, nvr_at_close }, + { "[286 MCA] IBM PS/2 model 50", ROM_IBMPS2_M50, "ibm_ps2_m50", L"ibm/ps2_m50", {{"", cpus_ps2_m30_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC_PS2, 1, 10, 1, 64, machine_ps2_model_50_init, NULL, NULL }, - { "[386SX ISA] AMI 386SX clone", ROM_AMI386SX, "ami_386", L"generic/ami/386", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 512,16384, 128, 128, machine_at_headland_init, NULL, nvr_at_close }, - { "[386SX ISA] Amstrad MegaPC", ROM_MEGAPC, "amstrad_megapc", L"amstrad/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, 128, machine_at_wd76c10_init, NULL, nvr_at_close }, - { "[386SX ISA] Award 386SX clone", ROM_AWARD386SX_OPTI495, "award_386sx", L"generic/award/opti495", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 128, machine_at_opti495_init, NULL, nvr_at_close }, - { "[386SX ISA] DTK 386SX clone", ROM_DTK386, "dtk_386", L"dtk/386", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 512,16384, 128, 128, machine_at_neat_init, NULL, nvr_at_close }, - { "[386SX ISA] IBM PS/1 model 2121", ROM_IBMPS1_2121, "ibm_ps1_2121", L"ibm/ps1_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, 128, machine_ps1_m2121_init, NULL, nvr_at_close }, - { "[386SX ISA] IBM PS/1 m.2121+ISA", ROM_IBMPS1_2121_ISA, "ibm_ps1_2121_isa", L"ibm/ps1_2121", {{"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, 128, machine_ps1_m2121_init, NULL, nvr_at_close }, + { "[386SX ISA] AMI 386SX clone", ROM_AMI386SX, "ami_386", L"generic/ami/386", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 512,16384, 128, 128, machine_at_headland_init, NULL, NULL }, + { "[386SX ISA] Amstrad MegaPC", ROM_MEGAPC, "amstrad_megapc", L"amstrad/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, 128, machine_at_wd76c10_init, NULL, NULL }, + { "[386SX ISA] Award 386SX clone", ROM_AWARD386SX_OPTI495, "award_386sx", L"generic/award/opti495", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 128, machine_at_opti495_init, NULL, NULL }, + { "[386SX ISA] DTK 386SX clone", ROM_DTK386, "dtk_386", L"dtk/386", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 512,16384, 128, 128, machine_at_neat_init, NULL, NULL }, + { "[386SX ISA] IBM PS/1 model 2121", ROM_IBMPS1_2121, "ibm_ps1_2121", L"ibm/ps1_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, 128, machine_ps1_m2121_init, NULL, NULL }, + { "[386SX ISA] IBM PS/1 m.2121+ISA", ROM_IBMPS1_2121_ISA, "ibm_ps1_2121_isa", L"ibm/ps1_2121", {{"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, 128, machine_ps1_m2121_init, NULL, NULL }, - { "[386SX MCA] IBM PS/2 model 55SX", ROM_IBMPS2_M55SX, "ibm_ps2_m55sx", L"ibm/ps2_m55sx", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 1, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC_PS2, 1, 8, 1, 68, machine_ps2_model_55sx_init, NULL, nvr_at_close }, - { "[386SX ISA] KMX-C-02", ROM_KMXC02, "kmxc02", L"unknown/kmxc02", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT, 512,16384, 512, 128, machine_at_scatsx_init, NULL, nvr_at_close }, + { "[386SX MCA] IBM PS/2 model 55SX", ROM_IBMPS2_M55SX, "ibm_ps2_m55sx", L"ibm/ps2_m55sx", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 1, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC_PS2, 1, 8, 1, 68, machine_ps2_model_55sx_init, NULL, NULL }, + { "[386SX ISA] KMX-C-02", ROM_KMXC02, "kmxc02", L"unknown/kmxc02", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT, 512,16384, 512, 128, machine_at_scatsx_init, NULL, NULL }, - { "[386DX ISA] AMI 386DX clone", ROM_AMI386DX_OPTI495, "ami_386dx", L"generic/ami/386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 128, machine_at_opti495_ami_init, NULL, nvr_at_close }, - { "[386DX ISA] Amstrad MegaPC 386DX", ROM_MEGAPCDX, "amstrad_megapc_dx", L"amstrad/megapc", {{"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, 128, machine_at_wd76c10_init, NULL, nvr_at_close }, - { "[386DX ISA] Award 386DX clone", ROM_AWARD386DX_OPTI495, "award_386dx", L"generic/award/opti495", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 128, machine_at_opti495_init, NULL, nvr_at_close }, - { "[386DX ISA] MR 386DX clone", ROM_MR386DX_OPTI495, "microid_mr386dx", L"microid/mr386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 128, machine_at_opti495_ami_init, NULL, nvr_at_close }, + { "[386DX ISA] AMI 386DX clone", ROM_AMI386DX_OPTI495, "ami_386dx", L"generic/ami/386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 128, machine_at_opti495_ami_init, NULL, NULL }, + { "[386DX ISA] Amstrad MegaPC 386DX", ROM_MEGAPCDX, "amstrad_megapc_dx", L"amstrad/megapc", {{"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, 128, machine_at_wd76c10_init, NULL, NULL }, + { "[386DX ISA] Award 386DX clone", ROM_AWARD386DX_OPTI495, "award_386dx", L"generic/award/opti495", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 128, machine_at_opti495_init, NULL, NULL }, + { "[386DX ISA] MR 386DX clone", ROM_MR386DX_OPTI495, "microid_mr386dx", L"microid/mr386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 128, machine_at_opti495_ami_init, NULL, NULL }, #if defined(DEV_BRANCH) && defined(USE_PORTABLE3) - { "[386DX ISA] Compaq Portable III (386)", ROM_PORTABLEIII386, "portable3_386", L"compaq/deskpro386", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_AT | MACHINE_HDC | MACHINE_VIDEO, 1, 14, 1, 128, machine_at_compaq_init, NULL, nvr_at_close }, + { "[386DX ISA] Compaq Portable III (386)", ROM_PORTABLEIII386, "portable3_386", L"compaq/deskpro386", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_AT | MACHINE_HDC | MACHINE_VIDEO, 1, 14, 1, 128, machine_at_compaq_init, NULL, NULL }, #endif - { "[386DX MCA] IBM PS/2 model 70 (type 3)", ROM_IBMPS2_M70_TYPE3, "ibm_ps2_m70_type3", L"ibm/ps2_m70_type3", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 1, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC_PS2, 2, 16, 2, 63, machine_ps2_model_70_type3_init, NULL, nvr_at_close }, - { "[386DX MCA] IBM PS/2 model 80", ROM_IBMPS2_M80, "ibm_ps2_m80", L"ibm/ps2_m80", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 1, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC_PS2, 1, 12, 1, 64, machine_ps2_model_80_init, NULL, nvr_at_close }, + { "[386DX MCA] IBM PS/2 model 70 (type 3)", ROM_IBMPS2_M70_TYPE3, "ibm_ps2_m70_type3", L"ibm/ps2_m70_type3", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 1, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC_PS2, 2, 16, 2, 63, machine_ps2_model_70_type3_init, NULL, NULL }, + { "[386DX MCA] IBM PS/2 model 80", ROM_IBMPS2_M80, "ibm_ps2_m80", L"ibm/ps2_m80", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 1, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC_PS2, 1, 12, 1, 64, machine_ps2_model_80_init, NULL, NULL }, - { "[486 ISA] AMI 486 clone", ROM_AMI486, "ami_486", L"generic/ami/486", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 128, machine_at_ali1429_init, NULL, nvr_at_close }, - { "[486 ISA] AMI WinBIOS 486", ROM_WIN486, "ami_win486", L"generic/ami/win486", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 128, machine_at_ali1429_init, NULL, nvr_at_close }, - { "[486 ISA] Award 486 clone", ROM_AWARD486_OPTI495, "award_486", L"generic/award/opti495", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 128, machine_at_opti495_init, NULL, nvr_at_close }, - { "[486 ISA] DTK PKM-0038S E-2", ROM_DTK486, "dtk_486", L"dtk/486", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 128, 1, 128, machine_at_dtk486_init, NULL, nvr_at_close }, - { "[486 ISA] IBM PS/1 model 2133", ROM_IBMPS1_2133, "ibm_ps1_2133", L"ibm/ps1_2133", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 1, 64, 1, 128, machine_ps1_m2133_init, NULL, nvr_at_close }, - { "[486 MCA] IBM PS/2 model 70 (type 4)", ROM_IBMPS2_M70_TYPE4, "ibm_ps2_m70_type4", L"ibm/ps2_m70_type4", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 1, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC_PS2, 2, 64, 2, 63, machine_ps2_model_70_type4_init, NULL, nvr_at_close }, + { "[486 ISA] AMI 486 clone", ROM_AMI486, "ami_486", L"generic/ami/486", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 128, machine_at_ali1429_init, NULL, NULL }, + { "[486 ISA] AMI WinBIOS 486", ROM_WIN486, "ami_win486", L"generic/ami/win486", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 128, machine_at_ali1429_init, NULL, NULL }, + { "[486 ISA] Award 486 clone", ROM_AWARD486_OPTI495, "award_486", L"generic/award/opti495", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 128, machine_at_opti495_init, NULL, NULL }, + { "[486 ISA] DTK PKM-0038S E-2", ROM_DTK486, "dtk_486", L"dtk/486", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 128, 1, 128, machine_at_dtk486_init, NULL, NULL }, + { "[486 ISA] IBM PS/1 model 2133", ROM_IBMPS1_2133, "ibm_ps1_2133", L"ibm/ps1_2133", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 1, 64, 1, 128, machine_ps1_m2133_init, NULL, NULL }, + { "[486 MCA] IBM PS/2 model 70 (type 4)", ROM_IBMPS2_M70_TYPE4, "ibm_ps2_m70_type4", L"ibm/ps2_m70_type4", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 1, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC_PS2, 2, 64, 2, 63, machine_ps2_model_70_type4_init, NULL, NULL }, - { "[486 PCI] Rise Computer R418", ROM_R418, "rise_r418", L"rise/r418", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 255, 1, 128, machine_at_r418_init, NULL, nvr_at_close }, + { "[486 PCI] Rise Computer R418", ROM_R418, "rise_r418", L"rise/r418", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 255, 1, 128, machine_at_r418_init, NULL, NULL }, #if defined(DEV_BRANCH) && defined(USE_GREENB) - { "[486 VLB] Green-B 4GP V3.1", ROM_4GPV31, "addtech_4gpv31", L"addtech/4gpv31", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VLB | MACHINE_AT, 1, 128, 1, 128, machine_at_4gpv31_init, NULL, nvr_at_close }, + { "[486 VLB] Green-B 4GP V3.1", ROM_4GPV31, "addtech_4gpv31", L"addtech/4gpv31", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VLB | MACHINE_AT, 1, 128, 1, 128, machine_at_4gpv31_init, NULL, NULL }, #endif - { "[Socket 4 LX] Intel Premiere/PCI", ROM_REVENGE, "intel_revenge", L"intel/revenge", {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 128, machine_at_batman_init, NULL, nvr_at_close }, + { "[Socket 4 LX] Intel Premiere/PCI", ROM_REVENGE, "intel_revenge", L"intel/revenge", {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 128, machine_at_batman_init, NULL, NULL }, #if defined(DEV_BRANCH) && defined(USE_AMD_K) - { "[Socket 5 NX] Intel Premiere/PCI II", ROM_PLATO, "intel_plato", L"intel/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, 128, machine_at_plato_init, NULL, nvr_at_close }, + { "[Socket 5 NX] Intel Premiere/PCI II", ROM_PLATO, "intel_plato", L"intel/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, 128, machine_at_plato_init, NULL, NULL }, - { "[Socket 5 FX] ASUS P/I-P54TP4XE", ROM_P54TP4XE, "asus_p54tp4xe", L"asus/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, 128, machine_at_p54tp4xe_init, NULL, nvr_at_close }, - { "[Socket 5 FX] Intel Advanced/EV", ROM_ENDEAVOR, "intel_endeavor", L"intel/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, 128, machine_at_endeavor_init, at_endeavor_get_device, nvr_at_close }, - { "[Socket 5 FX] Intel Advanced/ZP", ROM_ZAPPA, "intel_zappa", L"intel/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, 128, machine_at_zappa_init, NULL, nvr_at_close }, - { "[Socket 5 FX] PC Partner MB500N", ROM_MB500N, "pcpartner_mb500n", L"pcpartner/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, 128, machine_at_mb500n_init, NULL, nvr_at_close }, - { "[Socket 5 FX] President Award 430FX PCI",ROM_PRESIDENT, "president", L"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, 128, machine_at_president_init, NULL, nvr_at_close }, + { "[Socket 5 FX] ASUS P/I-P54TP4XE", ROM_P54TP4XE, "asus_p54tp4xe", L"asus/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, 128, machine_at_p54tp4xe_init, NULL, NULL }, + { "[Socket 5 FX] Intel Advanced/EV", ROM_ENDEAVOR, "intel_endeavor", L"intel/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, 128, machine_at_endeavor_init, at_endeavor_get_device, NULL }, + { "[Socket 5 FX] Intel Advanced/ZP", ROM_ZAPPA, "intel_zappa", L"intel/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, 128, machine_at_zappa_init, NULL, NULL }, + { "[Socket 5 FX] PC Partner MB500N", ROM_MB500N, "pcpartner_mb500n", L"pcpartner/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, 128, machine_at_mb500n_init, NULL, NULL }, + { "[Socket 5 FX] President Award 430FX PCI",ROM_PRESIDENT, "president", L"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, 128, machine_at_president_init, NULL, NULL }, - { "[Socket 7 FX] Intel Advanced/ATX", ROM_THOR, "intel_thor", L"intel/thor", {{"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, 128, machine_at_thor_init, NULL, nvr_at_close }, - { "[Socket 7 FX] MR Intel Advanced/ATX", ROM_MRTHOR, "intel_mrthor", L"intel/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, 128, machine_at_thor_init, NULL, nvr_at_close }, + { "[Socket 7 FX] Intel Advanced/ATX", ROM_THOR, "intel_thor", L"intel/thor", {{"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, 128, machine_at_thor_init, NULL, NULL }, + { "[Socket 7 FX] MR Intel Advanced/ATX", ROM_MRTHOR, "intel_mrthor", L"intel/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, 128, machine_at_thor_init, NULL, NULL }, - { "[Socket 7 HX] Acer M3a", ROM_ACERM3A, "acer_m3a", L"acer/m3a", {{"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, 128, machine_at_acerm3a_init, NULL, nvr_at_close }, - { "[Socket 7 HX] Acer V35n", ROM_ACERV35N, "acer_v35n", L"acer/v35n", {{"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, 128, machine_at_acerv35n_init, NULL, nvr_at_close }, - { "[Socket 7 HX] AOpen AP53", ROM_AP53, "aopen_ap53", L"aopen/ap53", {{"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, 512, 8, 128, machine_at_ap53_init, NULL, nvr_at_close }, - { "[Socket 7 HX] ASUS P/I-P55T2P4", ROM_P55T2P4, "asus_p55t2p4", L"asus/p55t2p4", {{"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, 512, 8, 128, machine_at_p55t2p4_init, NULL, nvr_at_close }, - { "[Socket 7 HX] SuperMicro Super P55T2S", ROM_P55T2S, "supermicro_p55t2s", L"supermicro/p55t2s", {{"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, 768, 8, 128, machine_at_p55t2s_init, NULL, nvr_at_close }, + { "[Socket 7 HX] Acer M3a", ROM_ACERM3A, "acer_m3a", L"acer/m3a", {{"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, 128, machine_at_acerm3a_init, NULL, NULL }, + { "[Socket 7 HX] Acer V35n", ROM_ACERV35N, "acer_v35n", L"acer/v35n", {{"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, 128, machine_at_acerv35n_init, NULL, NULL }, + { "[Socket 7 HX] AOpen AP53", ROM_AP53, "aopen_ap53", L"aopen/ap53", {{"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, 512, 8, 128, machine_at_ap53_init, NULL, NULL }, + { "[Socket 7 HX] ASUS P/I-P55T2P4", ROM_P55T2P4, "asus_p55t2p4", L"asus/p55t2p4", {{"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, 512, 8, 128, machine_at_p55t2p4_init, NULL, NULL }, + { "[Socket 7 HX] SuperMicro Super P55T2S", ROM_P55T2S, "supermicro_p55t2s", L"supermicro/p55t2s", {{"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, 768, 8, 128, machine_at_p55t2s_init, NULL, NULL }, - { "[Socket 7 VX] ASUS P/I-P55TVP4", ROM_P55TVP4, "asus_p55tvp4", L"asus/p55tvp4", {{"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, 128, machine_at_p55tvp4_init, NULL, nvr_at_close }, - { "[Socket 7 VX] Award 430VX PCI", ROM_430VX, "award_430vx", L"generic/award/430vx", {{"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, 128, machine_at_i430vx_init, NULL, nvr_at_close }, - { "[Socket 7 VX] Epox P55-VA", ROM_P55VA, "epox_p55va", L"epox/p55va", {{"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, 128, machine_at_p55va_init, NULL, nvr_at_close }, + { "[Socket 7 VX] ASUS P/I-P55TVP4", ROM_P55TVP4, "asus_p55tvp4", L"asus/p55tvp4", {{"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, 128, machine_at_p55tvp4_init, NULL, NULL }, + { "[Socket 7 VX] Award 430VX PCI", ROM_430VX, "award_430vx", L"generic/award/430vx", {{"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, 128, machine_at_i430vx_init, NULL, NULL }, + { "[Socket 7 VX] Epox P55-VA", ROM_P55VA, "epox_p55va", L"epox/p55va", {{"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, 128, machine_at_p55va_init, NULL, NULL }, #else - { "[Socket 5 NX] Intel Premiere/PCI II", ROM_PLATO, "intel_plato", L"intel/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, 128, machine_at_plato_init, NULL, nvr_at_close }, + { "[Socket 5 NX] Intel Premiere/PCI II", ROM_PLATO, "intel_plato", L"intel/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, 128, machine_at_plato_init, NULL, NULL }, - { "[Socket 5 FX] ASUS P/I-P54TP4XE", ROM_P54TP4XE, "asus_p54tp4xe", L"asus/p54tp4xe", {{"Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 8, 128, 8, 128, machine_at_p54tp4xe_init, NULL, nvr_at_close }, - { "[Socket 5 FX] Intel Advanced/EV", ROM_ENDEAVOR, "intel_endeavor", L"intel/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, 128, machine_at_endeavor_init, at_endeavor_get_device, nvr_at_close }, - { "[Socket 5 FX] Intel Advanced/ZP", ROM_ZAPPA, "intel_zappa", L"intel/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, 128, machine_at_zappa_init, NULL, nvr_at_close }, - { "[Socket 5 FX] PC Partner MB500N", ROM_MB500N, "pcpartner_mb500n", L"pcpartner/mb500n", {{"Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 8, 128, 8, 128, machine_at_mb500n_init, NULL, nvr_at_close }, - { "[Socket 5 FX] President Award 430FX PCI",ROM_PRESIDENT, "president", L"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, 128, machine_at_president_init, NULL, nvr_at_close }, + { "[Socket 5 FX] ASUS P/I-P54TP4XE", ROM_P54TP4XE, "asus_p54tp4xe", L"asus/p54tp4xe", {{"Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 8, 128, 8, 128, machine_at_p54tp4xe_init, NULL, NULL }, + { "[Socket 5 FX] Intel Advanced/EV", ROM_ENDEAVOR, "intel_endeavor", L"intel/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, 128, machine_at_endeavor_init, at_endeavor_get_device, NULL }, + { "[Socket 5 FX] Intel Advanced/ZP", ROM_ZAPPA, "intel_zappa", L"intel/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, 128, machine_at_zappa_init, NULL, NULL }, + { "[Socket 5 FX] PC Partner MB500N", ROM_MB500N, "pcpartner_mb500n", L"pcpartner/mb500n", {{"Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 8, 128, 8, 128, machine_at_mb500n_init, NULL, NULL }, + { "[Socket 5 FX] President Award 430FX PCI",ROM_PRESIDENT, "president", L"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, 128, machine_at_president_init, NULL, NULL }, - { "[Socket 7 FX] Intel Advanced/ATX", ROM_THOR, "intel_thor", L"intel/thor", {{"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, 128, machine_at_thor_init, NULL, nvr_at_close }, - { "[Socket 7 FX] MR Intel Advanced/ATX", ROM_MRTHOR, "intel_mrthor", L"intel/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, 128, machine_at_thor_init, NULL, nvr_at_close }, + { "[Socket 7 FX] Intel Advanced/ATX", ROM_THOR, "intel_thor", L"intel/thor", {{"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, 128, machine_at_thor_init, NULL, NULL }, + { "[Socket 7 FX] MR Intel Advanced/ATX", ROM_MRTHOR, "intel_mrthor", L"intel/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, 128, machine_at_thor_init, NULL, NULL }, - { "[Socket 7 HX] Acer M3a", ROM_ACERM3A, "acer_m3a", L"acer/m3a", {{"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, 128, machine_at_acerm3a_init, NULL, nvr_at_close }, - { "[Socket 7 HX] Acer V35n", ROM_ACERV35N, "acer_v35n", L"acer/v35n", {{"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, 128, machine_at_acerv35n_init, NULL, nvr_at_close }, - { "[Socket 7 HX] AOpen AP53", ROM_AP53, "aopen_ap53", L"aopen/ap53", {{"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, 512, 8, 128, machine_at_ap53_init, NULL, nvr_at_close }, - { "[Socket 7 HX] ASUS P/I-P55T2P4", ROM_P55T2P4, "asus_p55t2p4", L"asus/p55t2p4", {{"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, 512, 8, 128, machine_at_p55t2p4_init, NULL, nvr_at_close }, - { "[Socket 7 HX] SuperMicro Super P55T2S", ROM_P55T2S, "supermicro_p55t2s", L"supermicro/p55t2s", {{"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, 768, 8, 128, machine_at_p55t2s_init, NULL, nvr_at_close }, + { "[Socket 7 HX] Acer M3a", ROM_ACERM3A, "acer_m3a", L"acer/m3a", {{"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, 128, machine_at_acerm3a_init, NULL, NULL }, + { "[Socket 7 HX] Acer V35n", ROM_ACERV35N, "acer_v35n", L"acer/v35n", {{"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, 128, machine_at_acerv35n_init, NULL, NULL }, + { "[Socket 7 HX] AOpen AP53", ROM_AP53, "aopen_ap53", L"aopen/ap53", {{"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, 512, 8, 128, machine_at_ap53_init, NULL, NULL }, + { "[Socket 7 HX] ASUS P/I-P55T2P4", ROM_P55T2P4, "asus_p55t2p4", L"asus/p55t2p4", {{"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, 512, 8, 128, machine_at_p55t2p4_init, NULL, NULL }, + { "[Socket 7 HX] SuperMicro Super P55T2S", ROM_P55T2S, "supermicro_p55t2s", L"supermicro/p55t2s", {{"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, 768, 8, 128, machine_at_p55t2s_init, NULL, NULL }, - { "[Socket 7 VX] ASUS P/I-P55TVP4", ROM_P55TVP4, "asus_p55tvp4", L"asus/p55tvp4", {{"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, 128, machine_at_p55tvp4_init, NULL, nvr_at_close }, - { "[Socket 7 VX] Award 430VX PCI", ROM_430VX, "award_430vx", L"generic/award/430vx", {{"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, 128, machine_at_i430vx_init, NULL, nvr_at_close }, - { "[Socket 7 VX] Epox P55-VA", ROM_P55VA, "epox_p55va", L"epox/p55va", {{"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, 128, machine_at_p55va_init, NULL, nvr_at_close }, + { "[Socket 7 VX] ASUS P/I-P55TVP4", ROM_P55TVP4, "asus_p55tvp4", L"asus/p55tvp4", {{"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, 128, machine_at_p55tvp4_init, NULL, NULL }, + { "[Socket 7 VX] Award 430VX PCI", ROM_430VX, "award_430vx", L"generic/award/430vx", {{"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, 128, machine_at_i430vx_init, NULL, NULL }, + { "[Socket 7 VX] Epox P55-VA", ROM_P55VA, "epox_p55va", L"epox/p55va", {{"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, 128, machine_at_p55va_init, NULL, NULL }, #endif #if defined(DEV_BRANCH) && defined(USE_I686) - { "[Socket 8 FX] Tyan Titan-Pro AT", ROM_440FX, "tyan_440fx", L"tyan/440fx", {{"Intel", cpus_PentiumPro}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 128, machine_at_i440fx_init, NULL, nvr_at_close }, - { "[Socket 8 FX] Tyan Titan-Pro ATX", ROM_S1668, "tyan_tpatx", L"tyan/tpatx", {{"Intel", cpus_PentiumPro}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 128, machine_at_s1668_init, NULL, nvr_at_close }, + { "[Socket 8 FX] Tyan Titan-Pro AT", ROM_440FX, "tyan_440fx", L"tyan/440fx", {{"Intel", cpus_PentiumPro}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 128, machine_at_i440fx_init, NULL, NULL }, + { "[Socket 8 FX] Tyan Titan-Pro ATX", ROM_S1668, "tyan_tpatx", L"tyan/tpatx", {{"Intel", cpus_PentiumPro}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 128, machine_at_s1668_init, NULL, NULL }, #endif { "", -1, "", NULL, {{"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL } }; @@ -270,11 +270,3 @@ machine_get_machine_from_internal_name(char *s) return(0); } - - -void -machine_close(void) -{ - if (machines[machine].nvr_close) - machines[machine].nvr_close(); -} diff --git a/src/mem.c b/src/mem.c index 7b9fde3..4af38fd 100644 --- a/src/mem.c +++ b/src/mem.c @@ -12,7 +12,7 @@ * the DYNAMIC_TABLES=1 enables this. Will eventually go * away, either way... * - * Version: @(#)mem.c 1.0.8 2018/03/18 + * Version: @(#)mem.c 1.0.9 2018/03/18 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -1622,12 +1622,6 @@ pclog("MEM: reset: previous pages=%08lx, pages_sz=%i\n", pages, pages_sz); #if DYNAMIC_TABLES pclog("MEM: reset: new pages=%08lx, pages_sz=%i\n", pages, pages_sz); #endif - for (c=0; c * @@ -78,6 +78,10 @@ typedef struct _nvr_ { extern int nvr_dosave; +#ifdef EMU_DEVICE_H +extern const device_t at_nvr_device; +extern const device_t amstrad_nvr_device; +#endif extern void nvr_init(nvr_t *); @@ -92,8 +96,10 @@ extern void nvr_time_set(struct tm *); extern wchar_t *nvr_path(wchar_t *str); extern FILE *nvr_fopen(wchar_t *str, wchar_t *mode); +#if 0 extern void nvr_at_init(int irq); extern void nvr_at_close(void); +#endif #endif /*EMU_NVR_H*/ diff --git a/src/nvr_at.c b/src/nvr_at.c index 92e75b9..72e1cde 100644 --- a/src/nvr_at.c +++ b/src/nvr_at.c @@ -189,7 +189,7 @@ * including the later update (DS12887A) which implemented a * "century" register to be compatible with Y2K. * - * Version: @(#)nvr_at.c 1.0.3 2018/03/11 + * Version: @(#)nvr_at.c 1.0.4 2018/03/19 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -279,9 +279,6 @@ #define RTC_REGS 14 /* number of registers */ -static nvr_t *nvrp; - - /* Get the current NVR time. */ static void time_get(uint8_t *regs, struct tm *tm) @@ -380,7 +377,7 @@ check_alarm(uint8_t *regs, int8_t addr) /* Update the NVR registers from the internal clock. */ static void -update_timer(void *priv) +timer_update(void *priv) { nvr_t *nvr = (nvr_t *)priv; struct tm tm; @@ -429,7 +426,7 @@ update_timer(void *priv) /* Re-calculate the timer values. */ static void -rtc_timer_recalc(nvr_t *nvr, int add) +timer_recalc(nvr_t *nvr, int add) { int64_t c, nt; @@ -443,7 +440,7 @@ rtc_timer_recalc(nvr_t *nvr, int add) static void -rtc_timer(void *priv) +timer_intr(void *priv) { nvr_t *nvr = (nvr_t *)priv; @@ -453,7 +450,7 @@ rtc_timer(void *priv) } /* Update our timer interval. */ - rtc_timer_recalc(nvr, 1); + timer_recalc(nvr, 1); nvr->regs[RTC_REGC] |= REGC_PF; if (nvr->regs[RTC_REGB] & REGB_PIE) { @@ -468,7 +465,7 @@ rtc_timer(void *priv) /* Callback from internal clock, another second passed. */ static void -tick_timer(nvr_t *nvr) +timer_tick(nvr_t *nvr) { if (nvr->regs[RTC_REGB] & REGB_SET) return; @@ -494,7 +491,7 @@ nvr_write(uint16_t addr, uint8_t val, void *priv) case RTC_REGA: nvr->regs[RTC_REGA] = val; if (val & REGA_RS) - rtc_timer_recalc(nvr, 1); + timer_recalc(nvr, 1); else nvr->rtctime = 0x7fffffff; break; @@ -577,7 +574,7 @@ nvr_read(uint16_t addr, void *priv) /* Reset the RTC state to 1980/01/01 00:00. */ static void -nvr_at_reset(nvr_t *nvr) +nvr_reset(nvr_t *nvr) { memset(nvr->regs, 0x00, RTC_REGS); nvr->regs[RTC_DOM] = 1; @@ -589,7 +586,7 @@ nvr_at_reset(nvr_t *nvr) /* Process after loading from file. */ static void -nvr_at_start(nvr_t *nvr) +nvr_start(nvr_t *nvr) { struct tm tm; @@ -607,10 +604,82 @@ nvr_at_start(nvr_t *nvr) /* Start the RTC. */ nvr->regs[RTC_REGA] = (REGA_RS2|REGA_RS1); nvr->regs[RTC_REGB] = REGB_2412; - rtc_timer_recalc(nvr, 0); + timer_recalc(nvr, 0); } +static void * +nvr_init_common(int irq) +{ + nvr_t *nvr; + + /* Allocate an NVR for this machine. */ + nvr = (nvr_t *)malloc(sizeof(nvr_t)); + if (nvr == NULL) return(NULL); + memset(nvr, 0x00, sizeof(nvr_t)); + + /* This is machine specific. */ + nvr->size = machines[machine].nvrsz; + nvr->irq = irq; + + /* Set up any local handlers here. */ + nvr->reset = nvr_reset; + nvr->start = nvr_start; + nvr->tick = timer_tick; + + /* Initialize the generic NVR. */ + nvr_init(nvr); + + /* Start the timers. */ + timer_add(timer_update, &nvr->upd_ecount, &nvr->upd_ecount, nvr); + timer_add(timer_intr, &nvr->rtctime, TIMER_ALWAYS_ENABLED, nvr); + + /* Set up the I/O handler for this device. */ + io_sethandler(0x0070, 2, + nvr_read,NULL,NULL, nvr_write,NULL,NULL, nvr); + + return(nvr); +} + + +static void * +nvr_at_init(const device_t *info) +{ + /* The PC/AT and compatibles use IRQ8, Amstrad uses IRQ1. */ + return(nvr_init_common(info->local)); +} + + +static void +nvr_at_close(void *priv) +{ + nvr_t *nvr = (nvr_t *)priv; + + if (nvr->fn != NULL) + free(nvr->fn); + + free(nvr); +} + + +const device_t at_nvr_device = { + "PC/AT NVRAM", + MACHINE_ISA | MACHINE_AT, + 8, + nvr_at_init, nvr_at_close, NULL, + NULL, NULL, NULL, + NULL +}; + +const device_t amstrad_nvr_device = { + "Amstrad NVRAM", + MACHINE_ISA | MACHINE_AT, + 1, + nvr_at_init, nvr_at_close, NULL, + NULL, NULL, NULL, + NULL +}; +#if 0 void nvr_at_init(int irq) { @@ -626,16 +695,16 @@ nvr_at_init(int irq) nvr->irq = irq; /* Set up any local handlers here. */ - nvr->reset = nvr_at_reset; - nvr->start = nvr_at_start; - nvr->tick = tick_timer; + nvr->reset = nvr_reset; + nvr->start = nvr_start; + nvr->tick = timer_tick; /* Initialize the generic NVR. */ nvr_init(nvr); /* Start the timers. */ - timer_add(update_timer, &nvr->upd_ecount, &nvr->upd_ecount, nvr); - timer_add(rtc_timer, &nvr->rtctime, TIMER_ALWAYS_ENABLED, nvr); + timer_add(timer_update, &nvr->upd_ecount, &nvr->upd_ecount, nvr); + timer_add(timer_intr, &nvr->rtctime, TIMER_ALWAYS_ENABLED, nvr); /* Set up the I/O handler for this device. */ io_sethandler(0x0070, 2, @@ -657,3 +726,4 @@ nvr_at_close(void) nvrp = NULL; } +#endif diff --git a/src/pc.c b/src/pc.c index d3391c9..0a8d9a7 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.11 2018/03/18 + * Version: @(#)pc.c 1.0.13 2018/03/19 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -71,7 +71,7 @@ #include "mouse.h" #include "game/gameport.h" #include "floppy/fdd.h" -#include "floppy/fdc.h" +#include "floppy/fdd_common.h" #include "disk/hdd.h" #include "disk/hdc.h" #include "disk/hdc_ide.h" @@ -141,6 +141,7 @@ int sound_is_float = 1, /* (C) sound uses FP values */ GUS = 0, /* (C) sound option */ SSI2001 = 0, /* (C) sound option */ voodoo_enabled = 0; /* (C) video option */ +int joystick_type = 0; /* (C) joystick type */ int mem_size = 0; /* (C) memory size */ int cpu_manufacturer = 0, /* (C) cpu manufacturer */ cpu_use_dynarec = 0, /* (C) cpu uses/needs Dyna */ @@ -597,16 +598,11 @@ pc_reload(wchar_t *fn) config_write(cfg_path); - for (i=0; iexit(i); - if (cdrom_drives[i].host_drive == 200) - image_close(i); - else if ((cdrom_drives[i].host_drive >= 'A') && (cdrom_drives[i].host_drive <= 'Z')) - ioctl_close(i); - else - null_close(i); + cdrom_close(i); } pc_reset_hard_close(); @@ -705,25 +701,21 @@ pc_init_modules(void) ide_init_first(); - cdrom_global_reset(); - zip_global_reset(); - device_init(); timer_reset(); sound_reset(); - fdd_init(); + floppy_init(); sound_init(); + /* FIXME: should be disk_init(). */ hdc_init(hdc_name); - - ide_reset_hard(); - cdrom_hard_reset(); zip_hard_reset(); + ide_reset_hard(); scsi_card_init(); @@ -778,6 +770,7 @@ pc_reset_hard_init(void) timer_reset(); device_init(); + /* FIXME: should all be in sound_reset(). */ midi_device_init(); inital(); sound_reset(); @@ -821,25 +814,16 @@ pc_reset_hard_init(void) /* Reset the video card. */ video_reset(vid_card); + /* FIXME: these, and hdc_reset, should be in disk_reset(). */ + cdrom_hard_reset(); + zip_hard_reset(); + /* Reset the Hard Disk Controller module. */ hdc_reset(); - /* Reconfire and reset the IDE layer. */ - // FIXME: this should have been done via hdc_reset() above.. --FvK - ide_ter_disable(); - ide_qua_disable(); - if (ide_enable[2]) - ide_ter_init(); - if (ide_enable[3]) - ide_qua_init(); - ide_reset_hard(); - /* Reset and reconfigure the SCSI layer. */ scsi_card_init(); - cdrom_hard_reset(); - zip_hard_reset(); - /* Reset and reconfigure the Network Card layer. */ network_reset(); @@ -855,7 +839,7 @@ pc_reset_hard_init(void) if (SSI2001) device_add(&ssi2001_device); - if (joystick_type != 7) + if (joystick_type != JOYSTICK_TYPE_NONE) gameport_update_joystick_type(); if (config_changed) { @@ -902,6 +886,8 @@ pc_reset(int hard) nvr_save(); + machine_close(); + config_save(); if (hard) @@ -934,6 +920,8 @@ pc_close(thread_t *ptr) nvr_save(); + machine_close(); + config_save(); plat_mouse_capture(0); @@ -946,8 +934,7 @@ pc_close(thread_t *ptr) for (i=0; iexit(i); - for (i=0; i * Miran Grca, @@ -186,7 +186,7 @@ scsi_card_init(void) for (i=0; i * Miran Grca, @@ -320,7 +320,7 @@ extern void scsi_mutex(uint8_t start); extern void scsi_card_init(void); extern void scsi_card_reset(void); -extern uint8_t scsi_hard_disks[16][8]; +extern uint8_t scsi_disks[16][8]; extern int scsi_hd_err_stat_to_scsi(uint8_t id); extern int scsi_hd_phase_to_scsi(uint8_t id); diff --git a/src/scsi/scsi_device.c b/src/scsi/scsi_device.c index 5a272c9..79fd414 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.3 2018/03/08 + * Version: @(#)scsi_device.c 1.0.5 2018/03/19 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -111,7 +111,7 @@ scsi_device_target_save_cdb_byte(int lun_type, uint8_t id, uint8_t cdb_byte) shdc[id].request_length = cdb_byte; } else if (lun_type == SCSI_CDROM) { - cdrom[id].request_length = cdb_byte; + cdrom[id]->request_length = cdb_byte; } else if (lun_type == SCSI_ZIP) { zip[id].request_length = cdb_byte; @@ -127,11 +127,11 @@ scsi_device_get_callback(uint8_t scsi_id, uint8_t scsi_lun) switch (lun_type) { case SCSI_DISK: - id = scsi_hard_disks[scsi_id][scsi_lun]; + id = scsi_disks[scsi_id][scsi_lun]; return shdc[id].callback; case SCSI_CDROM: id = scsi_cdrom_drives[scsi_id][scsi_lun]; - return cdrom[id].callback; + return cdrom[id]->callback; case SCSI_ZIP: id = scsi_zip_drives[scsi_id][scsi_lun]; return zip[id].callback; @@ -151,11 +151,11 @@ scsi_device_sense(uint8_t scsi_id, uint8_t scsi_lun) switch (lun_type) { case SCSI_DISK: - id = scsi_hard_disks[scsi_id][scsi_lun]; + id = scsi_disks[scsi_id][scsi_lun]; return shdc[id].sense; case SCSI_CDROM: id = scsi_cdrom_drives[scsi_id][scsi_lun]; - return cdrom[id].sense; + return cdrom[id]->sense; case SCSI_ZIP: id = scsi_zip_drives[scsi_id][scsi_lun]; return zip[id].sense; @@ -175,7 +175,7 @@ scsi_device_request_sense(uint8_t scsi_id, uint8_t scsi_lun, uint8_t *buffer, ui switch (lun_type) { case SCSI_DISK: - id = scsi_hard_disks[scsi_id][scsi_lun]; + id = scsi_disks[scsi_id][scsi_lun]; scsi_hd_request_sense_for_scsi(id, buffer, alloc_length); break; case SCSI_CDROM: @@ -201,7 +201,7 @@ scsi_device_type_data(uint8_t scsi_id, uint8_t scsi_lun, uint8_t *type, uint8_t switch (lun_type) { case SCSI_DISK: - id = scsi_hard_disks[scsi_id][scsi_lun]; + id = scsi_disks[scsi_id][scsi_lun]; *type = 0x00; *rmb = (hdd[id].bus == HDD_BUS_SCSI_REMOVABLE) ? 0x80 : 0x00; break; @@ -228,7 +228,7 @@ scsi_device_read_capacity(uint8_t scsi_id, uint8_t scsi_lun, uint8_t *cdb, uint8 switch (lun_type) { case SCSI_DISK: - id = scsi_hard_disks[scsi_id][scsi_lun]; + id = scsi_disks[scsi_id][scsi_lun]; return scsi_hd_read_capacity(id, cdb, buffer, len); case SCSI_CDROM: id = scsi_cdrom_drives[scsi_id][scsi_lun]; @@ -268,7 +268,7 @@ scsi_device_valid(uint8_t scsi_id, uint8_t scsi_lun) switch (lun_type) { case SCSI_DISK: - id = scsi_hard_disks[scsi_id][scsi_lun]; + id = scsi_disks[scsi_id][scsi_lun]; break; case SCSI_CDROM: id = scsi_cdrom_drives[scsi_id][scsi_lun]; @@ -294,7 +294,7 @@ scsi_device_cdb_length(uint8_t scsi_id, uint8_t scsi_lun) switch (lun_type) { case SCSI_CDROM: id = scsi_cdrom_drives[scsi_id][scsi_lun]; - return cdrom[id].cdb_len; + return cdrom[id]->cdb_len; case SCSI_ZIP: id = scsi_zip_drives[scsi_id][scsi_lun]; return zip[id].cdb_len; @@ -314,7 +314,7 @@ scsi_device_command_phase0(uint8_t scsi_id, uint8_t scsi_lun, int cdb_len, uint8 switch (lun_type) { case SCSI_DISK: - id = scsi_hard_disks[scsi_id][scsi_lun]; + id = scsi_disks[scsi_id][scsi_lun]; break; case SCSI_CDROM: id = scsi_cdrom_drives[scsi_id][scsi_lun]; @@ -363,7 +363,7 @@ void scsi_device_command_phase1(uint8_t scsi_id, uint8_t scsi_lun) switch (lun_type) { case SCSI_DISK: - id = scsi_hard_disks[scsi_id][scsi_lun]; + id = scsi_disks[scsi_id][scsi_lun]; break; case SCSI_CDROM: id = scsi_cdrom_drives[scsi_id][scsi_lun]; diff --git a/src/scsi/scsi_disk.c b/src/scsi/scsi_disk.c index 893a8b1..d36d152 100644 --- a/src/scsi/scsi_disk.c +++ b/src/scsi/scsi_disk.c @@ -8,7 +8,7 @@ * * Emulation of SCSI fixed and removable disks. * - * Version: @(#)scsi_disk.c 1.0.4 2018/03/16 + * Version: @(#)scsi_disk.c 1.0.4 2018/03/19 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -45,8 +45,8 @@ #include "../version.h" #include "../timer.h" #include "../device.h" -#include "../nvr.h" #include "../intel_piix.h" +#include "../nvr.h" #include "../cdrom/cdrom.h" #include "../disk/hdd.h" #include "../disk/hdc.h" @@ -77,10 +77,10 @@ #define scsi_hd_ascq shdc[id].sense[13] -scsi_hard_disk_t shdc[HDD_NUM]; -FILE *shdf[HDD_NUM]; +scsi_disk_t shdc[HDD_NUM]; +FILE *shdf[HDD_NUM]; -uint8_t scsi_hard_disks[16][8] = { +uint8_t scsi_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 }, @@ -255,7 +255,7 @@ scsi_loadhd(int scsi_id, int scsi_lun, int id) { if (! hdd_image_load(id)) { if (hdd[id].bus != HDD_BUS_SCSI_REMOVABLE) { - scsi_hard_disks[scsi_id][scsi_lun] = 0xff; + scsi_disks[scsi_id][scsi_lun] = 0xff; } } else { scsi_disk_insert(id); @@ -296,15 +296,15 @@ build_scsi_hd_map(void) uint8_t i, j; for (i=0; i<16; i++) - memset(scsi_hard_disks[i], 0xff, 8); + memset(scsi_disks[i], 0xff, 8); 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][j] = find_hdd_for_scsi_id(i, j); + if (scsi_disks[i][j] != 0xff) { + memset(&(shdc[scsi_disks[i][j]]), 0, sizeof(shdc[scsi_disks[i][j]])); + if (wcslen(hdd[scsi_disks[i][j]].fn) > 0) { + scsi_loadhd(i, j, scsi_disks[i][j]); } } } diff --git a/src/scsi/scsi_disk.h b/src/scsi/scsi_disk.h index 8824d8c..8917b3d 100644 --- a/src/scsi/scsi_disk.h +++ b/src/scsi/scsi_disk.h @@ -8,7 +8,7 @@ * * Emulation of SCSI fixed and removable disks. * - * Version: @(#)scsi_disk.h 1.0.1 2018/02/14 + * Version: @(#)scsi_disk.h 1.0.2 2018/03/19 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -81,10 +81,10 @@ typedef struct { int block_descriptor_len; uint8_t *temp_buffer; -} scsi_hard_disk_t; +} scsi_disk_t; -extern scsi_hard_disk_t shdc[HDD_NUM]; +extern scsi_disk_t shdc[HDD_NUM]; extern FILE *shdf[HDD_NUM]; diff --git a/src/sound/midi_fluidsynth.c b/src/sound/midi_fluidsynth.c index 59836db..e8e9ea1 100644 --- a/src/sound/midi_fluidsynth.c +++ b/src/sound/midi_fluidsynth.c @@ -17,7 +17,7 @@ * website (for 32bit and 64bit Windows) are working, and * need no additional support files other than sound fonts. * - * Version: @(#)midi_fluidsynth.c 1.0.4 2018/03/15 + * Version: @(#)midi_fluidsynth.c 1.0.5 2018/03/19 * * Code borrowed from scummvm. * @@ -78,7 +78,7 @@ extern void al_set_midi(int freq, int buf_size); extern int soundon; -static void *fluidsynth_handle; /* handle to FluidSynth DLL */ +static void *fluidsynth_handle = NULL; /* handle to FluidSynth DLL */ /* Pointers to the real functions. */ static fluid_settings_t*(*f_new_fluid_settings)(void); diff --git a/src/video/vid_ati28800.c b/src/video/vid_ati28800.c index 2894c88..591479c 100644 --- a/src/video/vid_ati28800.c +++ b/src/video/vid_ati28800.c @@ -8,11 +8,12 @@ * * ATI 28800 emulation (VGA Charger and Korean VGA) * - * Version: @(#)vid_ati28800.c 1.0.7 2018/03/17 + * Version: @(#)vid_ati28800.c 1.0.8 2018/03/18 * * Authors: Fred N. van Kempen, * Miran Grca, * Sarah Walker, + * greatpsycho, * * Copyright 2017,2018 Fred N. van Kempen. * Copyright 2016-2018 Miran Grca. @@ -71,29 +72,26 @@ typedef struct ati28800_t { - svga_t svga; - ati_eeprom_t eeprom; - - rom_t bios_rom; - - uint8_t regs[256]; - int index; + svga_t svga; + ati_eeprom_t eeprom; - uint32_t memory; + rom_t bios_rom; + + uint8_t regs[256]; + int index; + + uint32_t memory; + + uint8_t port_03dd_val; + uint16_t get_korean_font_kind; + int in_get_korean_font_kind_set; + int get_korean_font_enabled; + int get_korean_font_index; + uint16_t get_korean_font_base; + int ksc5601_mode_enabled; } ati28800_t; -int ksc5601_mode_enabled; - - -static uint8_t port_03dd_val; -static uint16_t get_korean_font_kind; -static int in_get_korean_font_kind_set; -static int get_korean_font_enabled; -static int get_korean_font_index; -static uint16_t get_korean_font_base; - - static void ati28800_out(uint16_t addr, uint8_t val, void *p) { ati28800_t *ati28800 = (ati28800_t *)p; @@ -174,45 +172,54 @@ static void ati28800k_out(uint16_t addr, uint8_t val, void *p) switch (addr) { case 0x1CF: - if(ati28800->index == 0xBF && ((ati28800->regs[0xBF] ^ val) & 0x20)) + if (ati28800->index == 0xBF && ((ati28800->regs[0xBF] ^ val) & 0x20)) { - ksc5601_mode_enabled = val & 0x20; + ati28800->ksc5601_mode_enabled = val & 0x20; svga_recalctimings(svga); } ati28800_out(oldaddr, val, p); break; case 0x3DD: - port_03dd_val = val; - if(val == 1) get_korean_font_enabled = 0; - if(in_get_korean_font_kind_set) + ati28800->port_03dd_val = val; + if (val == 1) ati28800->get_korean_font_enabled = 0; + if (ati28800->in_get_korean_font_kind_set) { - get_korean_font_kind = (val << 8) | (get_korean_font_kind & 0xFF); - get_korean_font_enabled = 1; - get_korean_font_index = 0; - in_get_korean_font_kind_set = 0; + ati28800->get_korean_font_kind = (val << 8) | (ati28800->get_korean_font_kind & 0xFF); + ati28800->get_korean_font_enabled = 1; + ati28800->get_korean_font_index = 0; + ati28800->in_get_korean_font_kind_set = 0; } break; case 0x3DE: - in_get_korean_font_kind_set = 0; - switch(port_03dd_val) + ati28800->in_get_korean_font_kind_set = 0; + if (ati28800->get_korean_font_enabled && (ati28800->regs[0xBF] & 0x20)) { - case 0x10: - get_korean_font_base = ((val & 0x7F) << 7) | (get_korean_font_base & 0x7F); - break; - case 8: - get_korean_font_base = (get_korean_font_base & 0x3F80) | (val & 0x7F); - break; - case 1: - get_korean_font_kind = (get_korean_font_kind & 0xFF00) | val; - if(val & 2) in_get_korean_font_kind_set = 1; - break; - default: - break; + if ((ati28800->get_korean_font_base & 0x7F) > 0x20 && (ati28800->get_korean_font_base & 0x7F) < 0x7F) + fontdatksc5601_user[(ati28800->get_korean_font_kind & 4) * 24 + (ati28800->get_korean_font_base & 0x7F) - 0x20].chr[ati28800->get_korean_font_index] = val; + ati28800->get_korean_font_index++; + ati28800->get_korean_font_index &= 0x1F; } - break; - default: - ati28800_out(oldaddr, val, p); + else + { + switch(ati28800->port_03dd_val) + { + case 0x10: + ati28800->get_korean_font_base = ((val & 0x7F) << 7) | (ati28800->get_korean_font_base & 0x7F); + break; + case 8: + ati28800->get_korean_font_base = (ati28800->get_korean_font_base & 0x3F80) | (val & 0x7F); + break; + case 1: + ati28800->get_korean_font_kind = (ati28800->get_korean_font_kind & 0xFF00) | val; + if(val & 2) + ati28800->in_get_korean_font_kind_set = 1; + break; + } + break; + } + default: + ati28800_out(oldaddr, val, p); break; } } @@ -323,20 +330,24 @@ static uint8_t ati28800k_in(uint16_t addr, void *p) switch (addr) { case 0x3DE: - if(get_korean_font_enabled && (ati28800->regs[0xBF] & 0x20)) + if (ati28800->get_korean_font_enabled && (ati28800->regs[0xBF] & 0x20)) { - switch(get_korean_font_kind >> 8) + switch(ati28800->get_korean_font_kind >> 8) { case 4: /* ROM font */ - temp = fontdatksc5601[get_korean_font_base].chr[get_korean_font_index++]; + temp = fontdatksc5601[ati28800->get_korean_font_base].chr[ati28800->get_korean_font_index++]; break; - case 2: /* User defined font - TODO : Should be implemented later */ - temp = 0; + case 2: /* User defined font */ + if((ati28800->get_korean_font_base & 0x7F) > 0x20 && (ati28800->get_korean_font_base & 0x7F) < 0x7F) + temp = fontdatksc5601_user[(ati28800->get_korean_font_kind & 4) * 24 + (ati28800->get_korean_font_base & 0x7F) - 0x20].chr[ati28800->get_korean_font_index]; + else + temp = 0xFF; + ati28800->get_korean_font_index++; break; default: break; } - get_korean_font_index &= 0x1F; + ati28800->get_korean_font_index &= 0x1F; } break; default: @@ -456,9 +467,11 @@ ati28800_init(const device_t *info) void ati28800k_recalctimings(svga_t *svga) { + ati28800_t *ati28800 = (ati28800_t *) svga->p; + ati28800_recalctimings(svga); - if (svga->render == svga_render_text_80 && ksc5601_mode_enabled) + if (svga->render == svga_render_text_80 && ati28800->ksc5601_mode_enabled) { svga->render = svga_render_text_80_ksc5601; } @@ -472,13 +485,13 @@ ati28800k_init(const device_t *info) ati28800->memory = device_get_config_int("memory"); - port_03dd_val = 0; - get_korean_font_base = 0; - get_korean_font_index = 0; - get_korean_font_enabled = 0; - get_korean_font_kind = 0; - in_get_korean_font_kind_set = 0; - ksc5601_mode_enabled = 0; + ati28800->port_03dd_val = 0; + ati28800->get_korean_font_base = 0; + ati28800->get_korean_font_index = 0; + ati28800->get_korean_font_enabled = 0; + ati28800->get_korean_font_kind = 0; + ati28800->in_get_korean_font_kind_set = 0; + ati28800->ksc5601_mode_enabled = 0; rom_init(&ati28800->bios_rom, BIOS_ATIKOR_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); loadfont(FONT_ATIKOR_PATH, 6); @@ -567,7 +580,7 @@ void ati28800k_add_status_info(char *s, int max_len, void *p) svga_add_status_info(s, max_len, &ati28800->svga); - sprintf(temps, "Korean SVGA mode enabled : %s\n\n", ksc5601_mode_enabled ? "Yes" : "No"); + sprintf(temps, "Korean SVGA mode enabled : %s\n\n", ati28800->ksc5601_mode_enabled ? "Yes" : "No"); strncat(s, temps, max_len); } diff --git a/src/video/vid_svga_render.c b/src/video/vid_svga_render.c index 572ce0c..3a9d9a8 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.7 2018/03/17 + * Version: @(#)vid_svga_render.c 1.0.8 2018/03/18 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -330,7 +330,10 @@ void svga_render_text_80_ksc5601(svga_t *svga) dat = svga->vram[charaddr + (svga->sc << 2)]; if(x + xinc < svga->hdisp && (chr & nextchr & 0x80)) { - dat = fontdatksc5601[((chr & 0x7F) << 7) | (nextchr & 0x7F)].chr[svga->sc]; + if((chr == 0xc9 || chr == 0xfe) && (nextchr > 0xa0 && nextchr < 0xff)) + dat = fontdatksc5601_user[(chr == 0xfe ? 96 : 0) + (nextchr & 0x7F) - 0x20].chr[svga->sc]; + else + dat = fontdatksc5601[((chr & 0x7F) << 7) | (nextchr & 0x7F)].chr[svga->sc]; } else { @@ -377,7 +380,10 @@ void svga_render_text_80_ksc5601(svga_t *svga) } } - dat = fontdatksc5601[((chr & 0x7F) << 7) | (nextchr & 0x7F)].chr[svga->sc + 16]; + if((chr == 0xc9 || chr == 0xfe) && (nextchr > 0xa0 && nextchr < 0xff)) + dat = fontdatksc5601_user[(chr == 0xfe ? 96 : 0) + (nextchr & 0x7F) - 0x20].chr[svga->sc + 16]; + else + dat = fontdatksc5601[((chr & 0x7F) << 7) | (nextchr & 0x7F)].chr[svga->sc + 16]; if (svga->seqregs[1] & 1) { for (xx = 0; xx < 8; xx++) diff --git a/src/video/video.c b/src/video/video.c index d090fc7..88d845a 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.6 2018/03/17 + * Version: @(#)video.c 1.0.7 2018/03/18 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -101,7 +101,8 @@ uint8_t fontdat[2048][8]; /* IBM CGA font */ uint8_t fontdatm[2048][16]; /* IBM MDA font */ uint8_t fontdatw[512][32]; /* Wyse700 font */ uint8_t fontdat8x12[256][16]; /* MDSI Genius font */ -dbcs_font_t *fontdatksc5601; /* Korean KSC-5601 font */ +dbcs_font_t *fontdatksc5601, /* Korean KSC-5601 font */ + *fontdatksc5601_user; /* Korean KSC-5601 user defined font */ uint32_t pal_lookup[256]; int xsize = 1, ysize = 1; @@ -684,6 +685,11 @@ video_close(void) free(fontdatksc5601); fontdatksc5601 = NULL; } + + if (fontdatksc5601_user != NULL) { + free(fontdatksc5601_user); + fontdatksc5601_user = NULL; + } } @@ -783,8 +789,11 @@ loadfont(wchar_t *s, int format) if (fontdatksc5601 == NULL) fontdatksc5601 = malloc(16384 * sizeof(dbcs_font_t)); - for (c=0;c<16384;c++) { - for (d=0;d<32;d++) + if (fontdatksc5601_user == NULL) + fontdatksc5601_user = malloc(192 * sizeof(dbcs_font_t)); + + for (c = 0; c < 16384; c++) { + for (d = 0; d < 32; d++) fontdatksc5601[c].chr[d]=getc(f); } break; diff --git a/src/video/video.h b/src/video/video.h index db42e3d..edee329 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.8 2018/03/17 + * Version: @(#)video.h 1.0.9 2018/03/18 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -188,7 +188,8 @@ extern int video_fullscreen, extern int fullchange; extern uint8_t fontdat[2048][8]; extern uint8_t fontdatm[2048][16]; -extern dbcs_font_t *fontdatksc5601; +extern dbcs_font_t *fontdatksc5601, + *fontdatksc5601_user; extern uint32_t *video_6to8, *video_15to32, *video_16to32; diff --git a/src/win/win_cdrom.c b/src/win/win_cdrom.c index de5541c..8af115c 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.4 2018/03/07 + * Version: @(#)win_cdrom.c 1.0.5 2018/03/18 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -94,7 +94,13 @@ cdrom_eject(uint8_t id) IDM_CDROM_HOST_DRIVE | id | ((cdrom_drives[id].host_drive - 'A') << 3), MF_UNCHECKED); } + if (cdrom_image[id].prev_image_path) { + free(cdrom_image[id].prev_image_path); + cdrom_image[id].prev_image_path = NULL; + } + if (cdrom_drives[id].host_drive == 200) { + cdrom_image[id].prev_image_path = (wchar_t *)malloc(1024); wcscpy(cdrom_image[id].prev_image_path, cdrom_image[id].image_path); } cdrom_drives[id].prev_host_drive = cdrom_drives[id].host_drive; @@ -131,6 +137,8 @@ cdrom_reload(uint8_t id) if (cdrom_drives[id].prev_host_drive == 200) { wcscpy(cdrom_image[id].image_path, cdrom_image[id].prev_image_path); + free(cdrom_image[id].prev_image_path); + cdrom_image[id].prev_image_path = NULL; image_open(id, cdrom_image[id].image_path); if (cdrom_drives[id].bus_type) { /* Signal disc change to the emulated machine. */ diff --git a/src/win/win_cdrom_ioctl.c b/src/win/win_cdrom_ioctl.c index cdd04cd..8a5b5b6 100644 --- a/src/win/win_cdrom_ioctl.c +++ b/src/win/win_cdrom_ioctl.c @@ -9,7 +9,7 @@ * Implementation of the CD-ROM host drive IOCTL interface for * Windows using SCSI Passthrough Direct. * - * Version: @(#)cdrom_ioctl.c 1.0.5 2018/03/17 + * Version: @(#)cdrom_ioctl.c 1.0.6 2018/03/18 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -98,67 +98,71 @@ static int ioctl_hopen(uint8_t id); void ioctl_audio_callback(uint8_t id, int16_t *output, int len) { + cdrom_t *dev = cdrom[id]; RAW_READ_INFO in; DWORD count; - if (!cdrom_drives[id].sound_on || (cdrom_ioctl[id].cd_state != CD_PLAYING)) + if (!cdrom_drives[id].sound_on || (dev->cd_state != CD_PLAYING)) { - if (cdrom_ioctl[id].cd_state == CD_PLAYING) + if (dev->cd_state == CD_PLAYING) { - cdrom[id].seek_pos += (len >> 11); + dev->seek_pos += (len >> 11); } memset(output, 0, len * 2); return; } - while (cdrom_ioctl[id].cd_buflen < len) + while (dev->cd_buflen < len) { - if (cdrom[id].seek_pos < cdrom_ioctl[id].cd_end) + if (dev->seek_pos < dev->cd_end) { - in.DiskOffset.LowPart = (cdrom[id].seek_pos - 150) * 2048; + in.DiskOffset.LowPart = (dev->seek_pos - 150) * 2048; in.DiskOffset.HighPart = 0; in.SectorCount = 1; in.TrackMode = CDDA; - if (!DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_CDROM_RAW_READ, &in, sizeof(in), &(cdrom[id].cd_buffer[cdrom_ioctl[id].cd_buflen]), 2352, &count, NULL)) + if (!DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_CDROM_RAW_READ, &in, sizeof(in), &(dev->cd_buffer[dev->cd_buflen]), 2352, &count, NULL)) { - memset(&(cdrom[id].cd_buffer[cdrom_ioctl[id].cd_buflen]), 0, (BUF_SIZE - cdrom_ioctl[id].cd_buflen) * 2); + memset(&(dev->cd_buffer[dev->cd_buflen]), 0, (BUF_SIZE - dev->cd_buflen) * 2); cdrom_ioctl_windows[id].is_playing = 0; ioctl_close(id); - cdrom_ioctl[id].cd_state = CD_STOPPED; - cdrom_ioctl[id].cd_buflen = len; + dev->cd_state = CD_STOPPED; + dev->cd_buflen = len; } else { - cdrom[id].seek_pos++; - cdrom_ioctl[id].cd_buflen += (2352 / 2); + dev->seek_pos++; + dev->cd_buflen += (2352 / 2); } } else { - memset(&(cdrom[id].cd_buffer[cdrom_ioctl[id].cd_buflen]), 0, (BUF_SIZE - cdrom_ioctl[id].cd_buflen) * 2); + memset(&(dev->cd_buffer[dev->cd_buflen]), 0, (BUF_SIZE - dev->cd_buflen) * 2); cdrom_ioctl_windows[id].is_playing = 0; ioctl_close(id); - cdrom_ioctl[id].cd_state = CD_STOPPED; - cdrom_ioctl[id].cd_buflen = len; + dev->cd_state = CD_STOPPED; + dev->cd_buflen = len; } } - memcpy(output, cdrom[id].cd_buffer, len * 2); - memcpy(&cdrom[id].cd_buffer[0], &(cdrom[id].cd_buffer[len]), (BUF_SIZE - len) * 2); - cdrom_ioctl[id].cd_buflen -= len; + memcpy(output, dev->cd_buffer, len * 2); + memcpy(&dev->cd_buffer[0], &(dev->cd_buffer[len]), (BUF_SIZE - len) * 2); + dev->cd_buflen -= len; } void ioctl_audio_stop(uint8_t id) { + cdrom_t *dev = cdrom[id]; + cdrom_ioctl_windows[id].is_playing = 0; ioctl_close(id); - cdrom_ioctl[id].cd_state = CD_STOPPED; + dev->cd_state = CD_STOPPED; } static int get_track_nr(uint8_t id, uint32_t pos) { + cdrom_t *dev = cdrom[id]; int c; int track = 0; - if (!cdrom_ioctl[id].tocvalid) + if (dev->disc_changed) { return 0; } @@ -187,9 +191,10 @@ static int get_track_nr(uint8_t id, uint32_t pos) static uint32_t get_track_msf(uint8_t id, uint32_t track_no) { + cdrom_t *dev = cdrom[id]; int c; - if (!cdrom_ioctl[id].tocvalid) + if (dev->disc_changed) { return 0; } @@ -206,6 +211,7 @@ static uint32_t get_track_msf(uint8_t id, uint32_t track_no) static void ioctl_playaudio(uint8_t id, uint32_t pos, uint32_t len, int ismsf) { + cdrom_t *dev = cdrom[id]; int m = 0, s = 0, f = 0; uint32_t start_msf = 0, end_msf = 0; if (!cdrom_drives[id].host_drive) @@ -242,7 +248,7 @@ static void ioctl_playaudio(uint8_t id, uint32_t pos, uint32_t len, int ismsf) if (pos == 0xffffff) { cdrom_ioctl_log("Playing from current position (MSF)\n"); - pos = cdrom[id].seek_pos; + pos = dev->seek_pos; } else { @@ -259,51 +265,57 @@ static void ioctl_playaudio(uint8_t id, uint32_t pos, uint32_t len, int ismsf) if (pos == 0xffffffff) { cdrom_ioctl_log("Playing from current position\n"); - pos = cdrom[id].seek_pos; + pos = dev->seek_pos; } len += pos; } - cdrom[id].seek_pos = pos; - cdrom_ioctl[id].cd_end = len; - if (cdrom[id].seek_pos < 150) + dev->seek_pos = pos; + dev->cd_end = len; + if (dev->seek_pos < 150) { /* Adjust because the host expects a minimum adjusted LBA of 0 which is equivalent to an absolute LBA of 150. */ - cdrom[id].seek_pos = 150; + dev->seek_pos = 150; } if (!cdrom_ioctl_windows[id].is_playing) { ioctl_hopen(id); cdrom_ioctl_windows[id].is_playing = 1; } - cdrom_ioctl[id].cd_state = CD_PLAYING; + dev->cd_state = CD_PLAYING; } static void ioctl_pause(uint8_t id) { + cdrom_t *dev = cdrom[id]; + if (!cdrom_drives[id].host_drive) { return; } - if (cdrom_ioctl[id].cd_state == CD_PLAYING) + if (dev->cd_state == CD_PLAYING) { - cdrom_ioctl[id].cd_state = CD_PAUSED; + dev->cd_state = CD_PAUSED; } } static void ioctl_resume(uint8_t id) { + cdrom_t *dev = cdrom[id]; + if (!cdrom_drives[id].host_drive) { return; } - if (cdrom_ioctl[id].cd_state == CD_PAUSED) + if (dev->cd_state == CD_PAUSED) { - cdrom_ioctl[id].cd_state = CD_PLAYING; + dev->cd_state = CD_PLAYING; } } static void ioctl_stop(uint8_t id) { + cdrom_t *dev = cdrom[id]; + if (!cdrom_drives[id].host_drive) { return; @@ -313,14 +325,16 @@ static void ioctl_stop(uint8_t id) cdrom_ioctl_windows[id].is_playing = 0; ioctl_close(id); } - cdrom_ioctl[id].cd_state = CD_STOPPED; + dev->cd_state = CD_STOPPED; } static int ioctl_ready(uint8_t id) { + cdrom_t *dev = cdrom[id]; unsigned long size; int temp; CDROM_TOC ltoc; + if (!cdrom_drives[id].host_drive) { return 0; @@ -342,9 +356,9 @@ static int ioctl_ready(uint8_t id) if ((ltoc.TrackData[ltoc.LastTrack].Address[1] != cdrom_ioctl_windows[id].toc.TrackData[cdrom_ioctl_windows[id].toc.LastTrack].Address[1]) || (ltoc.TrackData[ltoc.LastTrack].Address[2] != cdrom_ioctl_windows[id].toc.TrackData[cdrom_ioctl_windows[id].toc.LastTrack].Address[2]) || (ltoc.TrackData[ltoc.LastTrack].Address[3] != cdrom_ioctl_windows[id].toc.TrackData[cdrom_ioctl_windows[id].toc.LastTrack].Address[3]) || - !cdrom_ioctl[id].tocvalid || (cdrom_drives[id].host_drive != cdrom_drives[id].prev_host_drive)) + dev->disc_changed || (cdrom_drives[id].host_drive != cdrom_drives[id].prev_host_drive)) { - cdrom_ioctl[id].cd_state = CD_STOPPED; + dev->cd_state = CD_STOPPED; if (cdrom_drives[id].host_drive != cdrom_drives[id].prev_host_drive) { cdrom_drives[id].prev_host_drive = cdrom_drives[id].host_drive; @@ -356,6 +370,7 @@ static int ioctl_ready(uint8_t id) static int ioctl_get_last_block(uint8_t id, unsigned char starttrack, int msf, int maxlen, int single) { + cdrom_t *dev = cdrom[id]; unsigned long size; int c, d = 0; CDROM_TOC lbtoc; @@ -364,11 +379,11 @@ static int ioctl_get_last_block(uint8_t id, unsigned char starttrack, int msf, i { return 0; } - cdrom_ioctl[id].cd_state = CD_STOPPED; + dev->cd_state = CD_STOPPED; ioctl_hopen(id); DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_CDROM_READ_TOC, NULL, 0, &lbtoc, sizeof(lbtoc), &size, NULL); ioctl_close(id); - cdrom_ioctl[id].tocvalid=1; + dev->disc_changed=0; for (c=d; c <= lbtoc.LastTrack; c++) { uint32_t address; @@ -385,6 +400,7 @@ static void ioctl_read_capacity(uint8_t id, uint8_t *b); static int ioctl_medium_changed(uint8_t id) { + cdrom_t *dev = cdrom[id]; unsigned long size; int temp; CDROM_TOC ltoc; @@ -399,11 +415,11 @@ static int ioctl_medium_changed(uint8_t id) { return 0; /* Drive empty, a not ready handler matter, not disc change. */ } - if (!cdrom_ioctl[id].tocvalid || (cdrom_drives[id].host_drive != cdrom_drives[id].prev_host_drive)) + if (dev->disc_changed || (cdrom_drives[id].host_drive != cdrom_drives[id].prev_host_drive)) { - cdrom_ioctl[id].cd_state = CD_STOPPED; + dev->cd_state = CD_STOPPED; cdrom_ioctl_windows[id].toc = ltoc; - cdrom_ioctl[id].tocvalid = 1; + dev->disc_changed = 0; if (cdrom_drives[id].host_drive != cdrom_drives[id].prev_host_drive) { cdrom_drives[id].prev_host_drive = cdrom_drives[id].host_drive; @@ -412,7 +428,7 @@ static int ioctl_medium_changed(uint8_t id) cdrom_ioctl[id].capacity_read=0; /* With this two lines, we read the READ CAPACITY command output from the host drive into our cache buffer. */ ioctl_read_capacity(id, NULL); ioctl_close(id); - cdrom_ioctl[id].cdrom_capacity = ioctl_get_last_block(id, 0, 0, 4096, 0); + dev->cdrom_capacity = ioctl_get_last_block(id, 0, 0, 4096, 0); return 1; } else @@ -421,14 +437,14 @@ static int ioctl_medium_changed(uint8_t id) (ltoc.TrackData[ltoc.LastTrack].Address[2] != cdrom_ioctl_windows[id].toc.TrackData[cdrom_ioctl_windows[id].toc.LastTrack].Address[2]) || (ltoc.TrackData[ltoc.LastTrack].Address[3] != cdrom_ioctl_windows[id].toc.TrackData[cdrom_ioctl_windows[id].toc.LastTrack].Address[3])) { - cdrom_ioctl[id].cd_state = CD_STOPPED; + dev->cd_state = CD_STOPPED; cdrom_ioctl_log("Setting TOC...\n"); cdrom_ioctl_windows[id].toc = ltoc; ioctl_hopen(id); cdrom_ioctl[id].capacity_read=0; /* With this two lines, we read the READ CAPACITY command output from the host drive into our cache buffer. */ ioctl_read_capacity(id, NULL); ioctl_close(id); - cdrom_ioctl[id].cdrom_capacity = ioctl_get_last_block(id, 0, 0, 4096, 0); + dev->cdrom_capacity = ioctl_get_last_block(id, 0, 0, 4096, 0); return 1; /* TOC mismatches. */ } } @@ -437,6 +453,7 @@ static int ioctl_medium_changed(uint8_t id) static uint8_t ioctl_getcurrentsubchannel(uint8_t id, uint8_t *b, int msf) { + cdrom_t *dev = cdrom[id]; CDROM_SUB_Q_DATA_FORMAT insub; SUB_Q_CHANNEL_DATA sub; unsigned long size; @@ -445,12 +462,12 @@ static uint8_t ioctl_getcurrentsubchannel(uint8_t id, uint8_t *b, int msf) if (!cdrom_drives[id].host_drive) return 0; - cdpos = cdrom[id].seek_pos; + cdpos = dev->seek_pos; - if (cdrom_ioctl[id].last_subchannel_pos == cdpos) + if (dev->last_subchannel_pos == cdpos) { - memcpy(&insub, cdrom_ioctl[id].sub_q_data_format, sizeof(insub)); - memcpy(&sub, cdrom_ioctl[id].sub_q_channel_data, sizeof(sub)); + memcpy(&insub, dev->sub_q_data_format, sizeof(insub)); + memcpy(&sub, dev->sub_q_channel_data, sizeof(sub)); } else { @@ -458,14 +475,14 @@ static uint8_t ioctl_getcurrentsubchannel(uint8_t id, uint8_t *b, int msf) ioctl_hopen(id); DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_CDROM_READ_Q_CHANNEL,&insub,sizeof(insub),&sub,sizeof(sub),&size,NULL); ioctl_close(id); - memset(cdrom_ioctl[id].sub_q_data_format, 0, 16); - memcpy(cdrom_ioctl[id].sub_q_data_format, &insub, sizeof(insub)); - memset(cdrom_ioctl[id].sub_q_channel_data, 0, 256); - memcpy(cdrom_ioctl[id].sub_q_channel_data, &sub, sizeof(sub)); - cdrom_ioctl[id].last_subchannel_pos = cdpos; + memset(dev->sub_q_data_format, 0, 16); + memcpy(dev->sub_q_data_format, &insub, sizeof(insub)); + memset(dev->sub_q_channel_data, 0, 256); + memcpy(dev->sub_q_channel_data, &sub, sizeof(sub)); + dev->last_subchannel_pos = cdpos; } - if (cdrom_ioctl[id].cd_state == CD_PLAYING || cdrom_ioctl[id].cd_state == CD_PAUSED) + if (dev->cd_state == CD_PLAYING || dev->cd_state == CD_PAUSED) { track = get_track_nr(id, cdpos); track_address = cdrom_ioctl_windows[id].toc.TrackData[track].Address[3] + (cdrom_ioctl_windows[id].toc.TrackData[track].Address[2] * 75) + (cdrom_ioctl_windows[id].toc.TrackData[track].Address[1] * 75 * 60); @@ -504,7 +521,7 @@ static uint8_t ioctl_getcurrentsubchannel(uint8_t id, uint8_t *b, int msf) b[pos++] = cdpos & 0xff; } - if (cdrom_ioctl[id].cd_state == CD_PLAYING) return 0x11; + if (dev->cd_state == CD_PLAYING) return 0x11; return 0x12; } @@ -545,6 +562,7 @@ static uint8_t ioctl_getcurrentsubchannel(uint8_t id, uint8_t *b, int msf) static void ioctl_eject(uint8_t id) { + cdrom_t *dev = cdrom[id]; unsigned long size; if (!cdrom_drives[id].host_drive) { @@ -555,7 +573,7 @@ static void ioctl_eject(uint8_t id) cdrom_ioctl_windows[id].is_playing = 0; ioctl_stop(id); } - cdrom_ioctl[id].cd_state = CD_STOPPED; + dev->cd_state = CD_STOPPED; ioctl_hopen(id); DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_STORAGE_EJECT_MEDIA,NULL,0,NULL,0,&size,NULL); ioctl_close(id); @@ -563,6 +581,7 @@ static void ioctl_eject(uint8_t id) static void ioctl_load(uint8_t id) { + cdrom_t *dev = cdrom[id]; unsigned long size; if (!cdrom_drives[id].host_drive) { @@ -573,23 +592,24 @@ static void ioctl_load(uint8_t id) cdrom_ioctl_windows[id].is_playing = 0; ioctl_stop(id); } - cdrom_ioctl[id].cd_state = CD_STOPPED; + dev->cd_state = CD_STOPPED; ioctl_hopen(id); DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_STORAGE_LOAD_MEDIA,NULL,0,NULL,0,&size,NULL); cdrom_ioctl[id].capacity_read=0; /* With this two lines, we read the READ CAPACITY command output from the host drive into our cache buffer. */ ioctl_read_capacity(id, NULL); ioctl_close(id); - cdrom_ioctl[id].cdrom_capacity = ioctl_get_last_block(id, 0, 0, 4096, 0); + dev->cdrom_capacity = ioctl_get_last_block(id, 0, 0, 4096, 0); } static int ioctl_is_track_audio(uint8_t id, uint32_t pos, int ismsf) { + cdrom_t *dev = cdrom[id]; int c; int control = 0; uint32_t track_address = 0; - if (!cdrom_ioctl[id].tocvalid) + if (dev->disc_changed) { return 0; } @@ -618,7 +638,7 @@ static int ioctl_is_track_audio(uint8_t id, uint32_t pos, int ismsf) } /* 00, 08, 10, 18, 20, 28, 30, 38 */ -int flags_to_size[5][32] = { { 0, 0, 2352, 2352, 2352, 2352, 2352, 2352, /* 00-38 (CD-DA) */ +static const int flags_to_size[5][32] = { { 0, 0, 2352, 2352, 2352, 2352, 2352, 2352, /* 00-38 (CD-DA) */ 2352, 2352, 2352, 2352, 2352, 2352, 2352, 2352, /* 40-78 */ 2352, 2352, 2352, 2352, 2352, 2352, 2352, 2352, /* 80-B8 */ 2352, 2352, 2352, 2352, 2352, 2352, 2352, 2352 }, /* C0-F8 */ @@ -649,6 +669,7 @@ static void cdrom_illegal_mode(uint8_t id) cdrom_ascq = 0; } +/* FIXME: allocate on heap! */ struct sptd_with_sense { SCSI_PASS_THROUGH s; @@ -659,6 +680,7 @@ struct sptd_with_sense static int ioctl_get_block_length(uint8_t id, const UCHAR *cdb, int number_of_blocks, int no_length_check) { + cdrom_t *dev = cdrom[id]; int sector_type = 0; int temp_len = 0; @@ -700,7 +722,7 @@ static int ioctl_get_block_length(uint8_t id, const UCHAR *cdb, int number_of_bl case 0xa8: /* READ (6), READ (10), READ (12) */ return 2048 * number_of_blocks; - break; + case 0xb9: sector_type = (cdb[1] >> 2) & 7; if (sector_type == 0) @@ -752,12 +774,12 @@ common_handler: cdrom_illegal_mode(id); return -1; } - return temp_len * cdrom[id].requested_blocks; - break; + return temp_len * dev->requested_blocks; + default: /* Other commands */ return 65534; - break; + } } @@ -812,6 +834,7 @@ static int SCSICommand(uint8_t id, const UCHAR *cdb, UCHAR *buf, uint32_t *len, static void ioctl_read_capacity(uint8_t id, uint8_t *b) { + cdrom_t *dev = cdrom[id]; uint32_t len = 0; const UCHAR cdb[] = { 0x25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; @@ -821,12 +844,12 @@ static void ioctl_read_capacity(uint8_t id, uint8_t *b) { SCSICommand(id, cdb, buf, &len, 1); - memcpy(cdrom_ioctl[id].rcbuf, buf, len); + memcpy(dev->rcbuf, buf, len); cdrom_ioctl[id].capacity_read = 1; } else { - memcpy(b, cdrom_ioctl[id].rcbuf, 16); + memcpy(b, dev->rcbuf, 16); } } @@ -957,23 +980,26 @@ static int ioctl_get_sector_data_type(uint8_t id, uint8_t b0, uint8_t b1, uint8_ static void ioctl_validate_toc(uint8_t id) { + cdrom_t *dev = cdrom[id]; unsigned long size; if (!cdrom_drives[id].host_drive) { return; } - cdrom_ioctl[id].cd_state = CD_STOPPED; + dev->cd_state = CD_STOPPED; ioctl_hopen(id); cdrom_ioctl_log("Validating TOC...\n"); DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_CDROM_READ_TOC, NULL,0,&cdrom_ioctl_windows[id].toc,sizeof(cdrom_ioctl_windows[id].toc),&size,NULL); ioctl_close(id); - cdrom_ioctl[id].tocvalid=1; + dev->disc_changed = 0; } +/* FIXME: malloc this as needed? */ UCHAR buf[262144]; static int ioctl_pass_through(uint8_t id, uint8_t *in_cdb, uint8_t *b, uint32_t *len) { + cdrom_t *dev = cdrom[id]; const UCHAR cdb[12]; int ret = 0; @@ -996,17 +1022,17 @@ static int ioctl_pass_through(uint8_t id, uint8_t *in_cdb, uint8_t *b, uint32_t memcpy((void *) cdb, in_cdb, 12); temp_len = 0; - temp_block_length = ioctl_get_block_length(id, cdb, cdrom[id].requested_blocks, 0); + temp_block_length = ioctl_get_block_length(id, cdb, dev->requested_blocks, 0); if (temp_block_length != -1) { cdrom_ioctl[id].actual_requested_blocks = 1; if ((cdb[0] == 0x08) || (cdb[0] == 0x28) || (cdb[0] == 0xA8) || (cdb[0] == 0xB9) || (cdb[0] == 0xBE)) { buffer_pos = 0; temp_len = 0; - for (i = 0; i < cdrom[id].requested_blocks; i++) + for (i = 0; i < dev->requested_blocks; i++) { cdrom_ioctl_log("CD-ROM %i: ioctl_pass_through(): Transferring block...\n", id, cdrom_ioctl[id].actual_requested_blocks); - cdrom_update_cdb((uint8_t *) cdb, cdrom[id].sector_pos + i, 1); + cdrom_update_cdb((uint8_t *) cdb, dev->sector_pos + i, 1); ret = SCSICommand(id, cdb, b + buffer_pos, &temp_len, 0); buffer_pos += temp_len; } @@ -1029,6 +1055,7 @@ static int ioctl_pass_through(uint8_t id, uint8_t *in_cdb, uint8_t *b, uint32_t static int ioctl_readtoc(uint8_t id, unsigned char *b, unsigned char starttrack, int msf, int maxlen, int single) { + cdrom_t *dev = cdrom[id]; int len=4; DWORD size; int c,d; @@ -1038,11 +1065,11 @@ static int ioctl_readtoc(uint8_t id, unsigned char *b, unsigned char starttrack, { return 0; } - cdrom_ioctl[id].cd_state = CD_STOPPED; + dev->cd_state = CD_STOPPED; ioctl_hopen(id); DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_CDROM_READ_TOC, NULL,0,&cdrom_ioctl_windows[id].toc,sizeof(cdrom_ioctl_windows[id].toc),&size,NULL); ioctl_close(id); - cdrom_ioctl[id].tocvalid = 1; + dev->disc_changed = 0; b[2]=cdrom_ioctl_windows[id].toc.FirstTrack; b[3]=cdrom_ioctl_windows[id].toc.LastTrack; d=0; @@ -1091,6 +1118,7 @@ static int ioctl_readtoc(uint8_t id, unsigned char *b, unsigned char starttrack, static int ioctl_readtoc_session(uint8_t id, unsigned char *b, int msf, int maxlen) { + cdrom_t *dev = cdrom[id]; int len=4; int size; uint32_t temp; @@ -1100,7 +1128,7 @@ static int ioctl_readtoc_session(uint8_t id, unsigned char *b, int msf, int maxl { return 0; } - cdrom_ioctl[id].cd_state = CD_STOPPED; + dev->cd_state = CD_STOPPED; memset(&toc_ex,0,sizeof(toc_ex)); memset(&toc,0,sizeof(toc)); toc_ex.Format=CDROM_READ_TOC_EX_FORMAT_SESSION; @@ -1136,6 +1164,7 @@ static int ioctl_readtoc_session(uint8_t id, unsigned char *b, int msf, int maxl static int ioctl_readtoc_raw(uint8_t id, uint8_t *b, int maxlen) { + cdrom_t *dev = cdrom[id]; int len=4; int size; int i; @@ -1145,7 +1174,7 @@ static int ioctl_readtoc_raw(uint8_t id, uint8_t *b, int maxlen) { return 0; } - cdrom_ioctl[id].cd_state = CD_STOPPED; + dev->cd_state = CD_STOPPED; memset(&toc_ex,0,sizeof(toc_ex)); memset(&toc,0,sizeof(toc)); toc_ex.Format=CDROM_READ_TOC_EX_FORMAT_FULL_TOC; @@ -1205,12 +1234,14 @@ static uint32_t ioctl_size(uint8_t id) static int ioctl_status(uint8_t id) { + cdrom_t *dev = cdrom[id]; + if (!(ioctl_ready(id)) && (cdrom_drives[id].host_drive <= 0)) { return CD_STATUS_EMPTY; } - switch(cdrom_ioctl[id].cd_state) + switch(dev->cd_state) { case CD_PLAYING: return CD_STATUS_PLAYING; @@ -1225,12 +1256,13 @@ static int ioctl_status(uint8_t id) void ioctl_reset(uint8_t id) { + cdrom_t *dev = cdrom[id]; CDROM_TOC ltoc; unsigned long size; if (!cdrom_drives[id].host_drive) { - cdrom_ioctl[id].tocvalid = 0; + dev->disc_changed = 1; return; } @@ -1239,7 +1271,7 @@ void ioctl_reset(uint8_t id) ioctl_close(id); cdrom_ioctl_windows[id].toc = ltoc; - cdrom_ioctl[id].tocvalid = 1; + dev->disc_changed = 0; } int ioctl_hopen(uint8_t id) @@ -1251,11 +1283,14 @@ int ioctl_hopen(uint8_t id) int ioctl_open(uint8_t id, char d) { + cdrom_t *dev = cdrom[id]; + sprintf(cdrom_ioctl[id].ioctl_path,"\\\\.\\%c:",d); - cdrom_ioctl[id].tocvalid=0; + dev->disc_changed = 1; + cdrom_ioctl_windows[id].hIOCTL = CreateFile(cdrom_ioctl[id].ioctl_path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); cdrom_drives[id].handler = &ioctl_cdrom; - cdrom_ioctl[id].ioctl_inited=1; + dev->handler_inited = 1; cdrom_ioctl[id].capacity_read=0; /* With this two lines, we read the READ CAPACITY command output from the host drive into our cache buffer. */ ioctl_read_capacity(id, NULL); CloseHandle(cdrom_ioctl_windows[id].hIOCTL); @@ -1275,10 +1310,12 @@ void ioctl_close(uint8_t id) static void ioctl_exit(uint8_t id) { + cdrom_t *dev = cdrom[id]; + cdrom_ioctl_windows[id].is_playing = 0; ioctl_stop(id); - cdrom_ioctl[id].ioctl_inited=0; - cdrom_ioctl[id].tocvalid=0; + dev->handler_inited = 0; + dev->disc_changed = 1; } static CDROM ioctl_cdrom= diff --git a/src/win/win_new_floppy.c b/src/win/win_new_floppy.c index 562626d..518b53f 100644 --- a/src/win/win_new_floppy.c +++ b/src/win/win_new_floppy.c @@ -8,7 +8,7 @@ * * Implementation of the New Floppy Image dialog. * - * Version: @(#)win_new_floppy.c 1.0.7 2018/03/08 + * Version: @(#)win_new_floppy.c 1.0.8 2018/03/18 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -575,6 +575,7 @@ NewFloppyDialogProcedure(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) int ret; FILE *f; int zip_types; + wchar_t *twcs; switch (message) { case WM_INITDIALOG: @@ -643,6 +644,21 @@ NewFloppyDialogProcedure(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) case IDC_CFILE: if (!file_dlg_w(hdlg, plat_get_string(is_zip ? IDS_2176 : IDS_2174), L"", 1)) { + if (!wcschr(wopenfilestring, L'.')) { + if (wcslen(wopenfilestring) && (wcslen(wopenfilestring) <= 256)) { + twcs = &wopenfilestring[wcslen(wopenfilestring)]; + twcs[0] = L'.'; + if (!is_zip && (filterindex == 3)) { + twcs[1] = L'8'; + twcs[2] = L'6'; + twcs[3] = L'f'; + } else { + twcs[1] = L'i'; + twcs[2] = L'm'; + twcs[3] = L'g'; + } + } + } h = GetDlgItem(hdlg, IDC_EDIT_FILE_NAME); f = _wfopen(wopenfilestring, L"rb"); if (f != NULL) { diff --git a/src/win/win_settings.c b/src/win/win_settings.c index c98ef4b..99d47cc 100644 --- a/src/win/win_settings.c +++ b/src/win/win_settings.c @@ -8,7 +8,7 @@ * * Implementation of the Settings dialog. * - * Version: @(#)win_settings.c 1.0.11 2018/03/15 + * Version: @(#)win_settings.c 1.0.13 2018/03/20 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -1177,7 +1177,7 @@ sound_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) int c = 0; int d = 0; LPTSTR lptsTemp; - const device_t *sound_dev/*, *midi_dev*/; + const device_t *sound_dev; char *s; switch (message) @@ -2756,6 +2756,7 @@ hard_disks_add_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) uint64_t r = 0; uint8_t channel = 0; uint8_t id = 0, lun = 0; + wchar_t *twcs; switch (message) { @@ -3072,6 +3073,16 @@ hd_add_ok_common: 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'; + } + } + if (!(existing & 1)) { f = _wfopen(wopenfilestring, L"rb"); @@ -3988,7 +3999,8 @@ static BOOL win_settings_cdrom_drives_recalc_list(HWND hwndList) 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); + wsprintf(szText, L"%ix", + cdrom_speeds[temp_cdrom_drives[i].speed_idx].speed); lvI.pszText = szText; } lvI.iItem = i; @@ -4318,7 +4330,8 @@ static void win_settings_cdrom_drives_update_item(HWND hwndList, int i) 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); + wsprintf(szText, L"%ix", + cdrom_speeds[temp_cdrom_drives[i].speed_idx].speed); lvI.pszText = szText; } lvI.iItem = i; @@ -4401,10 +4414,11 @@ static void cdrom_add_locations(HWND hdlg) } } + /* Create a list of usable CD-ROM speeds. */ h = GetDlgItem(hdlg, IDC_COMBO_CD_SPEED); - for (i = 1; i <= 72; i++) + for (i = 0; cdrom_speeds[i].speed > 0; i++) { - wsprintf(lptsTemp, L"%ix", i); + wsprintf(lptsTemp, L"%ix", cdrom_speeds[i]); SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); } @@ -4465,7 +4479,7 @@ static void cdrom_recalc_location_controls(HWND hdlg, int assign_id) } else { ShowWindow(h, SW_SHOW); EnableWindow(h, TRUE); - SendMessage(h, CB_SETCURSEL, temp_cdrom_drives[cdlv_current_sel].speed - 1, 0); + SendMessage(h, CB_SETCURSEL, temp_cdrom_drives[cdlv_current_sel].speed_idx, 0); } switch(bus) @@ -5023,7 +5037,7 @@ other_removable_devices_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lPar 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].speed_idx = cdrom_speed_idx(cdrom_speed_idx(CDROM_SPEED_DEFAULT)); if ((b2 == CDROM_BUS_ATAPI_PIO_ONLY) && (temp_cdrom_drives[cdlv_current_sel].bus_type == CDROM_BUS_ATAPI_PIO_AND_DMA)) assign = 0; else if ((b2 == CDROM_BUS_ATAPI_PIO_AND_DMA) && (temp_cdrom_drives[cdlv_current_sel].bus_type == CDROM_BUS_ATAPI_PIO_ONLY)) @@ -5093,7 +5107,7 @@ cdrom_bus_skip: 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; + temp_cdrom_drives[cdlv_current_sel].speed_idx = SendMessage(h, CB_GETCURSEL, 0, 0); h = GetDlgItem(hdlg, IDC_LIST_CDROM_DRIVES); win_settings_cdrom_drives_update_item(h, cdlv_current_sel); rd_ignore_change = 0; diff --git a/src/win/win_stbar.c b/src/win/win_stbar.c index 555e1bd..eda867f 100644 --- a/src/win/win_stbar.c +++ b/src/win/win_stbar.c @@ -8,7 +8,7 @@ * * Implementation of the Status Bar module. * - * Version: @(#)win_stbar.c 1.0.3 2018/03/07 + * Version: @(#)win_stbar.c 1.0.4 2018/03/18 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -1089,10 +1089,8 @@ StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) if (!file_dlg_w_st(hwnd, IDS_2075, cdrom_image[id].image_path, 0)) { cdrom_drives[id].prev_host_drive = cdrom_drives[id].host_drive; wcscpy(temp_path, wopenfilestring); - if ((wcscmp(cdrom_image[id].image_path, temp_path) == 0) && (cdrom_drives[id].host_drive == 200)) { - /* Switching from image to the same image. Do nothing. */ - break; - } + if (!cdrom_image[id].prev_image_path) + cdrom_image[id].prev_image_path = (wchar_t *) malloc(1024); wcscpy(cdrom_image[id].prev_image_path, cdrom_image[id].image_path); cdrom_drives[id].handler->exit(id); cdrom_close(id);