Merge branch 'master' of github.com:OBattler/86Box into tc1995

This commit is contained in:
TC1995
2018-03-15 23:24:19 +01:00
17 changed files with 480 additions and 238 deletions

View File

@@ -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, <mgrca8@gmail.com>
*
@@ -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);

View File

@@ -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, <mgrca8@gmail.com>
*
@@ -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;

View File

@@ -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;
}

View File

@@ -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, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
@@ -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:

View File

@@ -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, <mgrca8@gmail.com>
*
@@ -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);

View File

@@ -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, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
@@ -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();

View File

@@ -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++)
{

View File

@@ -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);

View File

@@ -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();
}

View File

@@ -3,6 +3,7 @@
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <math.h>
#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
};

View File

@@ -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, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
@@ -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);

View File

@@ -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, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
@@ -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;

View File

@@ -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, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
@@ -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++)

View File

@@ -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, <mgrca8@gmail.com>
* Fred N. van Kempen, <decwiz@yahoo.com>
@@ -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);

View File

@@ -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, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
@@ -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;

View File

@@ -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, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
@@ -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;

View File

@@ -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, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
@@ -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;
}