diff --git a/src/cdrom/cdrom.c b/src/cdrom/cdrom.c index 5a50c0cd7..502821ab6 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.34 2018/03/06 + * Version: @(#)cdrom.c 1.0.35 2018/03/15 * * Author: Miran Grca, * @@ -886,12 +886,6 @@ static void cdrom_unit_attention(uint8_t id) cdrom_log("CD-ROM %i: UNIT ATTENTION\n", id); } -static void cdrom_bus_master_error(uint8_t id) -{ - cdrom_sense_key = cdrom_asc = cdrom_ascq = 0; - cdrom_cmd_error(id); -} - static void cdrom_not_ready(uint8_t id) { cdrom_sense_key = SENSE_NOT_READY; @@ -2722,17 +2716,12 @@ int cdrom_read_from_ide_dma(uint8_t channel) return 0; if (ide_bus_master_write) { - if (ide_bus_master_write(channel >> 1, cdbufferb, cdrom[id].packet_len)) { - cdrom_bus_master_error(id); - cdrom_phase_callback(id); + if (ide_bus_master_write(channel >> 1, cdbufferb, cdrom[id].packet_len)) return 0; - } else + else return 1; - } else { - cdrom_bus_master_error(id); - cdrom_phase_callback(id); + } else return 0; - } return 0; } @@ -2750,6 +2739,12 @@ int cdrom_read_from_scsi_dma(uint8_t scsi_id, uint8_t scsi_lun) return 1; } +void cdrom_irq_raise(uint8_t id) +{ + if (cdrom_drives[id].bus_type < CDROM_BUS_SCSI) + ide_irq_raise(&(ide_drives[cdrom_drives[id].ide_channel])); +} + int cdrom_read_from_dma(uint8_t id) { int32_t *BufLen = &SCSIDevices[cdrom_drives[id].scsi_device_id][cdrom_drives[id].scsi_device_lun].BufferLength; @@ -2770,43 +2765,33 @@ int cdrom_read_from_dma(uint8_t id) cdrom_log("CD-ROM %i: ATAPI Input data length: %i\n", id, cdrom[id].packet_len); ret = cdrom_phase_data_out(id); - if (!ret) { - cdrom_phase_callback(id); - return 0; - } else - return 1; - return 0; + if (ret) { + cdrom_buf_free(id); + cdrom[id].packet_status = CDROM_PHASE_COMPLETE; + cdrom[id].status = READY_STAT; + cdrom[id].phase = 3; + ui_sb_update_icon(SB_CDROM | id, 0); + cdrom_irq_raise(id); + return 1; + } else + return 0; } int cdrom_write_to_ide_dma(uint8_t channel) { uint8_t id = atapi_cdrom_drives[channel]; - if (id > CDROM_NUM) { - cdrom_log("CD-ROM %i: Drive not found\n", id); + if (id > CDROM_NUM) return 0; - } if (ide_bus_master_read) { - if (ide_bus_master_read(channel >> 1, cdbufferb, cdrom[id].packet_len)) { - cdrom_log("CD-ROM %i: ATAPI DMA error\n", id); - cdrom_bus_master_error(id); - cdrom_phase_callback(id); + if (ide_bus_master_read(channel >> 1, cdbufferb, cdrom[id].packet_len)) return 0; - } - else { - cdrom_log("CD-ROM %i: ATAPI DMA success\n", id); + else return 1; - } - } else { - cdrom_log("CD-ROM %i: No bus master\n", id); - cdrom_bus_master_error(id); - cdrom_phase_callback(id); + } else return 0; - } - - return 0; } int cdrom_write_to_scsi_dma(uint8_t scsi_id, uint8_t scsi_lun) @@ -2834,16 +2819,16 @@ int cdrom_write_to_dma(uint8_t id) } else ret = cdrom_write_to_ide_dma(cdrom_drives[id].ide_channel); - if (!ret) + if (ret) { + cdrom_buf_free(id); + cdrom[id].packet_status = CDROM_PHASE_COMPLETE; + cdrom[id].status = READY_STAT; + cdrom[id].phase = 3; + ui_sb_update_icon(SB_CDROM | id, 0); + cdrom_irq_raise(id); + return 1; + } else return 0; - - return 1; -} - -void cdrom_irq_raise(uint8_t id) -{ - if (cdrom_drives[id].bus_type < CDROM_BUS_SCSI) - ide_irq_raise(&(ide_drives[cdrom_drives[id].ide_channel])); } /* If the result is 1, issue an IRQ, otherwise not. */ @@ -2879,12 +2864,6 @@ void cdrom_phase_callback(uint8_t id) case CDROM_PHASE_DATA_OUT_DMA: cdrom_log("CD-ROM %i: CDROM_PHASE_DATA_OUT_DMA\n", id); cdrom_read_from_dma(id); - cdrom_buf_free(id); - cdrom[id].packet_status = CDROM_PHASE_COMPLETE; - cdrom[id].status = READY_STAT; - cdrom[id].phase = 3; - ui_sb_update_icon(SB_CDROM | id, 0); - cdrom_irq_raise(id); return; case CDROM_PHASE_DATA_IN: cdrom_log("CD-ROM %i: CDROM_PHASE_DATA_IN\n", id); @@ -2895,12 +2874,6 @@ void cdrom_phase_callback(uint8_t id) case CDROM_PHASE_DATA_IN_DMA: cdrom_log("CD-ROM %i: CDROM_PHASE_DATA_IN_DMA\n", id); cdrom_write_to_dma(id); - cdrom_buf_free(id); - cdrom[id].packet_status = CDROM_PHASE_COMPLETE; - cdrom[id].status = READY_STAT; - cdrom[id].phase = 3; - ui_sb_update_icon(SB_CDROM | id, 0); - cdrom_irq_raise(id); return; case CDROM_PHASE_ERROR: cdrom_log("CD-ROM %i: CDROM_PHASE_ERROR\n", id); diff --git a/src/cdrom/cdrom.h b/src/cdrom/cdrom.h index d82a002cb..d463e8a25 100644 --- a/src/cdrom/cdrom.h +++ b/src/cdrom/cdrom.h @@ -9,7 +9,7 @@ * Implementation of the CD-ROM drive with SCSI(-like) * commands, for both ATAPI and SCSI usage. * - * Version: @(#)cdrom.h 1.0.5 2018/03/06 + * Version: @(#)cdrom.h 1.0.6 2018/03/15 * * Author: Miran Grca, * @@ -148,6 +148,8 @@ typedef struct { int block_descriptor_len; int init_length; + + int16_t cd_buffer[BUF_SIZE]; } cdrom_t; typedef struct { @@ -187,7 +189,6 @@ typedef struct { int cd_state; uint32_t cd_pos; uint32_t cd_end; - int16_t cd_buffer[BUF_SIZE]; int cd_buflen; } cdrom_image_t; @@ -199,7 +200,6 @@ typedef struct { 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; diff --git a/src/cdrom/cdrom_image.cc b/src/cdrom/cdrom_image.cc index da066c360..f8e32c75c 100644 --- a/src/cdrom/cdrom_image.cc +++ b/src/cdrom/cdrom_image.cc @@ -80,9 +80,9 @@ void image_audio_callback(uint8_t id, int16_t *output, int len) { if (cdrom[id].seek_pos < cdrom_image[id].cd_end) { - if (!cdimg[id]->ReadSector((unsigned char*)&cdrom_image[id].cd_buffer[cdrom_image[id].cd_buflen], true, cdrom[id].seek_pos)) + if (!cdimg[id]->ReadSector((unsigned char*)&cdrom[id].cd_buffer[cdrom_image[id].cd_buflen], true, cdrom[id].seek_pos)) { - memset(&cdrom_image[id].cd_buffer[cdrom_image[id].cd_buflen], 0, (BUF_SIZE - cdrom_image[id].cd_buflen) * 2); + 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; } @@ -94,13 +94,13 @@ void image_audio_callback(uint8_t id, int16_t *output, int len) } else { - memset(&cdrom_image[id].cd_buffer[cdrom_image[id].cd_buflen], 0, (BUF_SIZE - cdrom_image[id].cd_buflen) * 2); + 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; } } - memcpy(output, cdrom_image[id].cd_buffer, len * 2); - memmove(cdrom_image[id].cd_buffer, &cdrom_image[id].cd_buffer[len], (BUF_SIZE - len) * 2); + 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; } diff --git a/src/disk/hdc_ide.c b/src/disk/hdc_ide.c index 91696880b..3d572d035 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.32 2018/03/06 + * Version: @(#)hdc_ide.c 1.0.33 2018/03/15 * * Authors: Sarah Walker, * Miran Grca, @@ -90,6 +90,14 @@ #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 + enum { IDE_NONE = 0, @@ -397,11 +405,13 @@ static void ide_identify(IDE *ide) if (ide->buffer[49] & (1 << 8)) { - ide->buffer[52] = 2 << 8; /*DMA timing mode*/ + ide->buffer[51] = 120; + ide->buffer[52] = 120; /*DMA timing mode*/ ide->buffer[53] |= 6; ide->buffer[62] = 7; ide->buffer[63] = 7; + ide->buffer[64] = 3; /*PIO Modes 3 & 4*/ ide->buffer[88] = 7; if (ide->mdma_mode != -1) { @@ -411,7 +421,10 @@ static void ide_identify(IDE *ide) ide->buffer[88] |= d; else if ((ide->mdma_mode & 0x300) == 0x100) ide->buffer[63] |= d; - else + else if ((ide->mdma_mode & 0x300) == 0x400) { + if ((ide->mdma_mode & 0xff) >= 3) + ide->buffer[64] |= d; + } else ide->buffer[62] |= d; ide_log(" IDENTIFY DMA Mode: %04X, %04X\n", ide->buffer[62], ide->buffer[63]); } @@ -452,10 +465,12 @@ static void ide_atapi_identify(IDE *ide) if (PCI && (ide->board < 2) && (cdrom_drives[cdrom_id].bus_type == CDROM_BUS_ATAPI_PIO_AND_DMA)) { ide->buffer[49] |= 0x100; /* DMA supported */ - ide->buffer[52] = 2 << 8; /*DMA timing mode*/ + ide->buffer[51] = 120; + ide->buffer[52] = 120; /*DMA timing mode*/ ide->buffer[53] = 7; ide->buffer[62] = 7; ide->buffer[63] = 7; + ide->buffer[64] = 3; /*PIO Modes 3 & 4*/ ide->buffer[88] = 7; if (ide->mdma_mode != -1) { @@ -465,12 +480,16 @@ static void ide_atapi_identify(IDE *ide) ide->buffer[88] |= d; else if ((ide->mdma_mode & 0x300) == 0x100) ide->buffer[63] |= d; - else + else if ((ide->mdma_mode & 0x300) == 0x400) { + if ((ide->mdma_mode & 0xff) >= 3) + ide->buffer[64] |= d; + } else ide->buffer[62] |= d; ide_log("PIDENTIFY DMA Mode: %04X, %04X\n", ide->buffer[62], ide->buffer[63]); } - ide->buffer[65] = 0xb4; - ide->buffer[66] = 0xb4; + ide->buffer[65] = 120; + ide->buffer[66] = 120; + ide->buffer[67] = 120; ide->buffer[71] = 30; ide->buffer[72] = 30; ide->buffer[80] = 0x1e; /*ATA-1 to ATA-4 supported*/ @@ -506,26 +525,42 @@ static void ide_atapi_zip_identify(IDE *ide) if (PCI && (ide->board < 2) && (zip_drives[zip_id].bus_type == ZIP_BUS_ATAPI_PIO_AND_DMA)) { ide->buffer[49] |= 0x100; /* DMA supported */ - ide->buffer[52] = 0 << 8; /*DMA timing mode*/ - ide->buffer[53] = 6; - ide->buffer[63] = 3; - ide->buffer[88] = 7; - if (ide->mdma_mode != -1) + if (zip_drives[zip_id].is_250) { + ide->buffer[52] = 0 << 8; /*DMA timing mode*/ + ide->buffer[53] = 6; + ide->buffer[63] = 3; + ide->buffer[88] = 7; + ide->buffer[64] = 0x0001; /*PIO Mode 3*/ + ide->buffer[65] = 0x96; + ide->buffer[66] = 0x96; + ide->buffer[67] = 0xb4; + ide->buffer[68] = 0xb4; + ide->buffer[80] = 0x30; /*Supported ATA versions : ATA/ATAPI-4 ATA/ATAPI-5*/ + ide->buffer[81] = 0x15; /*Maximum ATA revision supported : ATA/ATAPI-5 T13 1321D revision 1*/ + } else { + ide->buffer[51] = 120; + ide->buffer[52] = 120; + ide->buffer[53] = 2; /*Words 64-70 are valid*/ + ide->buffer[63] = 0x0003; /*Multi-word DMA 0 & 1*/ + ide->buffer[64] = 0x0001; /*PIO Mode 3*/ + ide->buffer[65] = 120; + ide->buffer[66] = 120; + ide->buffer[67] = 120; + } + + if (ide->mdma_mode != -1) { d = (ide->mdma_mode & 0xff); d <<= 8; if ((ide->mdma_mode & 0x300) == 0x200) ide->buffer[88] |= d; - else + else if ((ide->mdma_mode & 0x300) == 0x400) { + if ((ide->mdma_mode & 0xff) >= 3) + ide->buffer[64] |= d; + } else ide->buffer[63] |= d; ide_log("PIDENTIFY DMA Mode: %04X, %04X\n", ide->buffer[62], ide->buffer[63]); } - ide->buffer[65] = 0x96; - ide->buffer[66] = 0x96; - ide->buffer[67] = 0xb4; - ide->buffer[68] = 0xb4; - ide->buffer[80] = 0x30; /*Supported ATA versions : ATA/ATAPI-4 ATA/ATAPI-5*/ - ide->buffer[81] = 0x15; /*Maximum ATA revision supported : ATA/ATAPI-5 T13 1321D revision 1*/ } } @@ -631,14 +666,25 @@ static int ide_set_features(IDE *ide) if (ide_drive_is_zip(ide)) { bus = zip_drives[atapi_zip_drives[ide->channel]].bus_type; dma = (bus == ZIP_BUS_ATAPI_PIO_AND_DMA); - max_pio = 0; + if (!PCI || !dma || (ide->board >= 2)) + max_pio = 0; + else + max_pio = 3; max_mdma = 1; } else if (ide_drive_is_cdrom(ide)) { bus = cdrom_drives[atapi_cdrom_drives[ide->channel]].bus_type; dma = (bus == CDROM_BUS_ATAPI_PIO_AND_DMA); + if (!PCI || !dma || (ide->board >= 2)) + max_pio = 0; + else + max_pio = 4; } else { bus = hdd[ide->hdd_num].bus; dma = (bus == HDD_BUS_IDE_PIO_AND_DMA); + if (!PCI || !dma || (ide->board >= 2)) + max_pio = 0; + else + max_pio = 2; } ide_log("Features code %02X\n", features); @@ -647,7 +693,7 @@ static int ide_set_features(IDE *ide) switch(features) { - case 0x03: /* Set transfer mode. */ + case FEATURE_SET_TRANSFER_MODE: /* Set transfer mode. */ ide_log("Transfer mode %02X\n", features_data >> 3); mode = (features_data >> 3); @@ -669,7 +715,7 @@ static int ide_set_features(IDE *ide) { return 0; } - ide->mdma_mode = -1; + ide->mdma_mode = (1 << submode) | 0x400; ide_log("IDE %02X: Setting PIO mode: %02X, %08X\n", ide->channel, submode, ide->mdma_mode); break; @@ -704,8 +750,17 @@ static int ide_set_features(IDE *ide) return 0; } - case 0x66: /* Disable reverting to power on defaults. */ - case 0xCC: /* Enable reverting to power on defaults. */ + case FEATURE_ENABLE_IRQ_OVERLAPPED: + case FEATURE_ENABLE_IRQ_SERVICE: + case FEATURE_DISABLE_IRQ_OVERLAPPED: + case FEATURE_DISABLE_IRQ_SERVICE: + if (!PCI || !dma || (ide->board >= 2)) + return 0; + else + return 1; + + case FEATURE_DISABLE_REVERT: /* Disable reverting to power on defaults. */ + case FEATURE_ENABLE_REVERT: /* Enable reverting to power on defaults. */ return 1; default: diff --git a/src/disk/zip.c b/src/disk/zip.c index cd20e2253..e6b2689de 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.8 2018/03/07 + * Version: @(#)zip.c 1.0.9 2018/03/15 * * Author: Miran Grca, * @@ -1084,12 +1084,6 @@ static void zip_unit_attention(uint8_t id) zip_log("ZIP %i: UNIT ATTENTION\n", id); } -static void zip_bus_master_error(uint8_t id) -{ - zip_sense_key = zip_asc = zip_ascq = 0; - zip_cmd_error(id); -} - static void zip_not_ready(uint8_t id) { zip_sense_key = SENSE_NOT_READY; @@ -2220,19 +2214,12 @@ int zip_read_from_ide_dma(uint8_t channel) return 0; if (ide_bus_master_write) { - if (ide_bus_master_write(channel >> 1, zipbufferb, zip[id].packet_len)) { - zip_bus_master_error(id); - zip_phase_callback(id); + if (ide_bus_master_write(channel >> 1, zipbufferb, zip[id].packet_len)) return 0; - } else + else return 1; - } else { - zip_bus_master_error(id); - zip_phase_callback(id); + } else return 0; - } - - return 0; } int zip_read_from_scsi_dma(uint8_t scsi_id, uint8_t scsi_lun) @@ -2248,6 +2235,12 @@ int zip_read_from_scsi_dma(uint8_t scsi_id, uint8_t scsi_lun) return 1; } +void zip_irq_raise(uint8_t id) +{ + if (zip_drives[id].bus_type < ZIP_BUS_SCSI) + ide_irq_raise(&(ide_drives[zip_drives[id].ide_channel])); +} + int zip_read_from_dma(uint8_t id) { int32_t *BufLen = &SCSIDevices[zip_drives[id].scsi_device_id][zip_drives[id].scsi_device_lun].BufferLength; @@ -2273,13 +2266,17 @@ int zip_read_from_dma(uint8_t id) } ret = zip_phase_data_out(id); - if (!ret) { - zip_phase_callback(id); - return 0; - } else - return 1; - return 0; + if (ret) { + zip_buf_free(id); + zip[id].packet_status = ZIP_PHASE_COMPLETE; + zip[id].status = READY_STAT; + zip[id].phase = 3; + ui_sb_update_icon(SB_ZIP | id, 0); + zip_irq_raise(id); + return 1; + } else + return 0; } int zip_write_to_ide_dma(uint8_t channel) @@ -2292,24 +2289,12 @@ int zip_write_to_ide_dma(uint8_t channel) } if (ide_bus_master_read) { - if (ide_bus_master_read(channel >> 1, zipbufferb, zip[id].packet_len)) { - zip_log("ZIP %i: ATAPI DMA error\n", id); - zip_bus_master_error(id); - zip_phase_callback(id); + if (ide_bus_master_read(channel >> 1, zipbufferb, zip[id].packet_len)) return 0; - } - else { - zip_log("ZIP %i: ATAPI DMA success\n", id); + else return 1; - } - } else { - zip_log("ZIP %i: No bus master\n", id); - zip_bus_master_error(id); - zip_phase_callback(id); + } else return 0; - } - - return 0; } int zip_write_to_scsi_dma(uint8_t scsi_id, uint8_t scsi_lun) @@ -2337,16 +2322,16 @@ int zip_write_to_dma(uint8_t id) } else ret = zip_write_to_ide_dma(zip_drives[id].ide_channel); - if (!ret) + if (ret) { + zip_buf_free(id); + zip[id].packet_status = ZIP_PHASE_COMPLETE; + zip[id].status = READY_STAT; + zip[id].phase = 3; + ui_sb_update_icon(SB_ZIP | id, 0); + zip_irq_raise(id); + return 1; + } else return 0; - - return 1; -} - -void zip_irq_raise(uint8_t id) -{ - if (zip_drives[id].bus_type < ZIP_BUS_SCSI) - ide_irq_raise(&(ide_drives[zip_drives[id].ide_channel])); } /* If the result is 1, issue an IRQ, otherwise not. */ @@ -2382,12 +2367,6 @@ void zip_phase_callback(uint8_t id) case ZIP_PHASE_DATA_OUT_DMA: zip_log("ZIP %i: ZIP_PHASE_DATA_OUT_DMA\n", id); zip_read_from_dma(id); - zip_buf_free(id); - zip[id].packet_status = ZIP_PHASE_COMPLETE; - zip[id].status = READY_STAT; - zip[id].phase = 3; - ui_sb_update_icon(SB_ZIP | id, 0); - zip_irq_raise(id); return; case ZIP_PHASE_DATA_IN: zip_log("ZIP %i: ZIP_PHASE_DATA_IN\n", id); @@ -2398,12 +2377,6 @@ void zip_phase_callback(uint8_t id) case ZIP_PHASE_DATA_IN_DMA: zip_log("ZIP %i: ZIP_PHASE_DATA_IN_DMA\n", id); zip_write_to_dma(id); - zip_buf_free(id); - zip[id].packet_status = ZIP_PHASE_COMPLETE; - zip[id].status = READY_STAT; - zip[id].phase = 3; - ui_sb_update_icon(SB_ZIP | id, 0); - zip_irq_raise(id); return; case ZIP_PHASE_ERROR: zip_log("ZIP %i: ZIP_PHASE_ERROR\n", id); diff --git a/src/machine/machine.c b/src/machine/machine.c index d43707b4f..a000a9fb5 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.29 2018/01/16 + * Version: @(#)machine.c 1.0.30 2018/03/15 * * Authors: Sarah Walker, * Miran Grca, @@ -52,6 +52,9 @@ machine_init(void) AT = IS_ARCH(machine, MACHINE_AT); PCI = IS_ARCH(machine, MACHINE_PCI); + /* Resize the memory. */ + mem_resize(); + /* Load the machine's ROM BIOS. */ rom_load_bios(romset); mem_add_bios(); diff --git a/src/mem.c b/src/mem.c index 93ae0ec47..7bb2a12bc 100644 --- a/src/mem.c +++ b/src/mem.c @@ -1317,6 +1317,42 @@ void mem_a20_init(void) } } +void mem_destroy_pages(void) +{ + if (pages) { + free(pages); + pages = NULL; + } +} + +void mem_resize_pages(void) +{ + int total_size, c; + + mem_destroy_pages(); + + if (AT) { + if (cpu_16bitbus) + total_size = 4096; + else + total_size = 1048576; + } else + total_size = 256; + + pclog("%i pages\n", total_size); + + pages = malloc(total_size * sizeof(page_t)); + + memset(pages, 0, total_size * sizeof(page_t)); + + for (c = 0; c < total_size; c++) + { + pages[c].mem = &ram[c << 12]; + pages[c].write_b = mem_write_ramb_page; + pages[c].write_w = mem_write_ramw_page; + pages[c].write_l = mem_write_raml_page; + } +} void mem_init(void) { @@ -1338,22 +1374,13 @@ void mem_init(void) writelookup2 = malloc(1024 * 1024 * sizeof(uintptr_t)); rom = NULL; biosmask = 0xffff; - pages = malloc((1 << 20) * sizeof(page_t)); - page_lookup = malloc((1 << 20) * sizeof(page_t *)); - - memset(pages, 0, (1 << 20) * sizeof(page_t)); - - memset(page_lookup, 0, (1 << 20) * sizeof(page_t *)); memset(ram_mapped_addr, 0, 64 * sizeof(uint32_t)); - - for (c = 0; c < (1 << 20); c++) - { - pages[c].mem = &ram[c << 12]; - pages[c].write_b = mem_write_ramb_page; - pages[c].write_w = mem_write_ramw_page; - pages[c].write_l = mem_write_raml_page; - } + + page_lookup = malloc((1 << 20) * sizeof(page_t *)); + memset(page_lookup, 0, (1 << 20) * sizeof(page_t *)); + + mem_resize_pages(); memset(isram, 0, sizeof(isram)); for (c = 0; c < (mem_size / 64); c++) @@ -1524,15 +1551,6 @@ void mem_resize() memset(ram, 0, (mem_size + 384) * 1024); } - memset(pages, 0, (1 << 20) * sizeof(page_t)); - for (c = 0; c < (1 << 20); c++) - { - pages[c].mem = &ram[c << 12]; - pages[c].write_b = mem_write_ramb_page; - pages[c].write_w = mem_write_ramw_page; - pages[c].write_l = mem_write_raml_page; - } - memset(isram, 0, sizeof(isram)); for (c = 0; c < (mem_size / 64); c++) { @@ -1541,6 +1559,8 @@ void mem_resize() isram[c] = 0; } + mem_resize_pages(); + memset(_mem_read_b, 0, sizeof(_mem_read_b)); memset(_mem_read_w, 0, sizeof(_mem_read_w)); memset(_mem_read_l, 0, sizeof(_mem_read_l)); @@ -1587,6 +1607,9 @@ void mem_resize() void mem_reset_page_blocks() { int c; + + if (!pages) + return; for (c = 0; c < ((mem_size * 1024) >> 12); c++) { diff --git a/src/mem.h b/src/mem.h index 9a5583d36..e31b3b1b2 100644 --- a/src/mem.h +++ b/src/mem.h @@ -240,6 +240,9 @@ extern void mem_add_bios(void); extern void mem_init(void); extern void mem_resize(void); +extern void mem_destroy_pages(void); +extern void mem_resize_pages(void); + extern uint8_t port_92_read(uint16_t port, void *priv); extern void port_92_write(uint16_t port, uint8_t val, void *priv); extern void port_92_clear_reset(void); diff --git a/src/pc.c b/src/pc.c index 3ecc85ab2..8ec023651 100644 --- a/src/pc.c +++ b/src/pc.c @@ -779,7 +779,6 @@ pc_reset_hard_init(void) /* Reset the general machine support modules. */ io_init(); // cpu_set(); - mem_resize(); timer_reset(); device_init(); @@ -967,6 +966,8 @@ pc_close(thread_t *ptr) network_close(); sound_cd_thread_end(); + + mem_destroy_pages(); } diff --git a/src/sound/snd_audiopci.c b/src/sound/snd_audiopci.c index 979972102..716327192 100644 --- a/src/sound/snd_audiopci.c +++ b/src/sound/snd_audiopci.c @@ -3,6 +3,7 @@ #include #include #include +#include #define HAVE_STDARG_H #include "../86box.h" #include "../device.h" @@ -15,6 +16,12 @@ #include "snd_audiopci.h" +#define N 16 + +#define ES1371_NCoef 91 + +static float low_fir_es1371_coef[ES1371_NCoef]; + typedef struct { uint8_t pci_command, pci_serr; @@ -55,6 +62,9 @@ typedef struct { int16_t buffer_l[64], buffer_r[64]; int buffer_pos, buffer_pos_end; + int filtered_l[32], filtered_r[32]; + int f_pos; + int16_t out_l, out_r; int32_t vol_l, vol_r; @@ -490,6 +500,7 @@ static void es1371_outl(uint16_t port, uint32_t val, void *p) case 0x71: es1371->dac[0].vf = (es1371->dac[0].vf & ~0x1f8000) | ((val & 0xfc00) << 5); es1371->dac[0].ac = (es1371->dac[0].ac & ~0x7f8000) | ((val & 0x00ff) << 15); + es1371->dac[0].f_pos = 0; break; case 0x72: es1371->dac[0].ac = (es1371->dac[0].ac & ~0x7fff) | (val & 0x7fff); @@ -501,6 +512,7 @@ static void es1371_outl(uint16_t port, uint32_t val, void *p) case 0x75: es1371->dac[1].vf = (es1371->dac[1].vf & ~0x1f8000) | ((val & 0xfc00) << 5); es1371->dac[1].ac = (es1371->dac[1].ac & ~0x7f8000) | ((val & 0x00ff) << 15); + es1371->dac[1].f_pos = 0; break; case 0x76: es1371->dac[1].ac = (es1371->dac[1].ac & ~0x7fff) | (val & 0x7fff); @@ -996,15 +1008,60 @@ static void es1371_fetch(es1371_t *es1371, int dac_nr) } } -static void es1371_next_sample(es1371_t *es1371, int dac_nr) +static inline float low_fir_es1371(int dac_nr, int i, float NewSample) { + static float x[2][2][128]; //input samples + static int x_pos[2] = {0, 0}; + float out = 0.0; + int read_pos; + int n_coef; + int pos = x_pos[dac_nr]; + + x[dac_nr][i][pos] = NewSample; + + /*Since only 1/16th of input samples are non-zero, only filter those that + are valid.*/ + read_pos = (pos + 15) & (127 & ~15); + n_coef = (16 - pos) & 15; + + while (n_coef < ES1371_NCoef) + { + out += low_fir_es1371_coef[n_coef] * x[dac_nr][i][read_pos]; + read_pos = (read_pos + 16) & (127 & ~15); + n_coef += 16; + } + + if (i == 1) + { + x_pos[dac_nr] = (x_pos[dac_nr] + 1) & 127; + if (x_pos[dac_nr] > 127) + x_pos[dac_nr] = 0; + } + + return out; +} + +static void es1371_next_sample_filtered(es1371_t *es1371, int dac_nr, int out_idx) +{ + int out_l, out_r; + int c; + if ((es1371->dac[dac_nr].buffer_pos - es1371->dac[dac_nr].buffer_pos_end) >= 0) { es1371_fetch(es1371, dac_nr); } - es1371->dac[dac_nr].out_l = es1371->dac[dac_nr].buffer_l[es1371->dac[dac_nr].buffer_pos & 63]; - es1371->dac[dac_nr].out_r = es1371->dac[dac_nr].buffer_r[es1371->dac[dac_nr].buffer_pos & 63]; + out_l = es1371->dac[dac_nr].buffer_l[es1371->dac[dac_nr].buffer_pos & 63]; + out_r = es1371->dac[dac_nr].buffer_r[es1371->dac[dac_nr].buffer_pos & 63]; + + es1371->dac[dac_nr].filtered_l[out_idx] = (int)low_fir_es1371(dac_nr, 0, (float)out_l); + es1371->dac[dac_nr].filtered_r[out_idx] = (int)low_fir_es1371(dac_nr, 1, (float)out_r); + for (c = 1; c < 16; c++) + { + es1371->dac[dac_nr].filtered_l[out_idx+c] = (int)low_fir_es1371(dac_nr, 0, 0); + es1371->dac[dac_nr].filtered_r[out_idx+c] = (int)low_fir_es1371(dac_nr, 1, 0); + } + // audiopci_log("Use %02x %04x %04x\n", es1371->dac[dac_nr].buffer_pos & 63, es1371->dac[dac_nr].out_l, es1371->dac[dac_nr].out_r); es1371->dac[dac_nr].buffer_pos++; @@ -1012,20 +1069,64 @@ static void es1371_next_sample(es1371_t *es1371, int dac_nr) } //static FILE *es1371_f;//,*es1371_f2; + +static void es1371_update(es1371_t *es1371) +{ + int32_t l, r; + + l = (es1371->dac[0].out_l * es1371->dac[0].vol_l) >> 12; + l += ((es1371->dac[1].out_l * es1371->dac[1].vol_l) >> 12); + r = (es1371->dac[0].out_r * es1371->dac[0].vol_r) >> 12; + r += ((es1371->dac[1].out_r * es1371->dac[1].vol_r) >> 12); + + l >>= 1; + r >>= 1; + + l = (l * es1371->master_vol_l) >> 15; + r = (r * es1371->master_vol_r) >> 15; + + if (l < -32768) + l = -32768; + else if (l > 32767) + l = 32767; + if (r < -32768) + r = -32768; + else if (r > 32767) + r = 32767; + + for (; es1371->pos < sound_pos_global; es1371->pos++) + { + es1371->buffer[es1371->pos*2] = l; + es1371->buffer[es1371->pos*2 + 1] = r; + } +} + static void es1371_poll(void *p) { es1371_t *es1371 = (es1371_t *)p; es1371->dac[1].time += es1371->dac[1].latch; + es1371_update(es1371); + if (es1371->int_ctrl & INT_DAC1_EN) { + int frac = es1371->dac[0].ac & 0x7fff; + int idx = es1371->dac[0].ac >> 15; + int samp1_l = es1371->dac[0].filtered_l[idx]; + int samp1_r = es1371->dac[0].filtered_r[idx]; + int samp2_l = es1371->dac[0].filtered_l[(idx + 1) & 31]; + int samp2_r = es1371->dac[0].filtered_r[(idx + 1) & 31]; + + es1371->dac[0].out_l = ((samp1_l * (0x8000 - frac)) + (samp2_l * frac)) >> 15; + es1371->dac[0].out_r = ((samp1_r * (0x8000 - frac)) + (samp2_r * frac)) >> 15; // audiopci_log("1Samp %i %i %08x\n", es1371->dac[0].curr_samp_ct, es1371->dac[0].samp_ct, es1371->dac[0].ac); - es1371->dac[0].ac += es1371->dac[0].vf; - if (es1371->dac[0].ac & (~0 << (15+4))) + es1371->dac[0].ac += es1371->dac[0].vf; + es1371->dac[0].ac &= ((32 << 15) - 1); + if ((es1371->dac[0].ac >> (15+4)) != es1371->dac[0].f_pos) { - es1371->dac[0].ac &= ~(~0 << (15+4)); - es1371_next_sample(es1371, 0); + es1371_next_sample_filtered(es1371, 0, es1371->dac[0].f_pos ? 16 : 0); + es1371->dac[0].f_pos = (es1371->dac[0].f_pos + 1) & 1; es1371->dac[0].curr_samp_ct++; if (es1371->dac[0].curr_samp_ct == es1371->dac[0].samp_ct) @@ -1043,51 +1144,35 @@ static void es1371_poll(void *p) if (es1371->int_ctrl & INT_DAC2_EN) { + int frac = es1371->dac[1].ac & 0x7fff; + int idx = es1371->dac[1].ac >> 15; + int samp1_l = es1371->dac[1].filtered_l[idx]; + int samp1_r = es1371->dac[1].filtered_r[idx]; + int samp2_l = es1371->dac[1].filtered_l[(idx + 1) & 31]; + int samp2_r = es1371->dac[1].filtered_r[(idx + 1) & 31]; + + es1371->dac[1].out_l = ((samp1_l * (0x8000 - frac)) + (samp2_l * frac)) >> 15; + es1371->dac[1].out_r = ((samp1_r * (0x8000 - frac)) + (samp2_r * frac)) >> 15; // audiopci_log("2Samp %i %i %08x\n", es1371->dac[1].curr_samp_ct, es1371->dac[1].samp_ct, es1371->dac[1].ac); es1371->dac[1].ac += es1371->dac[1].vf; - if (es1371->dac[1].ac & (~0 << (15+4))) + es1371->dac[1].ac &= ((32 << 15) - 1); + if ((es1371->dac[1].ac >> (15+4)) != es1371->dac[1].f_pos) { - es1371->dac[1].ac &= ~(~0 << (15+4)); - es1371_next_sample(es1371, 1); + es1371_next_sample_filtered(es1371, 1, es1371->dac[1].f_pos ? 16 : 0); + es1371->dac[1].f_pos = (es1371->dac[1].f_pos + 1) & 1; es1371->dac[1].curr_samp_ct++; if (es1371->dac[1].curr_samp_ct > es1371->dac[1].samp_ct) { - es1371->dac[1].curr_samp_ct = 0; +// es1371->dac[1].curr_samp_ct = 0; // audiopci_log("DAC2 IRQ\n"); es1371->int_status |= INT_STATUS_DAC2; es1371_update_irqs(es1371); } + if (es1371->dac[1].curr_samp_ct > es1371->dac[1].samp_ct) + es1371->dac[1].curr_samp_ct = 0; } } - - for (; es1371->pos < sound_pos_global; es1371->pos++) - { - int32_t l, r; - - l = (es1371->dac[0].out_l * es1371->dac[0].vol_l) >> 12; - l += ((es1371->dac[1].out_l * es1371->dac[1].vol_l) >> 12); - r = (es1371->dac[0].out_r * es1371->dac[0].vol_r) >> 12; - r += ((es1371->dac[1].out_r * es1371->dac[1].vol_r) >> 12); - - l >>= 1; - r >>= 1; - - l = (l * es1371->master_vol_l) >> 15; - r = (r * es1371->master_vol_r) >> 15; - - if (l < -32768) - l = -32768; - else if (l > 32767) - l = 32767; - if (r < -32768) - r = -32768; - else if (r > 32767) - r = 32767; - - es1371->buffer[es1371->pos*2] = l; - es1371->buffer[es1371->pos*2 + 1] = r; - } } static void es1371_get_buffer(int32_t *buffer, int len, void *p) @@ -1095,12 +1180,48 @@ static void es1371_get_buffer(int32_t *buffer, int len, void *p) es1371_t *es1371 = (es1371_t *)p; int c; + es1371_update(es1371); + for (c = 0; c < len * 2; c++) buffer[c] += (es1371->buffer[c] / 2); es1371->pos = 0; } +static inline double sinc(double x) +{ + return sin(M_PI * x) / (M_PI * x); +} + +static void generate_es1371_filter() +{ + /*Cutoff frequency = 1 / 32*/ + float fC = 1.0 / 32.0; + float gain; + int n; + + for (n = 0; n < ES1371_NCoef; n++) + { + /*Blackman window*/ + double w = 0.42 - (0.5 * cos((2.0*n*M_PI)/(double)(ES1371_NCoef-1))) + (0.08 * cos((4.0*n*M_PI)/(double)(ES1371_NCoef-1))); + /*Sinc filter*/ + double h = sinc(2.0 * fC * ((double)n - ((double)(ES1371_NCoef-1) / 2.0))); + + /*Create windowed-sinc filter*/ + low_fir_es1371_coef[n] = w * h; + } + + low_fir_es1371_coef[(ES1371_NCoef - 1) / 2] = 1.0; + + gain = 0.0; + for (n = 0; n < ES1371_NCoef; n++) + gain += low_fir_es1371_coef[n] / (float)N; + + /*Normalise filter, to produce unity gain*/ + for (n = 0; n < ES1371_NCoef; n++) + low_fir_es1371_coef[n] /= gain; +} + static void *es1371_init() { es1371_t *es1371 = malloc(sizeof(es1371_t)); @@ -1111,6 +1232,8 @@ static void *es1371_init() es1371->card = pci_add_card(PCI_ADD_NORMAL, es1371_pci_read, es1371_pci_write, es1371); timer_add(es1371_poll, &es1371->dac[1].time, TIMER_ALWAYS_ENABLED, es1371); + + generate_es1371_filter(); return es1371; } @@ -1128,6 +1251,54 @@ static void es1371_speed_changed(void *p) es1371->dac[1].latch = (int)((double)TIMER_USEC * (1000000.0 / 48000.0)); } + +void es1371_add_status_info_dac(es1371_t *es1371, char *s, int max_len, int dac_nr) +{ + int ena = dac_nr ? INT_DAC2_EN : INT_DAC1_EN; + char *dac_name = dac_nr ? "DAC2 (Wave)" : "DAC1 (MIDI)"; + char temps[128]; + + if (es1371->int_ctrl & ena) + { + int format = dac_nr ? ((es1371->si_cr >> 2) & 3) : (es1371->si_cr & 3); + double freq = 48000.0 * ((double)es1371->dac[dac_nr].vf / (32768.0 * 16.0)); + + switch (format) + { + case FORMAT_MONO_8: + snprintf(temps, 128, "%s format : 8-bit mono\n", dac_name); + break; + case FORMAT_STEREO_8: + snprintf(temps, 128, "%s format : 8-bit stereo\n", dac_name); + break; + case FORMAT_MONO_16: + snprintf(temps, 128, "%s format : 16-bit mono\n", dac_name); + break; + case FORMAT_STEREO_16: + snprintf(temps, 128, "%s format : 16-bit stereo\n", dac_name); + break; + } + + strncat(s, temps, max_len); + max_len -= strlen(temps); + + snprintf(temps, 128, "Playback frequency : %i Hz\n", (int)freq); + strncat(s, temps, max_len); + } + else + { + snprintf(temps, max_len, "%s stopped\n", dac_name); + strncat(s, temps, max_len); + } +} + +void es1371_add_status_info(char *s, int max_len, void *p) +{ + es1371_t *es1371 = (es1371_t *)p; + + es1371_add_status_info_dac(es1371, s, max_len, 0); + es1371_add_status_info_dac(es1371, s, max_len, 1); +} device_t es1371_device = { @@ -1140,6 +1311,6 @@ device_t es1371_device = NULL, es1371_speed_changed, NULL, - NULL, + es1371_add_status_info, NULL }; diff --git a/src/video/vid_ati18800.c b/src/video/vid_ati18800.c index bb02c5cec..3c047dc7d 100644 --- a/src/video/vid_ati18800.c +++ b/src/video/vid_ati18800.c @@ -8,7 +8,7 @@ * * ATI 18800 emulation (VGA Edge-16) * - * Version: @(#)vid_ati18800.c 1.0.5 2018/02/07 + * Version: @(#)vid_ati18800.c 1.0.6 2018/03/15 * * Authors: Sarah Walker, * Miran Grca, @@ -31,6 +31,7 @@ #include "vid_ati18800.h" #include "vid_ati_eeprom.h" #include "vid_svga.h" +#include "vid_svga_render.h" #define BIOS_ROM_PATH_WONDER L"roms/video/ati18800/VGA_Wonder_V3-1.02.bin" @@ -159,6 +160,28 @@ static uint8_t ati18800_in(uint16_t addr, void *p) return temp; } +static void ati18800_recalctimings(svga_t *svga) +{ + ati18800_t *ati18800 = (ati18800_t *)svga->p; + + if(svga->crtc[0x17] & 4) + { + svga->vtotal <<= 1; + svga->dispend <<= 1; + svga->vsyncstart <<= 1; + svga->split <<= 1; + svga->vblankstart <<= 1; + } + + if (!svga->scrblank && (ati18800->regs[0xb0] & 0x20)) /*Extended 256 colour modes*/ + { + svga->render = svga_render_8bpp_highres; + svga->bpp = 8; + svga->rowoffset <<= 1; + svga->ma <<= 1; + } +} + static void *ati18800_init(device_t *info) { ati18800_t *ati18800 = malloc(sizeof(ati18800_t)); @@ -178,7 +201,7 @@ static void *ati18800_init(device_t *info) }; svga_init(&ati18800->svga, ati18800, 1 << 19, /*512kb*/ - NULL, + ati18800_recalctimings, ati18800_in, ati18800_out, NULL, NULL); diff --git a/src/video/vid_ati28800.c b/src/video/vid_ati28800.c index 5a9c7093f..7c6b64a51 100644 --- a/src/video/vid_ati28800.c +++ b/src/video/vid_ati28800.c @@ -8,7 +8,7 @@ * * ATI 28800 emulation (VGA Charger and Korean VGA) * - * Version: @(#)vid_ati28800.c 1.0.10 2018/03/12 + * Version: @(#)vid_ati28800.c 1.0.11 2018/03/15 * * Authors: Sarah Walker, * Miran Grca, @@ -273,7 +273,7 @@ uint8_t ati28800k_in(uint16_t addr, void *p) switch(get_korean_font_kind >> 8) { case 4: /* ROM font */ - temp = fontdatksc5601[get_korean_font_base][get_korean_font_index++]; + temp = fontdatksc5601[get_korean_font_base].chr[get_korean_font_index++]; break; case 2: /* User defined font - TODO : Should be implemented later */ temp = 0; diff --git a/src/video/vid_svga_render.c b/src/video/vid_svga_render.c index 818e25d57..fcef68564 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.8 2018/03/12 + * Version: @(#)vid_svga_render.c 1.0.9 2018/03/15 * * Authors: Sarah Walker, * Miran Grca, @@ -311,7 +311,7 @@ void svga_render_text_80_ksc5601(svga_t *svga) if(x + xinc < svga->hdisp && (chr & nextchr & 0x80)) { - dat = fontdatksc5601[((chr & 0x7F) << 7) | (nextchr & 0x7F)][svga->sc]; + dat = fontdatksc5601[((chr & 0x7F) << 7) | (nextchr & 0x7F)].chr[svga->sc]; } else { @@ -358,7 +358,7 @@ void svga_render_text_80_ksc5601(svga_t *svga) } } - dat = fontdatksc5601[((chr & 0x7F) << 7) | (nextchr & 0x7F)][svga->sc + 16]; + 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/vid_table.c b/src/video/vid_table.c index b4b239697..d52c6d963 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -8,7 +8,7 @@ * * Define all known video cards. * - * Version: @(#)vid_table.c 1.0.23 2018/03/11 + * Version: @(#)vid_table.c 1.0.24 2018/03/15 * * Authors: Miran Grca, * Fred N. van Kempen, @@ -98,9 +98,9 @@ video_cards[] = { #endif { "[ISA] CGA", "cga", &cga_device, GFX_CGA, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, { "[ISA] Chips & Technologies SuperEGA", "superega", &sega_device, GFX_SUPER_EGA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, - { "[ISA] Cirrus Logic CL-GD 5428", "cl_gd5428_isa", &gd5428_isa_device, GFX_CL_GD5428_ISA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 8, 8, 12}}, - { "[ISA] Cirrus Logic CL-GD 5429", "cl_gd5429_isa", &gd5429_isa_device, GFX_CL_GD5429_ISA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 8, 8, 12}}, - { "[ISA] Cirrus Logic CL-GD 5434", "cl_gd5434_isa", &gd5434_isa_device, GFX_CL_GD5434_ISA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 8, 8, 12}}, + { "[ISA] Cirrus Logic CL-GD 5428", "cl_gd5428_isa", &gd5428_isa_device, GFX_CL_GD5428_ISA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 8, 8, 12}}, + { "[ISA] Cirrus Logic CL-GD 5429", "cl_gd5429_isa", &gd5429_isa_device, GFX_CL_GD5429_ISA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 8, 8, 12}}, + { "[ISA] Cirrus Logic CL-GD 5434", "cl_gd5434_isa", &gd5434_isa_device, GFX_CL_GD5434_ISA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 8, 8, 12}}, { "[ISA] Compaq ATI VGA Wonder XL (ATI-28800-5)","compaq_ati28800", &compaq_ati28800_device, GFX_VGAWONDERXL, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}}, { "[ISA] Compaq CGA", "compaq_cga", &compaq_cga_device, GFX_COMPAQ_CGA, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, { "[ISA] Compaq CGA 2", "compaq_cga_2", &compaq_cga_2_device, GFX_COMPAQ_CGA_2, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, @@ -190,6 +190,11 @@ video_reset(int card) if ((card == GFX_NONE) || \ (card == GFX_INTERNAL) || machines[machine].fixed_gfxcard) return; + if (fontdatksc5601) { + free(fontdatksc5601); + fontdatksc5601 = NULL; + } + pclog("VIDEO: initializing '%s'\n", video_cards[video_old_to_new(card)].name); /* Initialize the video card. */ device_add(video_cards[video_old_to_new(card)].device); diff --git a/src/video/video.c b/src/video/video.c index 19a3a7efc..728b9799d 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.18 2018/03/02 + * Version: @(#)video.c 1.0.19 2018/03/15 * * Authors: Sarah Walker, * Miran Grca, @@ -79,7 +79,7 @@ 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 */ -uint8_t fontdatksc5601[16384][32]; /* Korean KSC-5601 font */ +dbcs_font_t *fontdatksc5601;; /* Korean KSC-5601 font */ uint32_t pal_lookup[256]; int xsize = 1, ysize = 1; @@ -656,6 +656,11 @@ video_close(void) destroy_bitmap(buffer); destroy_bitmap(buffer32); + + if (fontdatksc5601) { + free(fontdatksc5601); + fontdatksc5601 = NULL; + } } @@ -765,11 +770,14 @@ loadfont(wchar_t *s, int format) break; case 6: /* Korean KSC-5601 */ + if (!fontdatksc5601) + fontdatksc5601 = malloc(16384 * sizeof(dbcs_font_t)); + for (c=0;c<16384;c++) { for (d=0;d<32;d++) { - fontdatksc5601[c][d]=getc(f); + fontdatksc5601[c].chr[d]=getc(f); } } break; diff --git a/src/video/video.h b/src/video/video.h index 33d92106c..1813e8115 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.22 2018/03/02 + * Version: @(#)video.h 1.0.23 2018/03/15 * * Authors: Sarah Walker, * Miran Grca, @@ -151,6 +151,10 @@ typedef struct { uint8_t r, g, b; } rgb_t; +typedef struct { + uint8_t chr[32]; +} dbcs_font_t; + typedef rgb_t PALETTE[256]; @@ -171,7 +175,7 @@ extern int video_fullscreen, extern int fullchange; extern uint8_t fontdat[2048][8]; extern uint8_t fontdatm[2048][16]; -extern uint8_t fontdatksc5601[16384][32]; +extern dbcs_font_t *fontdatksc5601; extern uint32_t *video_6to8, *video_15to32, *video_16to32; diff --git a/src/win/win_cdrom_ioctl.c b/src/win/win_cdrom_ioctl.c index b07527f2b..4dd160986 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.12 2018/02/25 + * Version: @(#)cdrom_ioctl.c 1.0.13 2018/03/15 * * Authors: Sarah Walker, * Miran Grca, @@ -98,9 +98,9 @@ void ioctl_audio_callback(uint8_t id, int16_t *output, int len) 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_ioctl[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), &(cdrom[id].cd_buffer[cdrom_ioctl[id].cd_buflen]), 2352, &count, NULL)) { - memset(&(cdrom_ioctl[id].cd_buffer[cdrom_ioctl[id].cd_buflen]), 0, (BUF_SIZE - cdrom_ioctl[id].cd_buflen) * 2); + memset(&(cdrom[id].cd_buffer[cdrom_ioctl[id].cd_buflen]), 0, (BUF_SIZE - cdrom_ioctl[id].cd_buflen) * 2); cdrom_ioctl_windows[id].is_playing = 0; ioctl_close(id); cdrom_ioctl[id].cd_state = CD_STOPPED; @@ -114,15 +114,15 @@ void ioctl_audio_callback(uint8_t id, int16_t *output, int len) } else { - memset(&(cdrom_ioctl[id].cd_buffer[cdrom_ioctl[id].cd_buflen]), 0, (BUF_SIZE - cdrom_ioctl[id].cd_buflen) * 2); + memset(&(cdrom[id].cd_buffer[cdrom_ioctl[id].cd_buflen]), 0, (BUF_SIZE - cdrom_ioctl[id].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; } } - memcpy(output, cdrom_ioctl[id].cd_buffer, len * 2); - memcpy(&cdrom_ioctl[id].cd_buffer[0], &(cdrom_ioctl[id].cd_buffer[len]), (BUF_SIZE - len) * 2); + 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; }