Fixed some CD-ROM-related bugs;

Added sanity checks to the device close functions of the Hercules family graphics cards;
Cleaned up, fixed the bugs in, and reworked the implementation of the Adaptec/BusLogic BIOS command handler;
Removed some scsi_device.c functions that have now become useless;
Removed some excess stuff from pc_init_modules().
This commit is contained in:
OBattler
2018-10-11 10:34:12 +02:00
parent defada30d4
commit b8d3992c07
8 changed files with 283 additions and 281 deletions

View File

@@ -8,7 +8,7 @@
*
* Generic CD-ROM drive core.
*
* Version: @(#)cdrom.c 1.0.0 2018/10/09
* Version: @(#)cdrom.c 1.0.1 2018/10/11
*
* Author: Miran Grca, <mgrca8@gmail.com>
*
@@ -160,6 +160,9 @@ void
cdrom_seek(cdrom_drive_t *dev, uint32_t pos)
{
/* cdrom_log("CD-ROM %i: Seek %08X\n", dev->id, pos); */
if (!dev)
return;
dev->seek_pos = pos;
if (dev->handler && dev->handler->stop)
dev->handler->stop(dev->id);
@@ -234,6 +237,9 @@ cdrom_close_handler(uint8_t id)
{
cdrom_drive_t *dev = &cdrom_drives[id];
if (!dev)
return;
switch (dev->host_drive) {
case 200:
image_close(id);
@@ -242,6 +248,8 @@ cdrom_close_handler(uint8_t id)
null_close(id);
break;
}
dev->handler = NULL;
}

View File

@@ -8,7 +8,7 @@
*
* Main emulator module where most things are controlled.
*
* Version: @(#)pc.c 1.0.81 2018/10/10
* Version: @(#)pc.c 1.0.82 2018/10/11
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
@@ -640,7 +640,6 @@ again2:
}
}
// cpuspeed2 = (AT) ? 2 : 1;
cpuspeed2 = (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type >= CPU_286) ? 2 : 1;
atfullspeed = 0;
@@ -665,15 +664,6 @@ again2:
hdc_init(hdc_name);
scsi_card_init();
/* These now come after as they now attach to the bus. */
scsi_disk_hard_reset();
cdrom_hard_reset();
zip_hard_reset();
pc_full_speed();
shadowbios = 0;

View File

@@ -8,7 +8,7 @@
*
* The generic SCSI device command handler.
*
* Version: @(#)scsi_device.c 1.0.19 2018/10/10
* Version: @(#)scsi_device.c 1.0.20 2018/10/11
*
* Authors: Miran Grca, <mgrca8@gmail.com>
* Fred N. van Kempen, <decwiz@yahoo.com>
@@ -99,22 +99,6 @@ void scsi_device_reset(scsi_device_t *dev)
}
void scsi_device_type_data(scsi_device_t *dev, uint8_t *type, uint8_t *rmb)
{
*rmb = dev->type >> 8;
*type = dev->type & 0xff;
}
int scsi_device_read_capacity(scsi_device_t *dev, uint8_t *cdb, uint8_t *buffer, uint32_t *len)
{
if (dev->read_capacity)
return dev->read_capacity(dev->p, cdb, buffer, len);
else
return 0;
}
int scsi_device_present(scsi_device_t *dev)
{
if (dev->type == SCSI_NONE)

View File

@@ -8,7 +8,7 @@
*
* Definitions for the generic SCSI device command handler.
*
* Version: @(#)scsi_device.h 1.0.11 2018/10/09
* Version: @(#)scsi_device.h 1.0.12 2018/10/11
*
* Authors: Miran Grca, <mgrca8@gmail.com>
* Fred N. van Kempen, <decwiz@yahoo.com>
@@ -129,6 +129,7 @@
#define SENSE_UNIT_ATTENTION 6
/* SCSI Additional Sense Codes */
#define ASC_NONE 0x00
#define ASC_AUDIO_PLAY_OPERATION 0x00
#define ASC_NOT_READY 0x04
#define ASC_ILLEGAL_OPCODE 0x20
@@ -144,6 +145,7 @@
#define ASC_DATA_PHASE_ERROR 0x4b
#define ASC_ILLEGAL_MODE_FOR_THIS_TRACK 0x64
#define ASCQ_NONE 0x00
#define ASCQ_UNIT_IN_PROCESS_OF_BECOMING_READY 0x01
#define ASCQ_INITIALIZING_COMMAND_REQUIRED 0x02
#define ASCQ_CAPACITY_DATA_CHANGED 0x09
@@ -360,13 +362,10 @@ extern int mode_select_terminate(int force);
extern int mode_select_write(uint8_t val);
extern uint8_t *scsi_device_sense(scsi_device_t *dev);
extern void scsi_device_type_data(scsi_device_t *dev, uint8_t *type, uint8_t *rmb);
extern int64_t scsi_device_get_callback(scsi_device_t *dev);
extern void scsi_device_request_sense(scsi_device_t *dev, uint8_t *buffer,
uint8_t alloc_length);
extern void scsi_device_reset(scsi_device_t *dev);
extern int scsi_device_read_capacity(scsi_device_t *dev, uint8_t *cdb,
uint8_t *buffer, uint32_t *len);
extern int scsi_device_present(scsi_device_t *dev);
extern int scsi_device_valid(scsi_device_t *dev);
extern int scsi_device_cdb_length(scsi_device_t *dev);

View File

@@ -11,7 +11,7 @@
* series of SCSI Host Adapters made by Mylex.
* These controllers were designed for various buses.
*
* Version: @(#)scsi_x54x.c 1.0.23 2018/10/09
* Version: @(#)scsi_x54x.c 1.0.24 2018/10/11
*
* Authors: TheCollector1995, <mariogplayer@gmail.com>
* Miran Grca, <mgrca8@gmail.com>
@@ -163,31 +163,48 @@ target_check(uint8_t id)
static uint8_t
completion_code(uint8_t *sense)
{
switch (sense[12]) {
case 0x00:
return(0x00);
uint8_t ret = 0xff;
case 0x20:
return(0x01);
switch (sense[12]) {
case ASC_NONE:
ret = 0x00;
break;
case ASC_ILLEGAL_OPCODE:
case ASC_INV_FIELD_IN_CMD_PACKET:
case ASC_INV_FIELD_IN_PARAMETER_LIST:
case ASC_DATA_PHASE_ERROR:
ret = 0x01;
break;
case 0x12:
case 0x21:
return(0x02);
case ASC_LBA_OUT_OF_RANGE:
ret = 0x02;
break;
case 0x27:
return(0x03);
case ASC_WRITE_PROTECTED:
ret = 0x03;
break;
case 0x14:
case 0x16:
return(0x04);
ret = 0x04;
break;
case ASC_INCOMPATIBLE_FORMAT:
case ASC_ILLEGAL_MODE_FOR_THIS_TRACK:
ret = 0x0c;
break;
case 0x10:
case 0x11:
return(0x10);
ret = 0x10;
break;
case 0x17:
case 0x18:
return(0x11);
ret = 0x11;
break;
case 0x01:
case 0x03:
@@ -209,38 +226,126 @@ completion_code(uint8_t *sense)
case 0x47:
case 0x48:
case 0x49:
return(0x20);
ret = 0x20;
break;
case 0x15:
case 0x02:
return(0x40);
ret = 0x40;
break;
case 0x04:
case 0x28:
case 0x25:
ret = 0x80;
break;
case ASC_NOT_READY:
case ASC_MEDIUM_MAY_HAVE_CHANGED:
case 0x29:
case 0x2a:
return(0xaa);
default:
case ASC_CAPACITY_DATA_CHANGED:
case ASC_MEDIUM_NOT_PRESENT:
ret = 0xaa;
break;
};
return(0xff);
return(ret);
}
static uint8_t
x54x_bios_command_08(uint8_t id, uint8_t *buffer)
x54x_bios_scsi_command(scsi_device_t *dev, uint8_t *cdb, uint8_t *buf, int len, uint32_t addr)
{
uint8_t cdb[12] = { GPCMD_READ_CDROM_CAPACITY, 0,0,0,0,0,0,0,0,0,0,0 };
uint8_t rcbuf[8] = { 0,0,0,0,0,0,0,0 };
uint32_t len = 0;
int i, ret, sc;
scsi_device_t *sd = &scsi_devices[id];
dev->buffer_length = -1;
ret = scsi_device_read_capacity(sd, cdb, rcbuf, &len);
sc = completion_code(scsi_device_sense(sd));
if (ret == 0) return(sc);
scsi_device_command_phase0(dev, cdb);
if (dev->phase == SCSI_PHASE_STATUS)
return(completion_code(scsi_device_sense(dev)));
dev->cmd_buffer = (uint8_t *)malloc(dev->buffer_length);
if (dev->phase == SCSI_PHASE_DATA_IN) {
scsi_device_command_phase1(dev);
if (len > 0) {
if (buf)
memcpy(buf, dev->cmd_buffer, dev->buffer_length);
else
DMAPageWrite(addr, dev->cmd_buffer, dev->buffer_length);
}
} else if (dev->phase == SCSI_PHASE_DATA_OUT) {
if (len > 0) {
if (buf)
memcpy(dev->cmd_buffer, buf, dev->buffer_length);
else
DMAPageRead(addr, dev->cmd_buffer, dev->buffer_length);
}
scsi_device_command_phase1(dev);
}
if (dev->cmd_buffer != NULL) {
free(dev->cmd_buffer);
dev->cmd_buffer = NULL;
}
return(completion_code(scsi_device_sense(dev)));
}
static uint8_t
x54x_bios_read_capacity(scsi_device_t *sd, uint8_t *buf)
{
uint8_t *cdb;
uint8_t ret;
cdb = (uint8_t *) malloc(12);
memset(cdb, 0, 12);
cdb[0] = GPCMD_READ_CDROM_CAPACITY;
memset(buf, 0, 8);
ret = x54x_bios_scsi_command(sd, cdb, buf, 8, 0);
free(cdb);
return(ret);
}
static uint8_t
x54x_bios_inquiry(scsi_device_t *sd, uint8_t *buf)
{
uint8_t *cdb;
uint8_t ret;
cdb = (uint8_t *) malloc(12);
memset(cdb, 0, 12);
cdb[0] = GPCMD_INQUIRY;
cdb[4] = 36;
memset(buf, 0, 36);
ret = x54x_bios_scsi_command(sd, cdb, buf, 36, 0);
free(cdb);
return(ret);
}
static uint8_t
x54x_bios_command_08(scsi_device_t *sd, uint8_t *buffer)
{
uint8_t *rcbuf;
uint8_t ret;
int i;
memset(buffer, 0x00, 6);
rcbuf = (uint8_t *) malloc(8);
ret = x54x_bios_read_capacity(sd, rcbuf);
if (ret) {
free(rcbuf);
return(ret);
}
memset(buffer, 0x00, 6);
for (i=0; i<4; i++)
@@ -250,32 +355,49 @@ x54x_bios_command_08(uint8_t id, uint8_t *buffer)
x54x_log("BIOS Command 0x08: %02X %02X %02X %02X %02X %02X\n",
buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5]);
free(rcbuf);
return(0);
}
static int
x54x_bios_command_15(uint8_t id, uint8_t *buffer)
x54x_bios_command_15(scsi_device_t *sd, uint8_t *buffer)
{
uint8_t cdb[12] = { GPCMD_READ_CDROM_CAPACITY, 0,0,0,0,0,0,0,0,0,0,0 };
uint8_t rcbuf[8] = { 0,0,0,0,0,0,0,0 };
uint32_t len = 0;
int i, ret, sc;
scsi_device_t *sd = &scsi_devices[id];
ret = scsi_device_read_capacity(sd, cdb, rcbuf, &len);
sc = completion_code(scsi_device_sense(sd));
uint8_t *inqbuf, *rcbuf;
uint8_t ret;
int i;
memset(buffer, 0x00, 6);
for (i=0; i<4; i++)
buffer[i] = (ret == 0) ? 0 : rcbuf[i];
scsi_device_type_data(sd, &(buffer[4]), &(buffer[5]));
inqbuf = (uint8_t *) malloc(36);
ret = x54x_bios_inquiry(sd, inqbuf);
if (ret) {
free(inqbuf);
return(ret);
}
buffer[4] = inqbuf[0];
buffer[5] = inqbuf[1];
rcbuf = (uint8_t *) malloc(8);
ret = x54x_bios_read_capacity(sd, rcbuf);
if (ret) {
free(rcbuf);
free(inqbuf);
return(ret);
}
for (i = 0; i < 4; i++)
buffer[i] = rcbuf[i];
x54x_log("BIOS Command 0x15: %02X %02X %02X %02X %02X %02X\n",
buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5]);
return(sc);
free(rcbuf);
free(inqbuf);
return(0);
}
@@ -283,12 +405,16 @@ x54x_bios_command_15(uint8_t id, uint8_t *buffer)
static uint8_t
x54x_bios_command(x54x_t *x54x, uint8_t max_id, BIOSCMD *cmd, int8_t islba)
{
const int bios_cmd_to_scsi[18] = { 0, 0, GPCMD_READ_10, GPCMD_WRITE_10, GPCMD_VERIFY_10, 0, 0,
GPCMD_FORMAT_UNIT, 0, 0, 0, 0, GPCMD_SEEK_10, 0, 0, 0,
GPCMD_TEST_UNIT_READY, GPCMD_REZERO_UNIT };
uint8_t cdb[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
scsi_device_t *dev;
uint32_t dma_address;
uint8_t *buf;
scsi_device_t *dev = NULL;
uint32_t dma_address = 0;
uint32_t lba;
int sector_len = cmd->secount;
uint8_t ret;
uint8_t ret = 0x00;
if (islba)
lba = lba32_blk(cmd);
@@ -300,41 +426,44 @@ x54x_bios_command(x54x_t *x54x, uint8_t max_id, BIOSCMD *cmd, int8_t islba)
if ((cmd->id > max_id) || (cmd->lun > 7)) {
x54x_log("BIOS Target ID %i or LUN %i are above maximum\n",
cmd->id, cmd->lun);
return(0x80);
ret = 0x80;
}
if (cmd->lun) {
x54x_log("BIOS Target LUN is not 0\n");
return(0x80);
ret = 0x80;
}
if (!ret) {
/* Get pointer to selected device. */
dev = &scsi_devices[cmd->id];
dev->buffer_length = 0;
if (! scsi_device_present(dev)) {
x54x_log("BIOS Target ID %i has no device attached\n", cmd->id);
return(0x80);
}
if ((dev->type == SCSI_REMOVABLE_CDROM) && !x54x->cdrom_boot) {
x54x_log("BIOS Target ID %i is CD-ROM on unsupported BIOS\n", cmd->id);
return(0x80);
}
dma_address = ADDR_TO_U32(cmd->dma_address);
x54x_log("BIOS Data Buffer write: length %d, pointer 0x%04X\n",
sector_len, dma_address);
if (dev->cmd_buffer != NULL) {
free(dev->cmd_buffer);
dev->cmd_buffer = NULL;
}
switch(cmd->command) {
if (! scsi_device_present(dev)) {
x54x_log("BIOS Target ID %i has no device attached\n", cmd->id);
ret = 0x80;
} else {
if ((dev->type == SCSI_REMOVABLE_CDROM) && !x54x->cdrom_boot) {
x54x_log("BIOS Target ID %i is CD-ROM on unsupported BIOS\n", cmd->id);
return(0x80);
} else {
dma_address = ADDR_TO_U32(cmd->dma_address);
x54x_log("BIOS Data Buffer write: length %d, pointer 0x%04X\n",
sector_len, dma_address);
}
}
}
if (!ret) switch(cmd->command) {
case 0x00: /* Reset Disk System, in practice it's a nop */
return(0);
ret = 0x00;
break;
case 0x01: /* Read Status of Last Operation */
target_check(cmd->id);
@@ -355,194 +484,70 @@ x54x_bios_command(x54x_t *x54x, uint8_t max_id, BIOSCMD *cmd, int8_t islba)
scsi_device_sense(dev), 14);
}
if (dev->cmd_buffer != NULL) {
if (dev && (dev->cmd_buffer != NULL)) {
free(dev->cmd_buffer);
dev->cmd_buffer = NULL;
}
return(0);
break;
case 0x02: /* Read Desired Sectors to Memory */
target_check(cmd->id);
dev->buffer_length = -1;
cdb[0] = GPCMD_READ_10;
cdb[1] = (cmd->lun & 7) << 5;
cdb[2] = (lba >> 24) & 0xff;
cdb[3] = (lba >> 16) & 0xff;
cdb[4] = (lba >> 8) & 0xff;
cdb[5] = lba & 0xff;
cdb[7] = 0;
cdb[8] = sector_len;
#if 0
x54x_log("BIOS CMD(READ, %08lx, %d)\n", lba, cmd->secount);
#endif
scsi_device_command_phase0(dev, cdb);
if (dev->phase == SCSI_PHASE_STATUS)
goto skip_read_phase1;
dev->cmd_buffer = (uint8_t *)malloc(dev->buffer_length);
scsi_device_command_phase1(dev);
if (sector_len > 0) {
x54x_log("BIOS DMA: Reading %i bytes at %08X\n",
dev->buffer_length, dma_address);
DMAPageWrite(dma_address,
dev->cmd_buffer, dev->buffer_length);
}
skip_read_phase1:
if (dev->cmd_buffer != NULL) {
free(dev->cmd_buffer);
dev->cmd_buffer = NULL;
}
return(completion_code(scsi_device_sense(dev)));
case 0x03: /* Write Desired Sectors from Memory */
target_check(cmd->id);
dev->buffer_length = -1;
cdb[0] = GPCMD_WRITE_10;
cdb[1] = (cmd->lun & 7) << 5;
cdb[2] = (lba >> 24) & 0xff;
cdb[3] = (lba >> 16) & 0xff;
cdb[4] = (lba >> 8) & 0xff;
cdb[5] = lba & 0xff;
cdb[7] = 0;
cdb[8] = sector_len;
#if 0
x54x_log("BIOS CMD(WRITE, %08lx, %d)\n", lba, cmd->secount);
#endif
scsi_device_command_phase0(dev, cdb);
if (dev->phase == SCSI_PHASE_STATUS)
goto skip_write_phase1;
dev->cmd_buffer = (uint8_t *)malloc(dev->buffer_length);
if (sector_len > 0) {
x54x_log("BIOS DMA: Reading %i bytes at %08X\n",
dev->buffer_length, dma_address);
DMAPageRead(dma_address,
dev->cmd_buffer, dev->buffer_length);
}
scsi_device_command_phase1(dev);
skip_write_phase1:
if (dev->cmd_buffer != NULL) {
free(dev->cmd_buffer);
dev->cmd_buffer = NULL;
}
return(completion_code(scsi_device_sense(dev)));
case 0x04: /* Verify Desired Sectors */
target_check(cmd->id);
cdb[0] = GPCMD_VERIFY_10;
cdb[1] = (cmd->lun & 7) << 5;
cdb[2] = (lba >> 24) & 0xff;
cdb[3] = (lba >> 16) & 0xff;
cdb[4] = (lba >> 8) & 0xff;
cdb[5] = lba & 0xff;
cdb[7] = 0;
cdb[8] = sector_len;
scsi_device_command_phase0(dev, cdb);
return(completion_code(scsi_device_sense(dev)));
case 0x05: /* Format Track, invalid since SCSI has no tracks */
//FIXME: add a longer delay here --FvK
return(1);
case 0x06: /* Identify SCSI Devices, in practice it's a nop */
//FIXME: add a longer delay here --FvK
return(0);
case 0x07: /* Format Unit */
target_check(cmd->id);
cdb[0] = GPCMD_FORMAT_UNIT;
cdb[1] = (cmd->lun & 7) << 5;
scsi_device_command_phase0(dev, cdb);
return(completion_code(scsi_device_sense(dev)));
case 0x08: /* Read Drive Parameters */
target_check(cmd->id);
dev->buffer_length = 6;
dev->cmd_buffer = (uint8_t *)malloc(dev->buffer_length);
memset(dev->cmd_buffer, 0x00, dev->buffer_length);
ret = x54x_bios_command_08(cmd->id, dev->cmd_buffer);
x54x_log("BIOS DMA: Reading 6 bytes at %08X\n", dma_address);
DMAPageWrite(dma_address,
dev->cmd_buffer, 4 /* dev->buffer_length */);
if (dev->cmd_buffer != NULL) {
free(dev->cmd_buffer);
dev->cmd_buffer = NULL;
}
return(ret);
case 0x09: /* Initialize Drive Pair Characteristics, in practice it's a nop */
//FIXME: add a longer delay here --FvK
return(0);
case 0x0c: /* Seek */
target_check(cmd->id);
cdb[0] = GPCMD_SEEK_10;
cdb[0] = bios_cmd_to_scsi[cmd->command];
cdb[1] = (cmd->lun & 7) << 5;
cdb[2] = (lba >> 24) & 0xff;
cdb[3] = (lba >> 16) & 0xff;
cdb[4] = (lba >> 8) & 0xff;
cdb[5] = lba & 0xff;
if (cmd->command != 0x0c)
cdb[8] = sector_len;
#if 0
x54x_log("BIOS CMD(READ/WRITE/VERIFY, %08lx, %d)\n", lba, cmd->secount);
#endif
scsi_device_command_phase0(dev, cdb);
ret = x54x_bios_scsi_command(dev, cdb, NULL, sector_len, dma_address);
if (cmd->command == 0x0c)
ret = !!ret;
break;
return((dev->status == SCSI_STATUS_OK) ? 1 : 0);
case 0x0d: /* Alternate Disk Reset, in practice it's a nop */
default:
x54x_log("BIOS: Unimplemented command: %02X\n", cmd->command);
case 0x05: /* Format Track, invalid since SCSI has no tracks */
case 0x0a: /* ???? */
case 0x0b: /* ???? */
case 0x12: /* ???? */
case 0x13: /* ???? */
//FIXME: add a longer delay here --FvK
return(0);
ret = 0x01;
break;
case 0x06: /* Identify SCSI Devices, in practice it's a nop */
case 0x09: /* Initialize Drive Pair Characteristics, in practice it's a nop */
case 0x0d: /* Alternate Disk Reset, in practice it's a nop */
case 0x0e: /* Read Sector Buffer */
case 0x0f: /* Write Sector Buffer */
case 0x14: /* Controller Diagnostic */
//FIXME: add a longer delay here --FvK
ret = 0x00;
break;
case 0x07: /* Format Unit */
case 0x10: /* Test Drive Ready */
target_check(cmd->id);
cdb[0] = GPCMD_TEST_UNIT_READY;
cdb[1] = (cmd->lun & 7) << 5;
scsi_device_command_phase0(dev, cdb);
return(completion_code(scsi_device_sense(dev)));
case 0x11: /* Recalibrate */
target_check(cmd->id);
cdb[0] = GPCMD_REZERO_UNIT;
cdb[0] = bios_cmd_to_scsi[cmd->command];
cdb[1] = (cmd->lun & 7) << 5;
scsi_device_command_phase0(dev, cdb);
return(completion_code(scsi_device_sense(dev)));
case 0x14: /* Controller Diagnostic */
//FIXME: add a longer delay here --FvK
return(0);
ret = x54x_bios_scsi_command(dev, cdb, NULL, sector_len, dma_address);
break;
case 0x08: /* Read Drive Parameters */
case 0x15: /* Read DASD Type */
target_check(cmd->id);
@@ -550,25 +555,26 @@ skip_write_phase1:
dev->cmd_buffer = (uint8_t *)malloc(dev->buffer_length);
memset(dev->cmd_buffer, 0x00, dev->buffer_length);
ret = x54x_bios_command_15(cmd->id, dev->cmd_buffer);
buf = (uint8_t *) malloc(6);
if (cmd->command == 0x08)
ret = x54x_bios_command_08(dev, buf);
else
ret = x54x_bios_command_15(dev, buf);
x54x_log("BIOS DMA: Reading 6 bytes at %08X\n", dma_address);
DMAPageWrite(dma_address,
dev->cmd_buffer, 4 /* dev->buffer_length */);
DMAPageWrite(dma_address, buf, 4);
free(buf);
if (dev->cmd_buffer != NULL) {
free(dev->cmd_buffer);
dev->cmd_buffer = NULL;
}
return(ret);
default:
x54x_log("BIOS: Unimplemented command: %02X\n", cmd->command);
return(1);
break;
}
x54x_log("BIOS Request complete\n");
x54x_log("BIOS Request %02X complete: %02X\n", cmd->command, ret);
return(ret);
}

View File

@@ -8,7 +8,7 @@
*
* Hercules emulation.
*
* Version: @(#)vid_hercules.c 1.0.13 2018/10/10
* Version: @(#)vid_hercules.c 1.0.14 2018/10/11
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
@@ -430,7 +430,12 @@ hercules_close(void *priv)
{
hercules_t *dev = (hercules_t *)priv;
if (!dev)
return;
if (dev->vram)
free(dev->vram);
free(dev);
}

View File

@@ -8,7 +8,7 @@
*
* Hercules Plus emulation.
*
* Version: @(#)vid_herculesplus.c 1.0.11 2018/10/10
* Version: @(#)vid_herculesplus.c 1.0.12 2018/10/11
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
@@ -653,7 +653,12 @@ herculesplus_close(void *priv)
{
herculesplus_t *dev = (herculesplus_t *)priv;
if (!dev)
return;
if (dev->vram)
free(dev->vram);
free(dev);
}

View File

@@ -8,7 +8,7 @@
*
* Hercules InColor emulation.
*
* Version: @(#)vid_incolor.c 1.0.12 2018/10/10
* Version: @(#)vid_incolor.c 1.0.13 2018/10/11
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
@@ -1061,7 +1061,12 @@ incolor_close(void *priv)
{
incolor_t *dev = (incolor_t *)priv;
if (!dev)
return;
if (dev->vram)
free(dev->vram);
free(dev);
}