Merge branch 'master' of github.com:OBattler/86Box into tc1995
This commit is contained in:
@@ -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);
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -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:
|
||||
|
@@ -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);
|
||||
|
@@ -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();
|
||||
|
69
src/mem.c
69
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++)
|
||||
{
|
||||
|
@@ -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);
|
||||
|
3
src/pc.c
3
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();
|
||||
}
|
||||
|
||||
|
||||
|
@@ -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
|
||||
};
|
||||
|
@@ -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);
|
||||
|
@@ -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;
|
||||
|
@@ -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++)
|
||||
|
@@ -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);
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user