Merge pull request #1571 from 86Box/master

Bring the branch up to par with master.
This commit is contained in:
Miran Grča
2021-08-02 06:58:22 +02:00
committed by GitHub
83 changed files with 3364 additions and 788 deletions

View File

@@ -85,7 +85,7 @@
and declared here instead. */
int dopause; /* system is paused */
int doresize; /* screen resize requested */
int is_quit; /* system exit requested */
volatile int is_quit; /* system exit requested */
uint64_t timer_freq;
char emu_version[200]; /* version ID string */
@@ -796,6 +796,7 @@ pc_reset_hard_init(void)
sound_reset();
scsi_reset();
scsi_device_init();
/* Initialize the actual machine and its basic modules. */
@@ -919,13 +920,8 @@ pc_close(thread_t *ptr)
/* Claim the video blitter. */
startblit();
/* Terminate the main thread. */
if (ptr != NULL) {
thread_kill(ptr);
/* Wait some more. */
plat_delay_ms(200);
}
/* Terminate the UI thread. */
is_quit = 1;
#if (defined(USE_DYNAREC) && defined(USE_NEW_DYNAREC))
codegen_close();
@@ -952,7 +948,7 @@ pc_close(thread_t *ptr)
#ifdef ENABLE_808X_LOG
if (dump_on_exit)
dumpregs(0);
dumpregs(0);
#endif
video_close();

View File

@@ -485,7 +485,7 @@ acpi_reg_read_via(int size, uint16_t addr, void *p)
case 0x42:
/* GPIO port Output Value */
if (size == 1)
ret = dev->regs.gpio_val & 0xff;
ret = dev->regs.gpio_val & 0x13;
break;
case 0x44:
/* GPIO port Input Value */
@@ -534,6 +534,11 @@ acpi_reg_read_via_596b(int size, uint16_t addr, void *p)
shift32 = (addr & 3) << 3;
switch (addr) {
case 0x42:
/* GPIO port Output Value */
if (size == 1)
ret = dev->regs.gpio_val & 0x13;
break;
case 0x44: case 0x45:
/* External SMI Input Value */
ret = (dev->regs.extsmi_val >> shift16) & 0xff;
@@ -544,7 +549,7 @@ acpi_reg_read_via_596b(int size, uint16_t addr, void *p)
break;
case 0x4c: case 0x4d: case 0x4e: case 0x4f:
/* GPO Port Output Value */
ret = (dev->regs.gpi_val >> shift32) & 0xff;
ret = (dev->regs.gpo_val >> shift32) & 0xff;
break;
default:
ret = acpi_reg_read_via_common(size, addr, p);
@@ -1030,7 +1035,7 @@ acpi_reg_write_via(int size, uint16_t addr, uint8_t val, void *p)
case 0x42:
/* GPIO port Output Value */
if (size == 1) {
dev->regs.gpio_val = val & 0x1f;
dev->regs.gpio_val = val & 0x13;
acpi_i2c_set(dev);
}
break;
@@ -1056,6 +1061,11 @@ acpi_reg_write_via_596b(int size, uint16_t addr, uint8_t val, void *p)
shift32 = (addr & 3) << 3;
switch (addr) {
case 0x42:
/* GPIO port Output Value */
if (size == 1)
dev->regs.gpio_val = val & 0x13;
break;
case 0x4c: case 0x4d: case 0x4e: case 0x4f:
/* GPO Port Output Value */
dev->regs.gpo_val = ((dev->regs.gpo_val & ~(0xff << shift32)) | (val << shift32)) & 0x7fffffff;
@@ -1605,6 +1615,10 @@ acpi_reset(void *priv)
dev->regs.gpi_val = 0xffff7fc1;
if (!strcmp(machines[machine].internal_name, "ficva503a"))
dev->regs.gpi_val |= 0x00000004;
if (!strcmp(machines[machine].internal_name, "6via90ap"))
dev->regs.gpi_val |= 0x00000004;
// dev->regs.gpi_val = 0xffffffe5;
// dev->regs.gpi_val = 0x00000004;
}
/* Power on always generates a resume event. */

View File

@@ -589,18 +589,13 @@ piix_write(int func, int addr, uint8_t val, void *priv)
} else if (func == 1) switch(addr) { /* IDE */
case 0x04:
fregs[0x04] = (val & 5);
if (dev->type < 3)
if (dev->type <= 3)
fregs[0x04] |= 0x02;
piix_ide_handlers(dev, 0x03);
piix_ide_bm_handlers(dev);
break;
case 0x07:
if (val & 0x20)
fregs[0x07] &= 0xdf;
if (val & 0x10)
fregs[0x07] &= 0xef;
if (val & 0x08)
fregs[0x07] &= 0xf7;
fregs[0x07] &= ~(val & 0x38);
break;
case 0x09:
if (dev->type == 5) {
@@ -613,36 +608,52 @@ piix_write(int func, int addr, uint8_t val, void *priv)
fregs[0x0d] = val & 0xf0;
break;
case 0x10:
fregs[0x10] = (val & 0xf8) | 1;
piix_ide_handlers(dev, 0x01);
if (dev->type == 5) {
fregs[0x10] = (val & 0xf8) | 1;
piix_ide_handlers(dev, 0x01);
}
break;
case 0x11:
fregs[0x11] = val;
piix_ide_handlers(dev, 0x01);
if (dev->type == 5) {
fregs[0x11] = val;
piix_ide_handlers(dev, 0x01);
}
break;
case 0x14:
fregs[0x14] = (val & 0xfc) | 1;
piix_ide_handlers(dev, 0x01);
if (dev->type == 5) {
fregs[0x14] = (val & 0xfc) | 1;
piix_ide_handlers(dev, 0x01);
}
break;
case 0x15:
fregs[0x15] = val;
piix_ide_handlers(dev, 0x01);
if (dev->type == 5) {
fregs[0x15] = val;
piix_ide_handlers(dev, 0x01);
}
break;
case 0x18:
fregs[0x18] = (val & 0xf8) | 1;
piix_ide_handlers(dev, 0x02);
if (dev->type == 5) {
fregs[0x18] = (val & 0xf8) | 1;
piix_ide_handlers(dev, 0x02);
}
break;
case 0x19:
fregs[0x19] = val;
piix_ide_handlers(dev, 0x02);
if (dev->type == 5) {
fregs[0x19] = val;
piix_ide_handlers(dev, 0x02);
}
break;
case 0x1c:
fregs[0x1c] = (val & 0xfc) | 1;
piix_ide_handlers(dev, 0x02);
if (dev->type == 5) {
fregs[0x1c] = (val & 0xfc) | 1;
piix_ide_handlers(dev, 0x02);
}
break;
case 0x1d:
fregs[0x1d] = val;
piix_ide_handlers(dev, 0x02);
if (dev->type == 5) {
fregs[0x1d] = val;
piix_ide_handlers(dev, 0x02);
}
break;
case 0x20:
fregs[0x20] = (val & 0xf0) | 1;
@@ -653,7 +664,8 @@ piix_write(int func, int addr, uint8_t val, void *priv)
piix_ide_bm_handlers(dev);
break;
case 0x3c:
fregs[0x3c] = val;
if (dev->type == 5)
fregs[0x3c] = val;
break;
case 0x3d:
if (dev->type == 5)
@@ -690,6 +702,8 @@ piix_write(int func, int addr, uint8_t val, void *priv)
if (dev->type > 4)
fregs[addr] = val;
break;
default:
break;
} else if (func == 2) switch(addr) { /* USB */
case 0x04:
if (dev->type > 4) {
@@ -1035,6 +1049,8 @@ piix_reset_hard(piix_t *dev)
/* Function 1: IDE */
fregs = (uint8_t *) dev->regs[1];
piix_log("PIIX Function 1: %02X%02X:%02X%02X\n", fregs[0x01], fregs[0x00], fregs[0x03], fregs[0x02]);
if (dev->type < 4)
fregs[0x04] = 0x02;
fregs[0x06] = 0x80; fregs[0x07] = 0x02;
if (dev->type == 4)
fregs[0x08] = dev->rev & 0x07;

View File

@@ -37,7 +37,7 @@ typedef struct
{
uint8_t cur_reg, tries,
reg_base, reg_last,
is_471,
reg_00, is_471,
regs[39], scratch[2];
smram_t *smram;
port_92_t *port_92;
@@ -78,7 +78,7 @@ sis_85c4xx_recalcmapping(sis_85c4xx_t *dev)
mem_set_mem_state(base, 0x8000, readext | writeext);
}
flushmmucache();
flushmmucache_nopc();
}
@@ -195,7 +195,8 @@ sis_85c4xx_out(uint16_t port, uint8_t val, void *priv)
}
break;
}
}
} else if ((dev->reg_base == 0x60) && (dev->cur_reg == 0x00))
dev->reg_00 = val;
dev->cur_reg = 0x00;
break;
@@ -217,9 +218,15 @@ sis_85c4xx_in(uint16_t port, void *priv)
case 0x23:
if (dev->is_471 && (dev->cur_reg == 0x1c))
ret = inb(0x70);
if ((dev->cur_reg >= dev->reg_base) && (dev->cur_reg <= dev->reg_last))
/* On the SiS 40x, the shadow RAM read and write enable bits are write-only! */
if ((dev->reg_base == 0x60) && (dev->cur_reg == 0x62))
ret = dev->regs[rel_reg] & 0x3f;
else if ((dev->cur_reg >= dev->reg_base) && (dev->cur_reg <= dev->reg_last))
ret = dev->regs[rel_reg];
dev->cur_reg = 0x00;
else if ((dev->reg_base == 0x60) && (dev->cur_reg == 0x00))
ret = dev->reg_00;
if (dev->reg_base != 0x60)
dev->cur_reg = 0x00;
break;
case 0xe1: case 0xe2:
@@ -341,6 +348,10 @@ sis_85c4xx_init(const device_t *info)
} else {
dev->reg_last = dev->reg_base + 0x11;
/* Bits 6 and 7 must be clear on the SiS 40x. */
if (dev->reg_base == 0x60)
dev->reg_00 = 0x24;
switch (mem_size_mb) {
case 1:
default:

View File

@@ -340,37 +340,36 @@ via_apollo_host_bridge_write(int func, int addr, uint8_t val, void *priv)
break;
case 0x61: /* Shadow RAM Control 1 */
if ((dev->pci_conf[0x61] ^ val) & 0x03)
apollo_map(0xc0000, 0x04000, val & 0x03);
if ((dev->pci_conf[0x61] ^ val) & 0x0c)
apollo_map(0xc4000, 0x04000, (val & 0x0c) >> 2);
if ((dev->pci_conf[0x61] ^ val) & 0x30)
apollo_map(0xc8000, 0x04000, (val & 0x30) >> 4);
if ((dev->pci_conf[0x61] ^ val) & 0xc0)
apollo_map(0xcc000, 0x04000, (val & 0xc0) >> 6);
apollo_map(0xc0000, 0x04000, val & 0x03);
apollo_map(0xc4000, 0x04000, (val & 0x0c) >> 2);
apollo_map(0xc8000, 0x04000, (val & 0x30) >> 4);
apollo_map(0xcc000, 0x04000, (val & 0xc0) >> 6);
dev->pci_conf[0x61] = val;
break;
case 0x62: /* Shadow RAM Control 2 */
if ((dev->pci_conf[0x62] ^ val) & 0x03)
apollo_map(0xd0000, 0x04000, val & 0x03);
if ((dev->pci_conf[0x62] ^ val) & 0x0c)
apollo_map(0xd4000, 0x04000, (val & 0x0c) >> 2);
if ((dev->pci_conf[0x62] ^ val) & 0x30)
apollo_map(0xd8000, 0x04000, (val & 0x30) >> 4);
if ((dev->pci_conf[0x62] ^ val) & 0xc0)
apollo_map(0xdc000, 0x04000, (val & 0xc0) >> 6);
apollo_map(0xd0000, 0x04000, val & 0x03);
apollo_map(0xd4000, 0x04000, (val & 0x0c) >> 2);
apollo_map(0xd8000, 0x04000, (val & 0x30) >> 4);
apollo_map(0xdc000, 0x04000, (val & 0xc0) >> 6);
dev->pci_conf[0x62] = val;
break;
case 0x63: /* Shadow RAM Control 3 */
if ((dev->pci_conf[0x63] ^ val) & 0x30) {
apollo_map(0xf0000, 0x10000, (val & 0x30) >> 4);
shadowbios = (((val & 0x30) >> 4) & 0x02);
}
if ((dev->pci_conf[0x63] ^ val) & 0xc0)
apollo_map(0xe0000, 0x10000, (val & 0xc0) >> 6);
shadowbios = 0;
shadowbios_write = 0;
apollo_map(0xf0000, 0x10000, (val & 0x30) >> 4);
shadowbios = (((val & 0x30) >> 4) & 0x02);
shadowbios_write = (((val & 0x30) >> 4) & 0x01);
apollo_map(0xe0000, 0x10000, (val & 0xc0) >> 6);
shadowbios |= (((val & 0xc0) >> 6) & 0x02);
shadowbios_write |= (((val & 0xc0) >> 6) & 0x01);
dev->pci_conf[0x63] = val;
smram_disable_all();
if (dev->id >= VIA_691) switch (val & 0x03) {
if (dev->id >= VIA_691) switch (val & 0x03) {
case 0x00:
default:
apollo_smram_map(dev, 1, 0x000a0000, 0x00020000, 1); /* SMM: Code DRAM, Data DRAM */
@@ -679,7 +678,8 @@ via_apollo_init(const device_t *info)
memset(dev, 0, sizeof(via_apollo_t));
dev->smram = smram_add();
apollo_smram_map(dev, 1, 0x000a0000, 0x00020000, 1); /* SMM: Code DRAM, Data DRAM */
if (dev->id != VIA_8601)
apollo_smram_map(dev, 1, 0x000a0000, 0x00020000, 1); /* SMM: Code DRAM, Data DRAM */
pci_add_card(PCI_ADD_NORTHBRIDGE, via_apollo_read, via_apollo_write, dev);

View File

@@ -285,7 +285,7 @@ pipc_reset_hard(void *priv)
dev->power_regs[0x34] = 0x68;
dev->power_regs[0x40] = 0x20;
dev->power_regs[0x42] = 0xd0;
dev->power_regs[0x42] = 0x50;
dev->power_regs[0x48] = 0x01;
if (dev->local == VIA_PIPC_686B) {
@@ -359,6 +359,9 @@ pipc_reset_hard(void *priv)
ide_pri_disable();
ide_sec_disable();
nvr_via_wp_set(0x00, 0x32, dev->nvr);
nvr_via_wp_set(0x00, 0x0d, dev->nvr);
}
@@ -502,7 +505,7 @@ nvr_update_io_mapping(pipc_t *dev)
if (dev->nvr_enabled)
nvr_at_handler(0, 0x0074, dev->nvr);
if ((dev->pci_isa_regs[0x5b] & 0x02) && (dev->pci_isa_regs[0x48] & 0x08))
if ((dev->pci_isa_regs[0x5b] & 0x02) || (dev->pci_isa_regs[0x48] & 0x08))
nvr_at_handler(1, 0x0074, dev->nvr);
}
@@ -682,6 +685,8 @@ pipc_write(int func, int addr, uint8_t val, void *priv)
case 0x77:
if (val & 0x10)
pclog("PIPC: Warning: Internal I/O APIC enabled.\n");
nvr_via_wp_set(!!(val & 0x04), 0x32, dev->nvr);
nvr_via_wp_set(!!(val & 0x02), 0x0d, dev->nvr);
break;
case 0x80: case 0x86: case 0x87:
@@ -922,8 +927,8 @@ pipc_write(int func, int addr, uint8_t val, void *priv)
break;
case 0x42:
dev->power_regs[addr] &= ~0x0f;
dev->power_regs[addr] |= val & 0x0f;
dev->power_regs[addr] &= ~0x2f;
dev->power_regs[addr] |= val & 0x2f;
acpi_set_irq_line(dev->acpi, dev->power_regs[addr]);
break;
@@ -1013,6 +1018,8 @@ pipc_reset(void *p)
pipc_write(1, 0x40, 0x04, p);
else
pipc_write(1, 0x40, 0x00, p);
pipc_write(0, 0x77, 0x00, p);
}

View File

@@ -37,6 +37,8 @@
#include "cpu.h"
#include <86box/device.h>
#include <86box/timer.h>
#include <86box/cassette.h>
#include <86box/cartridge.h>
#include <86box/nvr.h>
#include <86box/config.h>
#include <86box/isamem.h>
@@ -158,6 +160,23 @@ find_section(char *name)
}
void *
config_find_section(char *name)
{
return (void *) find_section(name);
}
void
config_rename_section(void *priv, char *name)
{
section_t *sec = (section_t *) priv;
memset(sec->name, 0x00, sizeof(sec->name));
memcpy(sec->name, name, MIN(128, strlen(name) + 1));
}
static entry_t *
find_entry(section_t *section, char *name)
{
@@ -514,6 +533,9 @@ load_general(void)
sound_gain = config_get_int(cat, "sound_gain", 0);
kbd_req_capture = config_get_int(cat, "kbd_req_capture", 0);
hide_status_bar = config_get_int(cat, "hide_status_bar", 0);
confirm_reset = config_get_int(cat, "confirm_reset", 1);
confirm_exit = config_get_int(cat, "confirm_exit", 1);
confirm_save = config_get_int(cat, "confirm_save", 1);
@@ -795,6 +817,10 @@ load_machine(void)
/* Remove this after a while.. */
config_delete_var(cat, "nvr_path");
config_delete_var(cat, "enable_sync");
/* Set up the architecture flags. */
AT = IS_AT(machine);
PCI = IS_ARCH(machine, MACHINE_BUS_PCI);
}
@@ -1019,17 +1045,30 @@ static void
load_storage_controllers(void)
{
char *cat = "Storage controllers";
char *p;
char *p, temp[512];
int c, min = 0;
int free_p = 0;
/* TODO: Backwards compatibility, get rid of this when enough time has passed. */
backwards_compat2 = (find_section(cat) == NULL);
/* TODO: Backwards compatibility, get rid of this when enough time has passed. */
p = config_get_string(cat, "scsicard", NULL);
if (p != NULL)
scsi_card_current = scsi_card_get_from_internal_name(p);
else
scsi_card_current = 0;
if (p != NULL) {
scsi_card_current[0] = scsi_card_get_from_internal_name(p);
min++;
}
config_delete_var(cat, "scsi_card");
for (c = min; c < SCSI_BUS_MAX; c++) {
sprintf(temp, "scsicard_%d", c + 1);
p = config_get_string(cat, temp, NULL);
if (p != NULL)
scsi_card_current[c] = scsi_card_get_from_internal_name(p);
else
scsi_card_current[c] = 0;
}
p = config_get_string(cat, "fdc", NULL);
if (p != NULL)
@@ -1068,6 +1107,50 @@ load_storage_controllers(void)
ide_ter_enabled = !!config_get_int(cat, "ide_ter", 0);
ide_qua_enabled = !!config_get_int(cat, "ide_qua", 0);
cassette_enable = !!config_get_int(cat, "cassette_enabled", AT ? 0 : 1);
p = config_get_string(cat, "cassette_file", "");
if (strlen(p) > 511)
fatal("load_storage_controllers(): strlen(p) > 511\n");
else
strncpy(cassette_fname, p, strlen(p) + 1);
p = config_get_string(cat, "cassette_mode", "");
if (strlen(p) > 511)
fatal("load_storage_controllers(): strlen(p) > 511\n");
else
strncpy(cassette_mode, p, strlen(p) + 1);
cassette_pos = config_get_int(cat, "cassette_position", 0);
cassette_srate = config_get_int(cat, "cassette_srate", 44100);
cassette_append = !!config_get_int(cat, "cassette_append", 0);
cassette_pcm = config_get_int(cat, "cassette_pcm", 0);
cassette_ui_writeprot = !!config_get_int(cat, "cassette_writeprot", 0);
for (c=0; c<2; c++) {
sprintf(temp, "cartridge_%02i_fn", c + 1);
p = config_get_string(cat, temp, "");
#if 0
/*
* NOTE:
* Temporary hack to remove the absolute
* path currently saved in most config
* files. We should remove this before
* finalizing this release! --FvK
*/
if (! wcsnicmp(wp, usr_path, wcslen(usr_path))) {
/*
* Yep, its absolute and prefixed
* with the EXE path. Just strip
* that off for now...
*/
wcsncpy(floppyfns[c], &wp[wcslen(usr_path)], sizeof_w(cart_fns[c]));
} else
#endif
if (strlen(p) > 511)
fatal("load_storage_controllers(): strlen(p) > 511\n");
else
strncpy(cart_fns[c], p, strlen(p) + 1);
}
}
@@ -1173,14 +1256,30 @@ load_hard_disks(void)
}
/* SCSI */
sprintf(temp, "hdd_%02i_scsi_id", c+1);
if (hdd[c].bus == HDD_BUS_SCSI) {
hdd[c].scsi_id = config_get_int(cat, temp, c);
sprintf(temp, "hdd_%02i_scsi_location", c+1);
sprintf(tmp2, "%01u:%02u", SCSI_BUS_MAX, c+2);
p = config_get_string(cat, temp, tmp2);
sscanf(p, "%01u:%02u", &board, &dev);
if (board >= SCSI_BUS_MAX) {
/* Invalid bus - check legacy ID */
sprintf(temp, "hdd_%02i_scsi_id", c+1);
hdd[c].scsi_id = config_get_int(cat, temp, c+2);
if (hdd[c].scsi_id > 15)
hdd[c].scsi_id = 15;
} else
if (hdd[c].scsi_id > 15)
hdd[c].scsi_id = 15;
} else {
board %= SCSI_BUS_MAX;
dev &= 15;
hdd[c].scsi_id = (board<<4)+dev;
}
} else {
sprintf(temp, "hdd_%02i_scsi_location", c+1);
config_delete_var(cat, temp);
}
sprintf(temp, "hdd_%02i_scsi_id", c+1);
config_delete_var(cat, temp);
memset(hdd[c].fn, 0x00, sizeof(hdd[c].fn));
memset(hdd[c].prev_fn, 0x00, sizeof(hdd[c].prev_fn));
@@ -1407,8 +1506,8 @@ load_floppy_and_cdrom_drives(void)
/* Default values, needed for proper operation of the Settings dialog. */
cdrom[c].ide_channel = cdrom[c].scsi_device_id = c + 2;
sprintf(temp, "cdrom_%02i_ide_channel", c+1);
if (cdrom[c].bus_type == CDROM_BUS_ATAPI) {
sprintf(temp, "cdrom_%02i_ide_channel", c+1);
sprintf(tmp2, "%01u:%01u", (c+2)>>1, (c+2)&1);
p = config_get_string(cat, temp, tmp2);
sscanf(p, "%01u:%01u", &board, &dev);
@@ -1418,17 +1517,38 @@ load_floppy_and_cdrom_drives(void)
if (cdrom[c].ide_channel > 7)
cdrom[c].ide_channel = 7;
} else {
sprintf(temp, "cdrom_%02i_scsi_id", c+1);
if (cdrom[c].bus_type == CDROM_BUS_SCSI) {
} else if (cdrom[c].bus_type == CDROM_BUS_SCSI) {
sprintf(temp, "cdrom_%02i_scsi_location", c+1);
sprintf(tmp2, "%01u:%02u", SCSI_BUS_MAX, c+2);
p = config_get_string(cat, temp, tmp2);
sscanf(p, "%01u:%02u", &board, &dev);
if (board >= SCSI_BUS_MAX) {
/* Invalid bus - check legacy ID */
sprintf(temp, "cdrom_%02i_scsi_id", c+1);
cdrom[c].scsi_device_id = config_get_int(cat, temp, c+2);
if (cdrom[c].scsi_device_id > 15)
cdrom[c].scsi_device_id = 15;
} else
config_delete_var(cat, temp);
} else {
board %= SCSI_BUS_MAX;
dev &= 15;
cdrom[c].scsi_device_id = (board<<4)+dev;
}
}
if (cdrom[c].bus_type != CDROM_BUS_ATAPI) {
sprintf(temp, "cdrom_%02i_ide_channel", c+1);
config_delete_var(cat, temp);
}
if (cdrom[c].bus_type != CDROM_BUS_SCSI) {
sprintf(temp, "cdrom_%02i_scsi_location", c+1);
config_delete_var(cat, temp);
}
sprintf(temp, "cdrom_%02i_scsi_id", c+1);
config_delete_var(cat, temp);
sprintf(temp, "cdrom_%02i_image_path", c+1);
p = config_get_string(cat, temp, "");
@@ -1519,8 +1639,8 @@ load_other_removable_devices(void)
cdrom[c].ide_channel = cdrom[c].scsi_device_id = c + 2;
config_delete_var(cat, temp);
sprintf(temp, "cdrom_%02i_ide_channel", c+1);
if (cdrom[c].bus_type == CDROM_BUS_ATAPI) {
sprintf(temp, "cdrom_%02i_ide_channel", c+1);
sprintf(tmp2, "%01u:%01u", (c+2)>>1, (c+2)&1);
p = config_get_string(cat, temp, tmp2);
sscanf(p, "%01u:%01u", &board, &dev);
@@ -1530,17 +1650,17 @@ load_other_removable_devices(void)
if (cdrom[c].ide_channel > 7)
cdrom[c].ide_channel = 7;
} else {
sprintf(temp, "cdrom_%02i_scsi_id", c+1);
if (cdrom[c].bus_type == CDROM_BUS_SCSI) {
cdrom[c].scsi_device_id = config_get_int(cat, temp, c+2);
if (cdrom[c].scsi_device_id > 15)
cdrom[c].scsi_device_id = 15;
} else
config_delete_var(cat, temp);
config_delete_var(cat, temp);
} else if (cdrom[c].bus_type == CDROM_BUS_SCSI) {
sprintf(temp, "cdrom_%02i_scsi_id", c+1);
cdrom[c].scsi_device_id = config_get_int(cat, temp, c+2);
if (cdrom[c].scsi_device_id > 15)
cdrom[c].scsi_device_id = 15;
config_delete_var(cat, temp);
}
config_delete_var(cat, temp);
sprintf(temp, "cdrom_%02i_image_path", c+1);
p = config_get_string(cat, temp, "");
@@ -1588,8 +1708,8 @@ load_other_removable_devices(void)
/* Default values, needed for proper operation of the Settings dialog. */
zip_drives[c].ide_channel = zip_drives[c].scsi_device_id = c + 2;
sprintf(temp, "zip_%02i_ide_channel", c+1);
if (zip_drives[c].bus_type == ZIP_BUS_ATAPI) {
sprintf(temp, "zip_%02i_ide_channel", c+1);
sprintf(tmp2, "%01u:%01u", (c+2)>>1, (c+2)&1);
p = config_get_string(cat, temp, tmp2);
sscanf(p, "%01u:%01u", &board, &dev);
@@ -1599,17 +1719,38 @@ load_other_removable_devices(void)
if (zip_drives[c].ide_channel > 7)
zip_drives[c].ide_channel = 7;
} else {
sprintf(temp, "zip_%02i_scsi_id", c+1);
if (zip_drives[c].bus_type == ZIP_BUS_SCSI) {
} else if (zip_drives[c].bus_type == ZIP_BUS_SCSI) {
sprintf(temp, "zip_%02i_scsi_location", c+1);
sprintf(tmp2, "%01u:%02u", SCSI_BUS_MAX, c+2);
p = config_get_string(cat, temp, tmp2);
sscanf(p, "%01u:%02u", &board, &dev);
if (board >= SCSI_BUS_MAX) {
/* Invalid bus - check legacy ID */
sprintf(temp, "zip_%02i_scsi_id", c+1);
zip_drives[c].scsi_device_id = config_get_int(cat, temp, c+2);
if (zip_drives[c].scsi_device_id > 15)
zip_drives[c].scsi_device_id = 15;
} else
config_delete_var(cat, temp);
} else {
board %= SCSI_BUS_MAX;
dev &= 15;
zip_drives[c].scsi_device_id = (board<<4)+dev;
}
}
if (zip_drives[c].bus_type != ZIP_BUS_ATAPI) {
sprintf(temp, "zip_%02i_ide_channel", c+1);
config_delete_var(cat, temp);
}
if (zip_drives[c].bus_type != ZIP_BUS_SCSI) {
sprintf(temp, "zip_%02i_scsi_location", c+1);
config_delete_var(cat, temp);
}
sprintf(temp, "zip_%02i_scsi_id", c+1);
config_delete_var(cat, temp);
sprintf(temp, "zip_%02i_image_path", c+1);
p = config_get_string(cat, temp, "");
@@ -1667,8 +1808,8 @@ load_other_removable_devices(void)
/* Default values, needed for proper operation of the Settings dialog. */
mo_drives[c].ide_channel = mo_drives[c].scsi_device_id = c + 2;
sprintf(temp, "mo_%02i_ide_channel", c+1);
if (mo_drives[c].bus_type == MO_BUS_ATAPI) {
sprintf(temp, "mo_%02i_ide_channel", c+1);
sprintf(tmp2, "%01u:%01u", (c+2)>>1, (c+2)&1);
p = config_get_string(cat, temp, tmp2);
sscanf(p, "%01u:%01u", &board, &dev);
@@ -1678,17 +1819,38 @@ load_other_removable_devices(void)
if (mo_drives[c].ide_channel > 7)
mo_drives[c].ide_channel = 7;
} else {
sprintf(temp, "mo_%02i_scsi_id", c+1);
if (mo_drives[c].bus_type == MO_BUS_SCSI) {
} else if (mo_drives[c].bus_type == MO_BUS_SCSI) {
sprintf(temp, "mo_%02i_scsi_location", c+1);
sprintf(tmp2, "%01u:%02u", SCSI_BUS_MAX, c+2);
p = config_get_string(cat, temp, tmp2);
sscanf(p, "%01u:%02u", &board, &dev);
if (board >= SCSI_BUS_MAX) {
/* Invalid bus - check legacy ID */
sprintf(temp, "mo_%02i_scsi_id", c+1);
mo_drives[c].scsi_device_id = config_get_int(cat, temp, c+2);
if (mo_drives[c].scsi_device_id > 15)
mo_drives[c].scsi_device_id = 15;
} else
config_delete_var(cat, temp);
} else {
board %= SCSI_BUS_MAX;
dev &= 15;
mo_drives[c].scsi_device_id = (board<<4)+dev;
}
}
if (mo_drives[c].bus_type != MO_BUS_ATAPI) {
sprintf(temp, "mo_%02i_ide_channel", c+1);
config_delete_var(cat, temp);
}
if (mo_drives[c].bus_type != MO_BUS_SCSI) {
sprintf(temp, "mo_%02i_scsi_location", c+1);
config_delete_var(cat, temp);
}
sprintf(temp, "mo_%02i_scsi_id", c+1);
config_delete_var(cat, temp);
sprintf(temp, "mo_%02i_image_path", c+1);
p = config_get_string(cat, temp, "");
@@ -1730,9 +1892,9 @@ load_other_peripherals(void)
if (backwards_compat2) {
p = config_get_string(cat, "scsicard", NULL);
if (p != NULL)
scsi_card_current = scsi_card_get_from_internal_name(p);
scsi_card_current[0] = scsi_card_get_from_internal_name(p);
else
scsi_card_current = 0;
scsi_card_current[0] = 0;
config_delete_var(cat, "scsicard");
p = config_get_string(cat, "fdc", NULL);
@@ -1810,13 +1972,22 @@ config_load(void)
memset(zip_drives, 0, sizeof(zip_drive_t));
if (! config_read(cfg_path)) {
config_changed = 1;
cpu_f = (cpu_family_t *) &cpu_families[0];
cpu = 0;
#ifdef USE_LANGUAGE
plat_langid = 0x0409;
#endif
kbd_req_capture = 0;
hide_status_bar = 0;
scale = 1;
machine = machine_get_machine_from_internal_name("ibmpc");
/* Set up the architecture flags. */
AT = IS_AT(machine);
PCI = IS_ARCH(machine, MACHINE_BUS_PCI);
fpu_type = fpu_get_type(cpu_f, cpu, "none");
gfxcard = video_get_video_from_internal_name("cga");
vid_api = plat_vidapi("default");
@@ -1847,6 +2018,15 @@ config_load(void)
for (i = 0; i < ISAMEM_MAX; i++)
isamem_type[i] = 0;
cassette_enable = AT ? 0 : 1;
memset(cassette_fname, 0x00, sizeof(cassette_fname));
memcpy(cassette_mode, "load", strlen("load") + 1);
cassette_pos = 0;
cassette_srate = 44100;
cassette_append = 0;
cassette_pcm = 0;
cassette_ui_writeprot = 0;
config_log("Config file not present or invalid!\n");
return;
}
@@ -1974,6 +2154,16 @@ save_general(void)
else
config_delete_var(cat, "sound_gain");
if (kbd_req_capture != 0)
config_set_int(cat, "kbd_req_capture", kbd_req_capture);
else
config_delete_var(cat, "kbd_req_capture");
if (hide_status_bar != 0)
config_set_int(cat, "hide_status_bar", hide_status_bar);
else
config_delete_var(cat, "hide_status_bar");
if (confirm_reset != 1)
config_set_int(cat, "confirm_reset", confirm_reset);
else
@@ -2324,12 +2514,20 @@ static void
save_storage_controllers(void)
{
char *cat = "Storage controllers";
char temp[512];
int c;
if (scsi_card_current == 0)
config_delete_var(cat, "scsicard");
else
config_set_string(cat, "scsicard",
scsi_card_get_internal_name(scsi_card_current));
config_delete_var(cat, "scsicard");
for (c = 0; c < SCSI_BUS_MAX; c++) {
sprintf(temp, "scsicard_%d", c + 1);
if (scsi_card_current[c] == 0)
config_delete_var(cat, temp);
else
config_set_string(cat, temp,
scsi_card_get_internal_name(scsi_card_current[c]));
}
if (fdc_type == FDC_INTERNAL)
config_delete_var(cat, "fdc");
@@ -2351,6 +2549,54 @@ save_storage_controllers(void)
config_set_int(cat, "ide_qua", ide_qua_enabled);
delete_section_if_empty(cat);
if (cassette_enable == 1)
config_delete_var(cat, "cassette_enabled");
else
config_set_int(cat, "cassette_enabled", cassette_enable);
if (cassette_fname == NULL)
config_delete_var(cat, "cassette_file");
else
config_set_string(cat, "cassette_file", cassette_fname);
if (cassette_mode == NULL)
config_delete_var(cat, "cassette_mode");
else
config_set_string(cat, "cassette_mode", cassette_mode);
if (cassette_pos == 0)
config_delete_var(cat, "cassette_position");
else
config_set_int(cat, "cassette_position", cassette_pos);
if (cassette_srate == 44100)
config_delete_var(cat, "cassette_srate");
else
config_set_int(cat, "cassette_srate", cassette_srate);
if (cassette_append == 0)
config_delete_var(cat, "cassette_append");
else
config_set_int(cat, "cassette_append", cassette_append);
if (cassette_pcm == 0)
config_delete_var(cat, "cassette_pcm");
else
config_set_int(cat, "cassette_pcm", cassette_pcm);
if (cassette_ui_writeprot == 0)
config_delete_var(cat, "cassette_writeprot");
else
config_set_int(cat, "cassette_writeprot", cassette_ui_writeprot);
for (c=0; c<2; c++) {
sprintf(temp, "cartridge_%02i_fn", c+1);
if (strlen(cart_fns[c]) == 0)
config_delete_var(cat, temp);
else
config_set_string(cat, temp, cart_fns[c]);
}
}
@@ -2439,10 +2685,16 @@ save_hard_disks(void)
}
sprintf(temp, "hdd_%02i_scsi_id", c+1);
if (hdd_is_valid(c) && (hdd[c].bus == HDD_BUS_SCSI))
config_set_int(cat, temp, hdd[c].scsi_id);
else
config_delete_var(cat, temp);
sprintf(temp, "hdd_%02i_scsi_location", c+1);
if (hdd[c].bus != HDD_BUS_SCSI)
config_delete_var(cat, temp);
else {
sprintf(tmp2, "%01u:%02u", hdd[c].scsi_id>>4,
hdd[c].scsi_id & 15);
config_set_string(cat, temp, tmp2);
}
sprintf(temp, "hdd_%02i_fn", c+1);
if (hdd_is_valid(c) && (strlen(hdd[c].fn) != 0))
@@ -2539,10 +2791,15 @@ save_floppy_and_cdrom_drives(void)
}
sprintf(temp, "cdrom_%02i_scsi_id", c + 1);
if (cdrom[c].bus_type != CDROM_BUS_SCSI) {
config_delete_var(cat, temp);
sprintf(temp, "cdrom_%02i_scsi_location", c+1);
if (cdrom[c].bus_type != CDROM_BUS_SCSI)
config_delete_var(cat, temp);
} else {
config_set_int(cat, temp, cdrom[c].scsi_device_id);
else {
sprintf(tmp2, "%01u:%02u", cdrom[c].scsi_device_id>>4,
cdrom[c].scsi_device_id & 15);
config_set_string(cat, temp, tmp2);
}
sprintf(temp, "cdrom_%02i_image_path", c + 1);
@@ -2586,10 +2843,15 @@ save_other_removable_devices(void)
}
sprintf(temp, "zip_%02i_scsi_id", c + 1);
if (zip_drives[c].bus_type != ZIP_BUS_SCSI) {
config_delete_var(cat, temp);
sprintf(temp, "zip_%02i_scsi_location", c+1);
if (zip_drives[c].bus_type != ZIP_BUS_SCSI)
config_delete_var(cat, temp);
} else {
config_set_int(cat, temp, zip_drives[c].scsi_device_id);
else {
sprintf(tmp2, "%01u:%02u", zip_drives[c].scsi_device_id>>4,
zip_drives[c].scsi_device_id & 15);
config_set_string(cat, temp, tmp2);
}
sprintf(temp, "zip_%02i_image_path", c + 1);
@@ -2621,10 +2883,15 @@ save_other_removable_devices(void)
}
sprintf(temp, "mo_%02i_scsi_id", c + 1);
if (mo_drives[c].bus_type != MO_BUS_SCSI) {
config_delete_var(cat, temp);
sprintf(temp, "mo_%02i_scsi_location", c+1);
if (mo_drives[c].bus_type != MO_BUS_SCSI)
config_delete_var(cat, temp);
} else {
config_set_int(cat, temp, mo_drives[c].scsi_device_id);
else {
sprintf(tmp2, "%01u:%02u", mo_drives[c].scsi_device_id>>4,
mo_drives[c].scsi_device_id & 15);
config_set_string(cat, temp, tmp2);
}
sprintf(temp, "mo_%02i_image_path", c + 1);

View File

@@ -90,11 +90,22 @@ device_init(void)
void
device_set_context(device_context_t *c, const device_t *d, int inst)
{
void *sec, *single_sec;
memset(c, 0, sizeof(device_context_t));
c->dev = d;
if (inst)
if (inst) {
sprintf(c->name, "%s #%i", d->name, inst);
else
/* If this is the first instance and a numbered section is not present, but a non-numbered
section of the same name is, rename the non-numbered section to numbered. */
if (inst == 1) {
sec = config_find_section(c->name);
single_sec = config_find_section((char *) d->name);
if ((sec == NULL) && (single_sec != NULL))
config_rename_section(single_sec, c->name);
}
} else
sprintf(c->name, "%s", d->name);
}

View File

@@ -13,7 +13,7 @@
# Copyright 2020,2021 David Hrdlička.
#
add_library(dev OBJECT bugger.c hasp.c hwm.c hwm_lm75.c hwm_lm78.c hwm_gl518sm.c
add_library(dev OBJECT bugger.c cassette.c cartridge.c hasp.c hwm.c hwm_lm75.c hwm_lm78.c hwm_gl518sm.c
hwm_vt82c686.c ibm_5161.c isamem.c isartc.c ../lpt.c pci_bridge.c
postcard.c serial.c clock_ics9xxx.c isapnp.c i2c.c i2c_gpio.c
smbus_piix4.c smbus_ali7101.c keyboard.c keyboard_xt.c keyboard_at.c

210
src/device/cartridge.c Normal file
View File

@@ -0,0 +1,210 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Implementation of the PCjr cartridge emulation.
*
*
*
* Authors: Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2021 Miran Grca.
*/
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#define HAVE_STDARG_H
#include <86box/86box.h>
#include <86box/timer.h>
#include <86box/plat.h>
#include <86box/ui.h>
#include <86box/mem.h>
#include <86box/machine.h>
#include <86box/cartridge.h>
typedef struct
{
uint8_t * buf;
uint32_t base;
} cart_t;
char cart_fns[2][512];
static cart_t carts[2];
static mem_mapping_t cart_mappings[2];
#ifdef ENABLE_CARTRIDGE_LOG
int cartridge_do_log = ENABLE_CARTRIDGE_LOG;
static void
cartridge_log(const char *fmt, ...)
{
va_list ap;
if (cartridge_do_log)
{
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
}
#else
#define cartridge_log(fmt, ...)
#endif
static uint8_t
cart_read(uint32_t addr, void *priv)
{
cart_t *dev = (cart_t *) priv;
return dev->buf[addr - dev->base];
}
static void
cart_load_error(int drive, char *fn)
{
cartridge_log("Cartridge: could not load '%s'\n",fn);
memset(cart_fns[drive], 0, sizeof(cart_fns[drive]));
ui_sb_update_icon_state(SB_CARTRIDGE | drive, 1);
}
static void
cart_image_close(int drive)
{
if (carts[drive].buf != NULL) {
free(carts[drive].buf);
carts[drive].buf = NULL;
}
carts[drive].base = 0x00000000;
mem_mapping_disable(&cart_mappings[drive]);
}
static void
cart_image_load(int drive, char *fn)
{
FILE *f;
uint32_t size;
uint32_t base = 0x00000000;
cart_image_close(drive);
f = fopen(fn, "rb");
if (fseek(f, 0, SEEK_END) == -1)
fatal("cart_image_load(): Error seeking to the end of the file\n");
size = ftell(f);
if (size < 0x1200) {
cartridge_log("cart_image_load(): File size %i is too small\n", size);
cart_load_error(drive, fn);
return;
}
if (size & 0x00000fff) {
size -= 0x00000200;
fseek(f, 0x000001ce, SEEK_SET);
fread(&base, 1, 2, f);
base <<= 4;
fseek(f, 0x00000200, SEEK_SET);
carts[drive].buf = (uint8_t *) malloc(size);
memset(carts[drive].buf, 0x00, size);
fread(carts[drive].buf, 1, size, f);
fclose(f);
} else {
base = drive ? 0xe0000 : 0xd0000;
if (size == 32768)
base += 0x8000;
fseek(f, 0x00000000, SEEK_SET);
carts[drive].buf = (uint8_t *) malloc(size);
memset(carts[drive].buf, 0x00, size);
fread(carts[drive].buf, 1, size, f);
fclose(f);
}
cartridge_log("cart_image_load(): %s at %08X-%08X\n", fn, base, base + size - 1);
carts[drive].base = base;
mem_mapping_set_addr(&cart_mappings[drive], base, size);
mem_mapping_set_exec(&cart_mappings[drive], carts[drive].buf);
mem_mapping_set_p(&cart_mappings[drive], &(carts[drive]));
}
static void
cart_load_common(int drive, char *fn, uint8_t hard_reset)
{
FILE *f;
cartridge_log("Cartridge: loading drive %d with '%s'\n", drive, fn);
if (!fn)
return;
f = plat_fopen(fn, "rb");
if (f) {
fclose(f);
strcpy(cart_fns[drive], fn);
cart_image_load(drive, cart_fns[drive]);
/* On the real PCjr, inserting a cartridge causes a reset
in order to boot from the cartridge. */
if (!hard_reset)
resetx86();
} else
cart_load_error(drive, fn);
}
void
cart_load(int drive, char *fn)
{
cart_load_common(drive, fn, 0);
}
void
cart_close(int drive)
{
cartridge_log("Cartridge: closing drive %d\n", drive);
cart_image_close(drive);
cart_fns[drive][0] = 0;
ui_sb_update_icon_state(SB_CARTRIDGE | drive, 1);
}
void
cart_reset(void)
{
int i;
cart_image_close(1);
cart_image_close(0);
if (!(machines[machine].flags & MACHINE_CARTRIDGE))
return;
for (i = 0; i < 2; i++) {
mem_mapping_add(&cart_mappings[i], 0x000d0000, 0x00002000,
cart_read,NULL,NULL,
NULL,NULL,NULL,
NULL, MEM_MAPPING_EXTERNAL, NULL);
mem_mapping_disable(&cart_mappings[i]);
}
cart_load_common(0, cart_fns[0], 1);
cart_load_common(1, cart_fns[1], 1);
}

723
src/device/cassette.c Normal file
View File

@@ -0,0 +1,723 @@
/*****************************************************************************
* pce *
*****************************************************************************/
/*****************************************************************************
* File name: src/arch/ibmpc/cassette.c *
* Created: 2008-11-25 by Hampa Hug <hampa@hampa.ch> *
* Copyright: (C) 2008-2019 Hampa Hug <hampa@hampa.ch> *
*****************************************************************************/
/*****************************************************************************
* This program is free software. You can redistribute it and / or modify it *
* under the terms of the GNU General Public License version 2 as published *
* by the Free Software Foundation. *
* *
* This program is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY, without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General *
* Public License for more details. *
*****************************************************************************/
#include <stdarg.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <wchar.h>
#define HAVE_STDARG_H
#include <86box/86box.h>
#include <86box/device.h>
#include "cpu.h"
#include <86box/machine.h>
#include <86box/plat.h>
#include <86box/ui.h>
#include <86box/timer.h>
#include <86box/pit.h>
#include <86box/cassette.h>
// #include <lib/console.h>
#define CAS_CLK 1193182
pc_cassette_t * cassette;
char cassette_fname[512];
char cassette_mode[512];
unsigned long cassette_pos, cassette_srate;
int cassette_enable;
int cassette_append, cassette_pcm;
int cassette_ui_writeprot;
static int cassette_cycles = -1;
static void pc_cas_reset (pc_cassette_t *cas);
#ifdef ENABLE_CASSETTE_LOG
int cassette_do_log = ENABLE_CASSETTE_LOG;
static void
cassette_log(const char *fmt, ...)
{
va_list ap;
if (cassette_do_log)
{
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
}
#else
#define cassette_log(fmt, ...)
#endif
void pc_cas_init (pc_cassette_t *cas)
{
cas->save = 0;
cas->pcm = 0;
cas->motor = 0;
ui_sb_update_icon(SB_CASSETTE, 0);
cas->position = 0;
cas->position_save = 0;
cas->position_load = 0;
cas->data_out = 0;
cas->data_inp = 0;
cas->pcm_out_vol = 64;
cas->pcm_out_val = 0;
cas->cas_out_cnt = 0;
cas->cas_out_buf = 0;
cas->cas_inp_cnt = 0;
cas->cas_inp_buf = 0;
cas->cas_inp_bit = 0;
cas->clk = 0;
cas->clk_pcm = 0;
cas->clk_out = 0;
cas->clk_inp = 0;
cas->srate = 44100;
cas->close = 0;
cas->fname = NULL;
cas->fp = NULL;
pc_cas_reset (cas);
}
void pc_cas_free (pc_cassette_t *cas)
{
free (cas->fname);
if (cas->close) {
fclose (cas->fp);
}
}
pc_cassette_t *pc_cas_new (void)
{
pc_cassette_t *cas;
cas = malloc (sizeof (pc_cassette_t));
if (cas == NULL) {
return (NULL);
}
pc_cas_init (cas);
return (cas);
}
void pc_cas_del (pc_cassette_t *cas)
{
if (cas != NULL) {
pc_cas_free (cas);
free (cas);
}
}
int pc_cas_set_fname (pc_cassette_t *cas, const char *fname)
{
unsigned n;
const char * ext;
if (cas->close)
fclose (cas->fp);
cas->close = 0;
cas->fp = NULL;
free (cas->fname);
cas->fname = NULL;
cas->position = 0;
cas->position_save = 0;
cas->position_load = 0;
if (fname == NULL) {
ui_sb_update_icon_state(SB_CASSETTE, 1);
return (0);
}
cas->fp = plat_fopen (fname, "r+b");
if (cas->fp == NULL)
cas->fp = plat_fopen (fname, "w+b");
if (cas->fp == NULL) {
ui_sb_update_icon_state(SB_CASSETTE, 1);
return (1);
}
cas->close = 1;
pc_cas_append (cas);
cas->position_save = cas->position;
if (cas->save == 0)
pc_cas_set_position (cas, 0);
n = strlen (fname);
cas->fname = malloc ((n + 1) * sizeof(char));
if (cas->fname != NULL)
memcpy (cas->fname, fname, (n + 1) * sizeof(char));
if (n > 4) {
ext = fname + (n - 4);
/* Has to be 44.1 kHz, mono, 8-bit. */
if (stricmp (ext, ".pcm") == 0)
pc_cas_set_pcm (cas, 1);
else if (stricmp (ext, ".raw") == 0)
pc_cas_set_pcm (cas, 1);
else if (stricmp (ext, ".wav") == 0)
pc_cas_set_pcm (cas, 1);
else if (stricmp (ext, ".cas") == 0)
pc_cas_set_pcm (cas, 0);
}
return (0);
}
static
void pc_cas_reset (pc_cassette_t *cas)
{
unsigned i;
cas->clk_pcm = 0;
cas->clk_out = cas->clk;
cas->clk_inp = 0;
cas->pcm_out_val = 0;
cas->cas_out_cnt = 0;
cas->cas_out_buf = 0;
cas->cas_inp_cnt = 0;
cas->cas_inp_buf = 0;
cas->cas_inp_bit = 0;
for (i = 0; i < 3; i++) {
cas->pcm_inp_fir[i] = 0;
}
}
int pc_cas_get_mode (const pc_cassette_t *cas)
{
return (cas->save);
}
void pc_cas_set_mode (pc_cassette_t *cas, int save)
{
save = (save != 0);
if (cas->save == save) {
return;
}
if (cas->save) {
cas->position_save = cas->position;
cas->position = cas->position_load;
}
else {
cas->position_load = cas->position;
cas->position = cas->position_save;
}
cas->save = save;
memset(cassette_mode, 0x00, sizeof(cassette_mode));
if (save)
memcpy(cassette_mode, "save", strlen("save") + 1);
else
memcpy(cassette_mode, "load", strlen("load") + 1);
if (cas->fp != NULL) {
fflush (cas->fp);
pc_cas_set_position (cas, cas->position);
}
pc_cas_reset (cas);
}
int pc_cas_get_pcm (const pc_cassette_t *cas)
{
return (cas->pcm);
}
void pc_cas_set_pcm (pc_cassette_t *cas, int pcm)
{
cas->pcm = (pcm != 0);
cassette_pcm = (pcm != 0);
pc_cas_reset (cas);
}
unsigned long pc_cas_get_srate (const pc_cassette_t *cas)
{
return (cas->srate);
}
void pc_cas_set_srate (pc_cassette_t *cas, unsigned long srate)
{
cas->srate = srate;
pc_cas_reset (cas);
}
void pc_cas_rewind (pc_cassette_t *cas)
{
if (cas->fp != NULL) {
rewind (cas->fp);
cas->position = 0;
}
pc_cas_reset (cas);
}
void pc_cas_append (pc_cassette_t *cas)
{
if (cas->fp != NULL) {
fseek (cas->fp, 0, SEEK_END);
cas->position = ftell (cas->fp);
}
pc_cas_reset (cas);
}
unsigned long pc_cas_get_position (const pc_cassette_t *cas)
{
return (cas->position);
}
int pc_cas_set_position (pc_cassette_t *cas, unsigned long pos)
{
if (cas->fp == NULL) {
return (1);
}
if (fseek (cas->fp, pos, SEEK_SET) != 0) {
return (1);
}
cas->position = pos;
pc_cas_reset (cas);
return (0);
}
static
void pc_cas_read_bit (pc_cassette_t *cas)
{
int val;
if (cas->cas_inp_cnt == 0) {
if (cas->fp == NULL) {
return;
}
if (feof (cas->fp)) {
return;
}
val = fgetc (cas->fp);
if (val == EOF) {
cassette_log ("cassette EOF at %lu\n", cas->position);
return;
}
cas->position += 1;
cas->cas_inp_cnt = 8;
cas->cas_inp_buf = val;
}
cas->cas_inp_bit = ((cas->cas_inp_buf & 0x80) != 0);
cas->cas_inp_buf = (cas->cas_inp_buf << 1) & 0xff;
cas->cas_inp_cnt -= 1;
}
static
int pc_cas_read_smp (pc_cassette_t *cas)
{
int smp, *fir;
if (feof (cas->fp)) {
return (0);
}
smp = fgetc (cas->fp);
if (smp == EOF) {
cassette_log ("cassette EOF at %lu\n", cas->position);
return (0);
}
cas->position += 1;
fir = cas->pcm_inp_fir;
fir[0] = fir[1];
fir[1] = fir[2];
fir[2] = (smp & 0x80) ? (smp - 256) : smp;
smp = (fir[0] + 2 * fir[1] + fir[2]) / 4;
return (smp);
}
static
void pc_cas_write_bit (pc_cassette_t *cas, unsigned char val)
{
if (val && !cassette_ui_writeprot) {
cas->cas_out_buf |= (0x80 >> cas->cas_out_cnt);
}
cas->cas_out_cnt += 1;
if (cas->cas_out_cnt >= 8) {
if (cas->fp != NULL) {
if (!cassette_ui_writeprot)
fputc (cas->cas_out_buf, cas->fp);
cas->position += 1;
}
cas->cas_out_buf = 0;
cas->cas_out_cnt = 0;
}
}
static
void pc_cas_write_smp (pc_cassette_t *cas, int val)
{
unsigned char smp;
if (val < 0) {
smp = (val < -127) ? 0x80 : (val + 256);
}
else {
smp = (val > 127) ? 0x7f : val;
}
if (!cassette_ui_writeprot)
fputc (smp, cas->fp);
cas->position += 1;
}
void pc_cas_set_motor (pc_cassette_t *cas, unsigned char val)
{
unsigned i;
val = (val != 0);
if (val == cas->motor) {
return;
}
if ((val == 0) && cas->save && cas->pcm) {
for (i = 0; i < (cas->srate / 16); i++) {
pc_cas_write_smp (cas, 0);
}
}
cassette_log ("cassette %S at %lu motor %s\n", (cas->fname != NULL) ? cas->fname : "<none>", cas->position, val ? "on" : "off");
cas->motor = val;
if (cas->fp != NULL) {
fflush (cas->fp);
pc_cas_set_position (cas, cas->position);
}
pc_cas_reset (cas);
if (cas->motor)
timer_set_delay_u64(&cas->timer, 8ULL * PITCONST);
else
timer_disable(&cas->timer);
ui_sb_update_icon(SB_CASSETTE, !!val);
}
unsigned char pc_cas_get_inp (const pc_cassette_t *cas)
{
return (cas->data_inp);
}
void pc_cas_set_out (pc_cassette_t *cas, unsigned char val)
{
unsigned long clk;
val = (val != 0);
if (cas->motor == 0) {
cas->data_inp = val;
return;
}
if (cas->data_out == val) {
return;
}
cas->data_out = val;
if (cas->pcm) {
cas->pcm_out_val = val ? -cas->pcm_out_vol : cas->pcm_out_vol;
return;
}
if (cas->save == 0) {
return;
}
if (val == 0) {
return;
}
clk = cas->clk - cas->clk_out;
cas->clk_out = cas->clk;
if (clk < (CAS_CLK / 4000)) {
;
}
else if (clk < ((3 * CAS_CLK) / 4000)) {
pc_cas_write_bit (cas, 0);
}
else if (clk < ((5 * CAS_CLK) / 4000)) {
pc_cas_write_bit (cas, 1);
}
}
void pc_cas_print_state (const pc_cassette_t *cas)
{
cassette_log ("%s %s %lu %s %lu\n", (cas->fname != NULL) ? cas->fname : "<none>", cas->pcm ? "pcm" : "cas", cas->srate, cas->save ? "save" : "load", cas->position);
}
static
void pc_cas_clock_pcm (pc_cassette_t *cas, unsigned long cnt)
{
unsigned long i, n;
int v = 0;
n = cas->srate * cnt + cas->clk_pcm;
cas->clk_pcm = n % CAS_CLK;
n = n / CAS_CLK;
if (n == 0) {
return;
}
if (cas->save) {
for (i = 0; i < n; i++) {
pc_cas_write_smp (cas, cas->pcm_out_val);
}
}
else {
for (i = 0; i < n; i++) {
v = pc_cas_read_smp (cas);
}
cas->data_inp = (v < 0) ? 0 : 1;
}
}
void pc_cas_clock (pc_cassette_t *cas, unsigned long cnt)
{
cas->clk += cnt;
if (cas->motor == 0) {
return;
}
if (cas->pcm) {
pc_cas_clock_pcm (cas, cnt);
return;
}
if (cas->save) {
return;
}
if (cas->clk_inp > cnt) {
cas->clk_inp -= cnt;
return;
}
cnt -= cas->clk_inp;
cas->data_inp = !cas->data_inp;
if (cas->data_inp) {
pc_cas_read_bit (cas);
}
if (cas->cas_inp_bit) {
cas->clk_inp = CAS_CLK / 2000;
}
else {
cas->clk_inp = CAS_CLK / 4000;
}
if (cas->clk_inp > cnt) {
cas->clk_inp -= cnt;
}
}
void pc_cas_advance (pc_cassette_t *cas)
{
int ticks;
cpu_s = (CPU *) &cpu_f->cpus[cpu_effective];
if (cas->motor == 0)
return;
if (cassette_cycles == -1)
cassette_cycles = cycles;
if (cycles <= cassette_cycles)
ticks = (cassette_cycles - cycles);
else
ticks = (cassette_cycles + (cpu_s->rspeed / 100) - cycles);
cassette_cycles = cycles;
pc_cas_clock(cas, ticks);
}
static void
cassette_close(void *p)
{
if (cassette != NULL) {
free(cassette);
cassette = NULL;
}
}
static void
cassette_callback(void *p)
{
pc_cassette_t *cas = (pc_cassette_t *) p;
pc_cas_clock (cas, 8);
if (cas->motor)
ui_sb_update_icon(SB_CASSETTE, 1);
timer_advance_u64(&cas->timer, 8ULL * PITCONST);
}
static void *
cassette_init(const device_t *info)
{
cassette = NULL;
if (cassette_pcm == 1)
cassette_pcm = -1;
cassette_log("CASSETTE: file=%s mode=%s pcm=%d srate=%lu pos=%lu append=%d\n",
(cassette_fname != NULL) ? cassette_fname : "<none>", cassette_mode, cassette_pcm, cassette_srate, cassette_pos, cassette_append);
cassette = pc_cas_new();
if (cassette == NULL) {
cassette_log("ERROR: *** alloc failed\n");
return NULL;
}
if (strlen(cassette_fname) == 0) {
if (pc_cas_set_fname (cassette, NULL)) {
cassette_log("ERROR: *** opening file failed (%s)\n", cassette_fname);
}
} else {
if (pc_cas_set_fname (cassette, cassette_fname)) {
cassette_log("ERROR: *** opening file failed (%s)\n", cassette_fname);
}
}
if (strcmp (cassette_mode, "load") == 0)
pc_cas_set_mode (cassette, 0);
else if (strcmp (cassette_mode, "save") == 0)
pc_cas_set_mode (cassette, 1);
else {
cassette_log ("ERROR: *** unknown cassette mode (%s)\n", cassette_mode);
}
if (cassette_append)
pc_cas_append (cassette);
else
pc_cas_set_position (cassette, cassette_pos);
if (cassette_pcm >= 0)
pc_cas_set_pcm (cassette, cassette_pcm);
pc_cas_set_srate (cassette, cassette_srate);
timer_add(&cassette->timer, cassette_callback, cassette, 0);
return cassette;
}
const device_t cassette_device = {
"IBM PC/PCjr Cassette Device",
0,
0,
cassette_init, cassette_close, NULL,
{ NULL }, NULL, NULL,
NULL
};

View File

@@ -33,6 +33,7 @@
#include <86box/fdd.h>
#include <86box/machine.h>
#include <86box/m_xt_t1000.h>
#include <86box/cassette.h>
#include <86box/io.h>
#include <86box/pic.h>
#include <86box/pit.h>
@@ -515,13 +516,14 @@ kbd_write(uint16_t port, uint8_t val, void *priv)
timer_process();
if ((kbd->type <= 1) && (cassette != NULL))
pc_cas_set_motor(cassette, (kbd->pb & 0x08) == 0);
speaker_update();
if ((kbd->type <= 1) && !(kbd->pb & 0x08))
speaker_gated = speaker_enable = 1;
else {
speaker_gated = val & 1;
speaker_enable = val & 2;
}
speaker_gated = val & 1;
speaker_enable = val & 2;
if (speaker_enable)
was_speaker_enable = 1;
pit_ctr_set_gate(&pit->counters[2], val & 1);
@@ -620,8 +622,12 @@ kbd_read(uint16_t port, void *priv)
/* This is needed to avoid error 131 (cassette error).
This is serial read: bit 5 = clock, bit 4 = data, cassette header is 256 x 0xff. */
if (kbd->type <= 1)
ret |= (ppispeakon ? 0x10 : 0);
if (kbd->type <= 1) {
if (cassette == NULL)
ret |= (ppispeakon ? 0x10 : 0);
else
ret |= (pc_cas_get_inp(cassette) ? 0x10 : 0);
}
if (kbd->type == 5)
ret |= (tandy1k_eeprom_read() ? 0x10 : 0);

View File

@@ -1883,7 +1883,11 @@ static uint8_t
ide_status(ide_t *ide, ide_t *ide_other, int ch)
{
if ((ide->type == IDE_NONE) && ((ide_other->type == IDE_NONE) || !(ch & 1)))
#ifdef STATUS_BIT_7_PULLDOWN
return 0x7F; /* Bit 7 pulled down, all other bits pulled up, per the spec. */
#else
return 0xFF;
#endif
else if ((ide->type == IDE_NONE) && (ch & 1))
return 0x00; /* On real hardware, a slave with a present master always returns a status of 0x00. */
else if (ide->type == IDE_ATAPI)

View File

@@ -831,12 +831,13 @@ mo_sense_clear(mo_t *dev, int command)
static void
mo_set_phase(mo_t *dev, uint8_t phase)
{
uint8_t scsi_id = dev->drv->scsi_device_id;
uint8_t scsi_bus = (dev->drv->scsi_device_id >> 4) & 0x0f;
uint8_t scsi_id = dev->drv->scsi_device_id & 0x0f;
if (dev->drv->bus_type != MO_BUS_SCSI)
return;
scsi_devices[scsi_id].phase = phase;
scsi_devices[scsi_bus][scsi_id].phase = phase;
}
@@ -1343,9 +1344,11 @@ mo_command(scsi_common_t *sc, uint8_t *cdb)
int32_t blen = 0;
int32_t *BufLen;
uint32_t previous_pos = 0;
uint8_t scsi_bus = (dev->drv->scsi_device_id >> 4) & 0x0f;
uint8_t scsi_id = dev->drv->scsi_device_id & 0x0f;
if (dev->drv->bus_type == MO_BUS_SCSI) {
BufLen = &scsi_devices[dev->drv->scsi_device_id].buffer_length;
BufLen = &scsi_devices[scsi_bus][scsi_id].buffer_length;
dev->status &= ~ERR_STAT;
} else {
BufLen = &blen;
@@ -2106,6 +2109,8 @@ mo_drive_reset(int c)
mo_t *dev;
scsi_device_t *sd;
ide_t *id;
uint8_t scsi_bus = (mo_drives[c].scsi_device_id >> 4) & 0x0f;
uint8_t scsi_id = mo_drives[c].scsi_device_id & 0x0f;
if (!mo_drives[c].priv) {
mo_drives[c].priv = (mo_t *) malloc(sizeof(mo_t));
@@ -2119,7 +2124,7 @@ mo_drive_reset(int c)
if (mo_drives[c].bus_type == MO_BUS_SCSI) {
/* SCSI MO, attach to the SCSI bus. */
sd = &scsi_devices[mo_drives[c].scsi_device_id];
sd = &scsi_devices[scsi_bus][scsi_id];
sd->sc = (scsi_common_t *) dev;
sd->command = mo_command;
@@ -2158,14 +2163,24 @@ mo_hard_reset(void)
{
mo_t *dev;
int c;
uint8_t scsi_id, scsi_bus;
for (c = 0; c < MO_NUM; c++) {
if ((mo_drives[c].bus_type == MO_BUS_ATAPI) || (mo_drives[c].bus_type == MO_BUS_SCSI)) {
mo_log("MO hard_reset drive=%d\n", c);
/* Make sure to ignore any SCSI MO drive that has an out of range ID. */
if ((mo_drives[c].bus_type == MO_BUS_SCSI) && (mo_drives[c].scsi_device_id >= SCSI_ID_MAX))
continue;
if (mo_drives[c].bus_type == MO_BUS_SCSI) {
scsi_bus = (mo_drives[c].scsi_device_id >> 4) & 0x0f;
scsi_id = mo_drives[c].scsi_device_id & 0x0f;
/* Make sure to ignore any SCSI MO drive that has an out of range SCSI Bus. */
if (scsi_bus >= SCSI_BUS_MAX)
continue;
/* Make sure to ignore any SCSI MO drive that has an out of range ID. */
if (scsi_id >= SCSI_ID_MAX)
continue;
}
/* Make sure to ignore any ATAPI MO drive that has an out of range IDE channel. */
if ((mo_drives[c].bus_type == MO_BUS_ATAPI) && (mo_drives[c].ide_channel > 7))
@@ -2199,10 +2214,15 @@ mo_close(void)
{
mo_t *dev;
int c;
uint8_t scsi_id, scsi_bus;
for (c = 0; c < MO_NUM; c++) {
if (mo_drives[c].bus_type == MO_BUS_SCSI)
memset(&scsi_devices[mo_drives[c].scsi_device_id], 0x00, sizeof(scsi_device_t));
if (mo_drives[c].bus_type == MO_BUS_SCSI) {
scsi_bus = (mo_drives[c].scsi_device_id >> 4) & 0x0f;
scsi_id = mo_drives[c].scsi_device_id & 0x0f;
memset(&scsi_devices[scsi_bus][scsi_id], 0x00, sizeof(scsi_device_t));
}
dev = (mo_t *) mo_drives[c].priv;

View File

@@ -1000,12 +1000,13 @@ zip_sense_clear(zip_t *dev, int command)
static void
zip_set_phase(zip_t *dev, uint8_t phase)
{
uint8_t scsi_id = dev->drv->scsi_device_id;
uint8_t scsi_bus = (dev->drv->scsi_device_id >> 4) & 0x0f;
uint8_t scsi_id = dev->drv->scsi_device_id & 0x0f;
if (dev->drv->bus_type != ZIP_BUS_SCSI)
return;
scsi_devices[scsi_id].phase = phase;
scsi_devices[scsi_bus][scsi_id].phase = phase;
}
@@ -1416,9 +1417,11 @@ zip_command(scsi_common_t *sc, uint8_t *cdb)
unsigned preamble_len;
int32_t blen = 0;
int32_t *BufLen;
uint8_t scsi_bus = (dev->drv->scsi_device_id >> 4) & 0x0f;
uint8_t scsi_id = dev->drv->scsi_device_id & 0x0f;
if (dev->drv->bus_type == ZIP_BUS_SCSI) {
BufLen = &scsi_devices[dev->drv->scsi_device_id].buffer_length;
BufLen = &scsi_devices[scsi_bus][scsi_id].buffer_length;
dev->status &= ~ERR_STAT;
} else {
BufLen = &blen;
@@ -2330,6 +2333,8 @@ zip_drive_reset(int c)
zip_t *dev;
scsi_device_t *sd;
ide_t *id;
uint8_t scsi_bus = (zip_drives[c].scsi_device_id >> 4) & 0x0f;
uint8_t scsi_id = zip_drives[c].scsi_device_id & 0x0f;
if (!zip_drives[c].priv) {
zip_drives[c].priv = (zip_t *) malloc(sizeof(zip_t));
@@ -2343,7 +2348,7 @@ zip_drive_reset(int c)
if (zip_drives[c].bus_type == ZIP_BUS_SCSI) {
/* SCSI ZIP, attach to the SCSI bus. */
sd = &scsi_devices[zip_drives[c].scsi_device_id];
sd = &scsi_devices[scsi_bus][scsi_id];
sd->sc = (scsi_common_t *) dev;
sd->command = zip_command;
@@ -2382,14 +2387,24 @@ zip_hard_reset(void)
{
zip_t *dev;
int c;
uint8_t scsi_id, scsi_bus;
for (c = 0; c < ZIP_NUM; c++) {
if ((zip_drives[c].bus_type == ZIP_BUS_ATAPI) || (zip_drives[c].bus_type == ZIP_BUS_SCSI)) {
zip_log("ZIP hard_reset drive=%d\n", c);
/* Make sure to ignore any SCSI ZIP drive that has an out of range ID. */
if ((zip_drives[c].bus_type == ZIP_BUS_SCSI) && (zip_drives[c].scsi_device_id >= SCSI_ID_MAX))
continue;
if (zip_drives[c].bus_type == ZIP_BUS_SCSI) {
scsi_bus = (zip_drives[c].scsi_device_id >> 4) & 0x0f;
scsi_id = zip_drives[c].scsi_device_id & 0x0f;
/* Make sure to ignore any SCSI ZIP drive that has an out of range SCSI bus. */
if (scsi_bus >= SCSI_BUS_MAX)
continue;
/* Make sure to ignore any SCSI ZIP drive that has an out of range ID. */
if (scsi_id >= SCSI_ID_MAX)
continue;
}
/* Make sure to ignore any ATAPI ZIP drive that has an out of range IDE channel. */
if ((zip_drives[c].bus_type == ZIP_BUS_ATAPI) && (zip_drives[c].ide_channel > 7))
@@ -2423,10 +2438,15 @@ zip_close(void)
{
zip_t *dev;
int c;
uint8_t scsi_bus, scsi_id;
for (c = 0; c < ZIP_NUM; c++) {
if (zip_drives[c].bus_type == ZIP_BUS_SCSI)
memset(&scsi_devices[zip_drives[c].scsi_device_id], 0x00, sizeof(scsi_device_t));
if (zip_drives[c].bus_type == ZIP_BUS_SCSI) {
scsi_bus = (zip_drives[c].scsi_device_id >> 4) & 0x0f;
scsi_id = zip_drives[c].scsi_device_id & 0x0f;
memset(&scsi_devices[scsi_bus][scsi_id], 0x00, sizeof(scsi_device_t));
}
dev = (zip_t *) zip_drives[c].priv;

View File

@@ -489,30 +489,30 @@ fdd_load(int drive, char *fn)
if (!p)
return;
f = plat_fopen(fn, "rb");
if (!f)
return;
if (fseek(f, -1, SEEK_END) == -1)
fatal("fdd_load(): Error seeking to the end of the file\n");
size = ftell(f) + 1;
fclose(f);
while (loaders[c].ext) {
if (!strcasecmp(p, (char *) loaders[c].ext) && (size == loaders[c].size || loaders[c].size == -1)) {
driveloaders[drive] = c;
strcpy(floppyfns[drive], fn);
d86f_setup(drive);
loaders[c].load(drive, floppyfns[drive]);
drive_empty[drive] = 0;
fdd_forced_seek(drive, 0);
fdd_changed[drive] = 1;
return;
if (f) {
if (fseek(f, -1, SEEK_END) == -1)
fatal("fdd_load(): Error seeking to the end of the file\n");
size = ftell(f) + 1;
fclose(f);
while (loaders[c].ext) {
if (!strcasecmp(p, (char *) loaders[c].ext) && (size == loaders[c].size || loaders[c].size == -1)) {
driveloaders[drive] = c;
strcpy(floppyfns[drive], fn);
d86f_setup(drive);
loaders[c].load(drive, floppyfns[drive]);
drive_empty[drive] = 0;
fdd_forced_seek(drive, 0);
fdd_changed[drive] = 1;
return;
}
c++;
}
c++;
}
fdd_log("FDD: could not load '%s' %s\n",fn,p);
drive_empty[drive] = 1;
fdd_set_head(drive, 0);
memset(floppyfns[drive], 0, sizeof(floppyfns[drive]));
ui_sb_update_icon_state(drive, 1);
ui_sb_update_icon_state(SB_FLOPPY | drive, 1);
}
@@ -538,7 +538,7 @@ fdd_close(int drive)
drives[drive].byteperiod = NULL;
drives[drive].stop = NULL;
d86f_destroy(drive);
ui_sb_update_icon_state(drive, 1);
ui_sb_update_icon_state(SB_FLOPPY | drive, 1);
}

View File

@@ -189,6 +189,8 @@ extern void resub_cycles(int old_cycles);
extern double isa_timing;
extern int io_delay, framecountx;
extern volatile int cpu_thread_run;
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,40 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Definitions for the PCjr cartridge emulation.
*
*
*
* Authors: Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2021 Miran Grca.
*/
#ifndef EMU_CARTRIDGE_H
# define EMU_CARTRIDGE_H
#ifdef __cplusplus
extern "C" {
#endif
extern char cart_fns[2][512];
extern void cart_load(int drive, char *fn);
extern void cart_close(int drive);
extern void cart_reset(void);
#ifdef __cplusplus
}
#endif
#endif /*EMU_CARTRIDGE_H*/

View File

@@ -0,0 +1,173 @@
/*****************************************************************************
* pce *
*****************************************************************************/
/*****************************************************************************
* File name: src/ibmpc/cassette.h *
* Created: 2008-11-25 by Hampa Hug <hampa@hampa.ch> *
* Copyright: (C) 2008-2019 Hampa Hug <hampa@hampa.ch> *
*****************************************************************************/
/*****************************************************************************
* This program is free software. You can redistribute it and / or modify it *
* under the terms of the GNU General Public License version 2 as published *
* by the Free Software Foundation. *
* *
* This program is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY, without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General *
* Public License for more details. *
*****************************************************************************/
#ifndef PCE_IBMPC_CASSETTE_H
#define PCE_IBMPC_CASSETTE_H 1
#include <stdio.h>
typedef struct {
char save;
char pcm;
unsigned char motor;
unsigned long position;
unsigned long position_save;
unsigned long position_load;
unsigned char data_out;
unsigned char data_inp;
int pcm_out_vol;
int pcm_out_val;
unsigned cas_out_cnt;
unsigned char cas_out_buf;
unsigned cas_inp_cnt;
unsigned char cas_inp_buf;
unsigned char cas_inp_bit;
int pcm_inp_fir[3];
unsigned long clk;
unsigned long clk_pcm;
unsigned long clk_out;
unsigned long clk_inp;
unsigned long srate;
char close;
char *fname;
FILE *fp;
pc_timer_t timer;
} pc_cassette_t;
void pc_cas_init (pc_cassette_t *cas);
void pc_cas_free (pc_cassette_t *cas);
pc_cassette_t *pc_cas_new (void);
void pc_cas_del (pc_cassette_t *cas);
/*!***************************************************************************
* @short Set the cassette file
* @return True on error, false otherwise
*****************************************************************************/
int pc_cas_set_fname (pc_cassette_t *cas, const char *fname);
/*!***************************************************************************
* @short Get the cassette mode
* @return True if in save mode, false if in load mode
*****************************************************************************/
int pc_cas_get_mode (const pc_cassette_t *cas);
/*!***************************************************************************
* @short Set the cassette mode
* @param save If true set save mode, otherwise set load mode
*****************************************************************************/
void pc_cas_set_mode (pc_cassette_t *cas, int save);
/*!***************************************************************************
* @short Get the cassette pcm mode
* @return True if in pcm mode, false if in binary mode
*****************************************************************************/
int pc_cas_get_pcm (const pc_cassette_t *cas);
/*!***************************************************************************
* @short Set the cassette pcm mode
* @param pcm If true set pcm mode, otherwise set binary mode
*****************************************************************************/
void pc_cas_set_pcm (pc_cassette_t *cas, int pcm);
/*!***************************************************************************
* @short Get the pcm sample rate
* @return The sample rate in Hz
*****************************************************************************/
unsigned long pc_cas_get_srate (const pc_cassette_t *cas);
/*!***************************************************************************
* @short Set the pcm sample rate
* @param pcm The sample rate in Hz
*****************************************************************************/
void pc_cas_set_srate (pc_cassette_t *cas, unsigned long srate);
/*!***************************************************************************
* @short Rewind the cassette
*****************************************************************************/
void pc_cas_rewind (pc_cassette_t *cas);
/*!***************************************************************************
* @short Fast forward to the end of the cassette
*****************************************************************************/
void pc_cas_append (pc_cassette_t *cas);
/*!***************************************************************************
* @short Get the current load/save position
*****************************************************************************/
unsigned long pc_cas_get_position (const pc_cassette_t *cas);
/*!***************************************************************************
* @short Set the current load/save position
*****************************************************************************/
int pc_cas_set_position (pc_cassette_t *cas, unsigned long pos);
/*!***************************************************************************
* @short Set the cassette motor status
*****************************************************************************/
void pc_cas_set_motor (pc_cassette_t *cas, unsigned char val);
/*!***************************************************************************
* @short Get the current input from the cassette
*****************************************************************************/
unsigned char pc_cas_get_inp (const pc_cassette_t *cas);
/*!***************************************************************************
* @short Set the current output to the cassette
*****************************************************************************/
void pc_cas_set_out (pc_cassette_t *cas, unsigned char val);
void pc_cas_print_state (const pc_cassette_t *cas);
void pc_cas_clock (pc_cassette_t *cas, unsigned long cnt);
void pc_cas_advance (pc_cassette_t *cas);
extern pc_cassette_t * cassette;
extern char cassette_fname[512];
extern char cassette_mode[512];
extern unsigned long cassette_pos, cassette_srate;
extern int cassette_enable;
extern int cassette_append, cassette_pcm;
extern int cassette_ui_writeprot;
extern const device_t cassette_device;
#endif

View File

@@ -158,6 +158,9 @@ extern void config_set_mac(char *head, char *name, int val);
extern void config_set_string(char *head, char *name, char *val);
extern void config_set_wstring(char *head, char *name, wchar_t *val);
extern void * config_find_section(char *name);
extern void config_rename_section(void *priv, char *name);
#ifdef __cplusplus
}
#endif

View File

@@ -19,7 +19,7 @@
# define EMU_HDD_H
#define HDD_NUM 40 /* total of 40 images supported */
#define HDD_NUM 88 /* total of 88 images supported */
/* Hard Disk bus types. */

View File

@@ -121,6 +121,10 @@
#define IDS_2145 2145 // "You are loading an unsupported..."
#define IDS_2146 2146 // "CPU type filtering based on..."
#define IDS_2147 2147 // "Continue"
#define IDS_2148 2148 // "Cassette: %s"
#define IDS_2149 2149 // "Cassette images (*.PCM;*.RAW;*..."
#define IDS_2150 2150 // "Cartridge %i: %ls"
#define IDS_2151 2151 // "Cartridge images (*.JRC)\0*.JRC\0..."
#define IDS_4096 4096 // "Hard disk (%s)"
#define IDS_4097 4097 // "%01i:%01i"
@@ -161,6 +165,7 @@
#define IDS_4132 4132 // "This could mean that the parent..."
#define IDS_4133 4133 // "Parent and child disk timestamps..."
#define IDS_4134 4134 // "Could not fix VHD timestamp."
#define IDS_4135 4135 // "%01i:%02i"
#define IDS_4352 4352 // "MFM/RLL"
#define IDS_4353 4353 // "XT IDE"
@@ -228,9 +233,9 @@
#define IDS_LANG_ENUS IDS_7168
#define STR_NUM_2048 100
#define STR_NUM_2048 104
#define STR_NUM_3072 11
#define STR_NUM_4096 39
#define STR_NUM_4096 40
#define STR_NUM_4352 6
#define STR_NUM_4608 6
#define STR_NUM_5120 1

View File

@@ -82,6 +82,7 @@
#define MACHINE_IDE_QUAD 0x07800000 /* sys has int quad IDE/ATAPI - mark as dual + both ter and and qua IDE/ATAPI */
#define MACHINE_SCSI 0x08000000 /* sys has int single SCSI - mark as pri SCSI */
#define MACHINE_SCSI_DUAL 0x18000000 /* sys has int dual SCSI - mark as both pri and sec SCSI */
#define MACHINE_CARTRIDGE 0x20000000 /* sys has two cartridge bays */
#define IS_ARCH(m, a) (machines[m].flags & (a)) ? 1 : 0;
#define IS_AT(m) ((machines[m].flags & 0x00000FC8) && !(machines[m].flags & MACHINE_PC98)) ? 1 : 0;

View File

@@ -118,6 +118,7 @@ extern void nvr_at_handler(int set, uint16_t base, nvr_t *nvr);
extern void nvr_at_sec_handler(int set, uint16_t base, nvr_t *nvr);
extern void nvr_read_addr_set(int set, nvr_t *nvr);
extern void nvr_wp_set(int set, int h, nvr_t *nvr);
extern void nvr_via_wp_set(int set, int reg, nvr_t *nvr);
extern void nvr_bank_set(int base, uint8_t bank, nvr_t *nvr);
extern void nvr_lock_set(int base, int size, int lock, nvr_t *nvr);

View File

@@ -64,8 +64,8 @@ extern "C" {
/* Global variables residing in the platform module. */
extern int dopause, /* system is paused */
doresize, /* screen resize requested */
is_quit, /* system exit requested */
mouse_capture; /* mouse is captured in app */
extern volatile int is_quit; /* system exit requested */
#ifdef MTR_ENABLED
extern int tracing_on;
@@ -80,6 +80,8 @@ extern int update_icons;
extern int unscaled_size_x, /* current unscaled size X */
unscaled_size_y; /* current unscaled size Y */
extern int kbd_req_capture, hide_status_bar;
/* System-related functions. */
extern char *fix_exe_path(char *str);
extern FILE *plat_fopen(const char *path, const char *mode);
@@ -129,6 +131,10 @@ extern void plat_power_off(void);
/* Platform-specific device support. */
extern void cassette_mount(char *fn, uint8_t wp);
extern void cassette_eject(void);
extern void cartridge_mount(uint8_t id, char *fn, uint8_t wp);
extern void cartridge_eject(uint8_t id);
extern void floppy_mount(uint8_t id, char *fn, uint8_t wp);
extern void floppy_eject(uint8_t id);
extern void cdrom_mount(uint8_t id, char *fn);
@@ -150,7 +156,6 @@ typedef void event_t;
typedef void mutex_t;
extern thread_t *thread_create(void (*thread_func)(void *param), void *param);
extern void thread_kill(thread_t *arg);
extern int thread_wait(thread_t *arg, int timeout);
extern event_t *thread_create_event(void);
extern void thread_set_event(event_t *arg);

View File

@@ -180,78 +180,86 @@
#define IDC_CHECK_PARALLEL3 1079
#define IDC_OTHER_PERIPH 1080 /* storage controllers config */
#define IDC_COMBO_SCSI 1081
#define IDC_CONFIGURE_SCSI 1082
#define IDC_COMBO_HDC 1083
#define IDC_CONFIGURE_HDC 1084
#define IDC_CHECK_IDE_TER 1085
#define IDC_BUTTON_IDE_TER 1086
#define IDC_CHECK_IDE_QUA 1087
#define IDC_BUTTON_IDE_QUA 1088
#define IDC_COMBO_HDC 1081
#define IDC_CONFIGURE_HDC 1082
#define IDC_CHECK_IDE_TER 1083
#define IDC_BUTTON_IDE_TER 1084
#define IDC_CHECK_IDE_QUA 1085
#define IDC_BUTTON_IDE_QUA 1086
#define IDC_GROUP_SCSI 1087
#define IDC_COMBO_SCSI_1 1088
#define IDC_COMBO_SCSI_2 1089
#define IDC_COMBO_SCSI_3 1090
#define IDC_COMBO_SCSI_4 1091
#define IDC_CONFIGURE_SCSI_1 1092
#define IDC_CONFIGURE_SCSI_2 1093
#define IDC_CONFIGURE_SCSI_3 1094
#define IDC_CONFIGURE_SCSI_4 1095
#define IDC_CHECK_CASSETTE 1096
#define IDC_HARD_DISKS 1090 /* hard disks config */
#define IDC_LIST_HARD_DISKS 1091
#define IDC_BUTTON_HDD_ADD_NEW 1092
#define IDC_BUTTON_HDD_ADD 1093
#define IDC_BUTTON_HDD_REMOVE 1094
#define IDC_COMBO_HD_BUS 1095
#define IDC_COMBO_HD_CHANNEL 1096
#define IDC_COMBO_HD_ID 1097
#define IDC_COMBO_HD_LUN 1098
#define IDC_COMBO_HD_CHANNEL_IDE 1099
#define IDC_HARD_DISKS 1100 /* hard disks config */
#define IDC_LIST_HARD_DISKS 1101
#define IDC_BUTTON_HDD_ADD_NEW 1102
#define IDC_BUTTON_HDD_ADD 1103
#define IDC_BUTTON_HDD_REMOVE 1104
#define IDC_COMBO_HD_BUS 1105
#define IDC_COMBO_HD_CHANNEL 1106
#define IDC_COMBO_HD_ID 1107
#define IDC_COMBO_HD_LUN 1108
#define IDC_COMBO_HD_CHANNEL_IDE 1109
#define IDC_EDIT_HD_FILE_NAME 1100 /* add hard disk dialog */
#define IDC_EDIT_HD_SPT 1101
#define IDC_EDIT_HD_HPC 1102
#define IDC_EDIT_HD_CYL 1103
#define IDC_EDIT_HD_SIZE 1104
#define IDC_COMBO_HD_TYPE 1105
#define IDC_PBAR_IMG_CREATE 1106
#define IDC_COMBO_HD_IMG_FORMAT 1107
#define IDC_COMBO_HD_BLOCK_SIZE 1108
#define IDC_EDIT_HD_FILE_NAME 1110 /* add hard disk dialog */
#define IDC_EDIT_HD_SPT 1111
#define IDC_EDIT_HD_HPC 1112
#define IDC_EDIT_HD_CYL 1113
#define IDC_EDIT_HD_SIZE 1114
#define IDC_COMBO_HD_TYPE 1115
#define IDC_PBAR_IMG_CREATE 1116
#define IDC_COMBO_HD_IMG_FORMAT 1117
#define IDC_COMBO_HD_BLOCK_SIZE 1118
#define IDC_REMOV_DEVICES 1110 /* floppy and cd-rom drives config */
#define IDC_LIST_FLOPPY_DRIVES 1111
#define IDC_COMBO_FD_TYPE 1112
#define IDC_CHECKTURBO 1113
#define IDC_CHECKBPB 1114
#define IDC_LIST_CDROM_DRIVES 1115
#define IDC_COMBO_CD_BUS 1116
#define IDC_COMBO_CD_ID 1117
#define IDC_COMBO_CD_LUN 1118
#define IDC_COMBO_CD_CHANNEL_IDE 1119
#define IDC_REMOV_DEVICES 1120 /* floppy and cd-rom drives config */
#define IDC_LIST_FLOPPY_DRIVES 1121
#define IDC_COMBO_FD_TYPE 1122
#define IDC_CHECKTURBO 1123
#define IDC_CHECKBPB 1124
#define IDC_LIST_CDROM_DRIVES 1125
#define IDC_COMBO_CD_BUS 1126
#define IDC_COMBO_CD_ID 1127
#define IDC_COMBO_CD_LUN 1128
#define IDC_COMBO_CD_CHANNEL_IDE 1129
#define IDC_LIST_ZIP_DRIVES 1120 /* other removable devices config */
#define IDC_COMBO_ZIP_BUS 1121
#define IDC_COMBO_ZIP_ID 1122
#define IDC_COMBO_ZIP_LUN 1123
#define IDC_COMBO_ZIP_CHANNEL_IDE 1124
#define IDC_CHECK250 1125
#define IDC_COMBO_CD_SPEED 1126
#define IDC_LIST_MO_DRIVES 1127
#define IDC_COMBO_MO_BUS 1128
#define IDC_COMBO_MO_ID 1129
#define IDC_COMBO_MO_LUN 1130
#define IDC_COMBO_MO_CHANNEL_IDE 1131
#define IDC_COMBO_MO_TYPE 1132
#define IDC_LIST_ZIP_DRIVES 1130 /* other removable devices config */
#define IDC_COMBO_ZIP_BUS 1131
#define IDC_COMBO_ZIP_ID 1132
#define IDC_COMBO_ZIP_LUN 1133
#define IDC_COMBO_ZIP_CHANNEL_IDE 1134
#define IDC_CHECK250 1135
#define IDC_COMBO_CD_SPEED 1136
#define IDC_LIST_MO_DRIVES 1137
#define IDC_COMBO_MO_BUS 1138
#define IDC_COMBO_MO_ID 1139
#define IDC_COMBO_MO_LUN 1140
#define IDC_COMBO_MO_CHANNEL_IDE 1141
#define IDC_COMBO_MO_TYPE 1142
#define IDC_CHECK_BUGGER 1140 /* other periph config */
#define IDC_CHECK_POSTCARD 1141
#define IDC_COMBO_ISARTC 1142
#define IDC_CONFIGURE_ISARTC 1143
#define IDC_COMBO_FDC 1144
#define IDC_CONFIGURE_FDC 1145
#define IDC_GROUP_ISAMEM 1146
#define IDC_COMBO_ISAMEM_1 1147
#define IDC_COMBO_ISAMEM_2 1148
#define IDC_COMBO_ISAMEM_3 1149
#define IDC_COMBO_ISAMEM_4 1150
#define IDC_CONFIGURE_ISAMEM_1 1151
#define IDC_CONFIGURE_ISAMEM_2 1152
#define IDC_CONFIGURE_ISAMEM_3 1153
#define IDC_CONFIGURE_ISAMEM_4 1154
#define IDC_CHECK_BUGGER 1150 /* other periph config */
#define IDC_CHECK_POSTCARD 1151
#define IDC_COMBO_ISARTC 1152
#define IDC_CONFIGURE_ISARTC 1153
#define IDC_COMBO_FDC 1154
#define IDC_CONFIGURE_FDC 1155
#define IDC_GROUP_ISAMEM 1156
#define IDC_COMBO_ISAMEM_1 1157
#define IDC_COMBO_ISAMEM_2 1158
#define IDC_COMBO_ISAMEM_3 1159
#define IDC_COMBO_ISAMEM_4 1160
#define IDC_CONFIGURE_ISAMEM_1 1161
#define IDC_CONFIGURE_ISAMEM_2 1162
#define IDC_CONFIGURE_ISAMEM_3 1163
#define IDC_CONFIGURE_ISAMEM_4 1164
#define IDC_SLIDER_GAIN 1160 /* sound gain dialog */
#define IDC_SLIDER_GAIN 1170 /* sound gain dialog */
#define IDC_EDIT_FILE_NAME 1200 /* new floppy image dialog */
#define IDC_COMBO_DISK_SIZE 1201
@@ -285,21 +293,21 @@
#define IDM_ABOUT 40001
#define IDC_ABOUT_ICON 65535
#define IDM_ACTION_RCTRL_IS_LALT 40010
#define IDM_ACTION_SCREENSHOT 40011
#define IDM_ACTION_HRESET 40012
#define IDM_ACTION_RESET_CAD 40013
#define IDM_ACTION_EXIT 40014
#define IDM_ACTION_CTRL_ALT_ESC 40015
#define IDM_ACTION_PAUSE 40016
#define IDM_ACTION_KBD_REQ_CAPTURE 40010
#define IDM_ACTION_RCTRL_IS_LALT 40011
#define IDM_ACTION_SCREENSHOT 40012
#define IDM_ACTION_HRESET 40013
#define IDM_ACTION_RESET_CAD 40014
#define IDM_ACTION_EXIT 40015
#define IDM_ACTION_CTRL_ALT_ESC 40016
#define IDM_ACTION_PAUSE 40017
#ifdef MTR_ENABLED
#define IDM_ACTION_BEGIN_TRACE 40017
#define IDM_ACTION_END_TRACE 40018
#define IDM_ACTION_TRACE 40019
#define IDM_ACTION_BEGIN_TRACE 40018
#define IDM_ACTION_END_TRACE 40019
#define IDM_ACTION_TRACE 40020
#endif
#define IDM_CONFIG 40020
#define IDM_CONFIG_LOAD 40021
#define IDM_CONFIG_SAVE 40022
#define IDM_VID_HIDE_STATUS_BAR 40021
#define IDM_UPDATE_ICONS 40030
#define IDM_VID_RESIZE 40040
#define IDM_VID_REMEMBER 40041
@@ -371,29 +379,41 @@
* and 5 bits for Removable Disks (5 bits for ID), so we use an
* 8bit (256 entries) space for these devices.
*/
#define IDM_FLOPPY_IMAGE_NEW 0x1200
#define IDM_FLOPPY_IMAGE_EXISTING 0x1300
#define IDM_FLOPPY_IMAGE_EXISTING_WP 0x1400
#define IDM_FLOPPY_EXPORT_TO_86F 0x1500
#define IDM_FLOPPY_EJECT 0x1600
#define IDM_CASSETTE_IMAGE_NEW 0x1200
#define IDM_CASSETTE_IMAGE_EXISTING 0x1300
#define IDM_CASSETTE_IMAGE_EXISTING_WP 0x1400
#define IDM_CASSETTE_RECORD 0x1500
#define IDM_CASSETTE_PLAY 0x1600
#define IDM_CASSETTE_REWIND 0x1700
#define IDM_CASSETTE_FAST_FORWARD 0x1800
#define IDM_CASSETTE_EJECT 0x1900
#define IDM_CDROM_MUTE 0x2200
#define IDM_CDROM_EMPTY 0x2300
#define IDM_CDROM_RELOAD 0x2400
#define IDM_CDROM_IMAGE 0x2500
#define IDM_CDROM_HOST_DRIVE 0x2600
#define IDM_CARTRIDGE_IMAGE 0x2200
#define IDM_CARTRIDGE_EJECT 0x2300
#define IDM_ZIP_IMAGE_NEW 0x3200
#define IDM_ZIP_IMAGE_EXISTING 0x3300
#define IDM_ZIP_IMAGE_EXISTING_WP 0x3400
#define IDM_ZIP_EJECT 0x3500
#define IDM_ZIP_RELOAD 0x3600
#define IDM_FLOPPY_IMAGE_NEW 0x3200
#define IDM_FLOPPY_IMAGE_EXISTING 0x3300
#define IDM_FLOPPY_IMAGE_EXISTING_WP 0x3400
#define IDM_FLOPPY_EXPORT_TO_86F 0x3500
#define IDM_FLOPPY_EJECT 0x3600
#define IDM_MO_IMAGE_NEW 0x4200
#define IDM_MO_IMAGE_EXISTING 0x4300
#define IDM_MO_IMAGE_EXISTING_WP 0x4400
#define IDM_MO_EJECT 0x4500
#define IDM_MO_RELOAD 0x4600
#define IDM_CDROM_MUTE 0x4200
#define IDM_CDROM_EMPTY 0x4300
#define IDM_CDROM_RELOAD 0x4400
#define IDM_CDROM_IMAGE 0x4500
#define IDM_CDROM_HOST_DRIVE 0x4600
#define IDM_ZIP_IMAGE_NEW 0x5200
#define IDM_ZIP_IMAGE_EXISTING 0x5300
#define IDM_ZIP_IMAGE_EXISTING_WP 0x5400
#define IDM_ZIP_EJECT 0x5500
#define IDM_ZIP_RELOAD 0x5600
#define IDM_MO_IMAGE_NEW 0x6200
#define IDM_MO_IMAGE_EXISTING 0x6300
#define IDM_MO_IMAGE_EXISTING_WP 0x6400
#define IDM_MO_EJECT 0x6500
#define IDM_MO_RELOAD 0x6600
/* Next default values for new objects */

View File

@@ -21,7 +21,7 @@
#ifndef EMU_SCSI_H
#define EMU_SCSI_H
extern int scsi_card_current;
extern int scsi_card_current[4];
extern int scsi_card_available(int card);
#ifdef EMU_DEVICE_H

View File

@@ -21,6 +21,8 @@
/* Configuration. */
#define SCSI_BUS_MAX 4 /* currently we support up to 4 controllers */
#define SCSI_ID_MAX 16 /* 16 on wide buses */
#define SCSI_LUN_MAX 8 /* always 8 */
@@ -359,7 +361,7 @@ typedef struct {
#define SCSI_REMOVABLE_DISK 0x8000
#define SCSI_REMOVABLE_CDROM 0x8005
extern scsi_device_t scsi_devices[SCSI_ID_MAX];
extern scsi_device_t scsi_devices[SCSI_BUS_MAX][SCSI_ID_MAX];
extern int cdrom_add_error_and_subchannel(uint8_t *b, int real_sector_type);
@@ -384,4 +386,7 @@ extern void scsi_device_identify(scsi_device_t *dev, uint8_t lun);
extern void scsi_device_close_all(void);
extern void scsi_device_init(void);
extern void scsi_reset(void);
extern uint8_t scsi_get_bus(void);
#endif /*SCSI_DEVICE_H*/

View File

@@ -382,7 +382,7 @@ typedef struct {
uint8_t callback_phase :4,
callback_sub_phase :4,
scsi_cmd_phase, pad,
scsi_cmd_phase, bus,
sync,
parity, shram_mode,
Geometry, Control,
@@ -429,7 +429,7 @@ typedef struct {
PendingInterrupt, Lock,
target_data_len, pad0;
uint32_t Base, fdc_address, rom_addr, /* address of BIOS ROM */
uint32_t Base, fdc_address, rom_addr, /* address of BIOS ROM */
CmdParamLeft, Outgoing,
transfer_size;
@@ -441,7 +441,7 @@ typedef struct {
BIOSMailboxInit, BIOSMailboxCount,
BIOSMailboxOutAddr, BIOSMailboxOutPosCur,
BIOSMailboxReq,
Residue, bus; /* Basically a copy of device flags */
Residue, card_bus; /* Basically a copy of device flags */
/* 8 bytes */
uint64_t temp_period;

View File

@@ -30,9 +30,8 @@
#define SBPRO 5 /* DSP v3.00 */
#define SBPRO2 6 /* DSP v3.02 + OPL3 */
#define SB16 7 /* DSP v4.05 + OPL3 */
#define SADGOLD 8 /* AdLib Gold */
#define SND_WSS 9 /* Windows Sound System */
#define SND_PAS16 10 /* Pro Audio Spectrum 16 */
#define SBAWE32 8 /* DSP v4.13 + OPL3 */
#define SBAWE64 9 /* DSP v4.16 + OPL3 */
/* SB 2.0 CD version */
typedef struct sb_ct1335_mixer_t

View File

@@ -116,6 +116,7 @@ extern const device_t sb_16_pnp_device;
extern const device_t sb_32_pnp_device;
extern const device_t sb_awe32_device;
extern const device_t sb_awe32_pnp_device;
extern const device_t sb_awe64_gold_device;
/* Innovation SSI-2001 */
extern const device_t ssi2001_device;

View File

@@ -50,14 +50,16 @@ extern void ui_check_menu_item(int id, int checked);
/* Status Bar functions. */
#define SB_ICON_WIDTH 24
#define SB_FLOPPY 0x00
#define SB_CDROM 0x10
#define SB_ZIP 0x20
#define SB_MO 0x30
#define SB_HDD 0x40
#define SB_NETWORK 0x50
#define SB_SOUND 0x60
#define SB_TEXT 0x70
#define SB_CASSETTE 0x00
#define SB_CARTRIDGE 0x10
#define SB_FLOPPY 0x20
#define SB_CDROM 0x30
#define SB_ZIP 0x40
#define SB_MO 0x50
#define SB_HDD 0x60
#define SB_NETWORK 0x70
#define SB_SOUND 0x80
#define SB_TEXT 0x90
extern wchar_t *ui_window_title(wchar_t *s);
extern void ui_status_update(void);

View File

@@ -500,8 +500,9 @@ typedef struct voodoo_t
void *codegen_data;
struct voodoo_set_t *set;
uint8_t fifo_thread_run, render_thread_run[4];
uint8_t *vram, *changedvram;
void *p;

View File

@@ -58,6 +58,8 @@ DECLARE_HANDLE(DPI_AWARENESS_CONTEXT);
#define SDL_CLASS_NAME L"86BoxSDLWnd"
#define SDL_SUB_CLASS_NAME L"86BoxSDLSubWnd"
#define CASSETTE_SUBMENU_NAME L"CassetteSubmenu"
#define CARTRIDGE_SUBMENU_NAME L"CartridgeSubmenu"
#define FLOPPY_SUBMENU_NAME L"FloppySubmenu"
#define CDROM_SUBMENU_NAME L"CdromSubmenu"
#define ZIP_SUBMENU_NAME L"ZIPSubmenu"
@@ -220,10 +222,14 @@ extern wchar_t *BrowseFolder(wchar_t *saved_path, wchar_t *title);
extern void media_menu_init();
extern void media_menu_reset();
extern int media_menu_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
extern HMENU media_menu_get_cassette(void);
extern HMENU media_menu_get_cartridge(int id);
extern HMENU media_menu_get_floppy(int id);
extern HMENU media_menu_get_cdrom(int id);
extern HMENU media_menu_get_zip(int id);
extern HMENU media_menu_get_mo(int id);
extern void media_menu_update_cassette(void);
extern void media_menu_update_cartridge(int id);
extern void media_menu_update_floppy(int id);
extern void media_menu_update_cdrom(int id);
extern void media_menu_update_zip(int id);

View File

@@ -108,7 +108,8 @@ typedef struct {
stat;
uint8_t plane_write, /* 1512/200 */
plane_read, /* 1512/200 */
border; /* 1512/200 */
border, /* 1512/200 */
invert; /* 512/640 */
int fontbase; /* 1512/200 */
int linepos,
displine;
@@ -1695,8 +1696,17 @@ vid_init_200(amstrad_t *ams)
overscan_x = overscan_y = 16;
green = makecol(0x1C, 0x71, 0x31);
blue = makecol(0x0f, 0x21, 0x3f);
if (ams->type == AMS_PC200)
vid->invert = 0;
else
vid->invert = device_get_config_int("invert");
if (vid->invert) {
blue = makecol(0x1C, 0x71, 0x31);
green = makecol(0x0f, 0x21, 0x3f);
} else {
green = makecol(0x1C, 0x71, 0x31);
blue = makecol(0x0f, 0x21, 0x3f);
}
cgapal_rebuild();
set_lcd_cols(0);
@@ -1954,6 +1964,9 @@ device_config_t vid_ppc512_config[] =
}
}
},
{
"invert", "Invert LCD colors", CONFIG_BINARY, "", 0
},
{
"", "", -1
}
@@ -2441,6 +2454,8 @@ machine_amstrad_init(const machine_t *model, int type)
ams->language = 7;
video_reset(gfxcard);
if (gfxcard == VID_INTERNAL) switch(type) {
case AMS_PC1512:
loadfont("roms/machines/pc1512/40078", 8);

View File

@@ -348,7 +348,10 @@ machine_at_gw286ct_init(const machine_t *model)
device_add(&f82c710_device);
machine_at_scat_init(model, 1);
machine_at_common_init(model);
device_add(&keyboard_at_device);
device_add(&scat_4_device);
device_add(&ide_isa_device);

View File

@@ -823,6 +823,8 @@ machine_at_compaq_init(const machine_t *model, int type)
write_ram, write_ramw, write_raml,
0xa0000+ram, MEM_MAPPING_INTERNAL, NULL);
video_reset(gfxcard);
switch(type) {
case COMPAQ_PORTABLEII:
break;

View File

@@ -365,6 +365,7 @@ void t3100e_map_ram(uint8_t val)
int n;
int32_t upper_len;
#ifdef ENABLE_T3100E_LOG
t3100e_log("OUT 0x8084, %02x [ set memory mapping :", val | 0x40);
if (val & 1) t3100e_log("ENABLE_EMS ");
if (val & 2) t3100e_log("ENABLE_XMS ");
@@ -372,6 +373,7 @@ void t3100e_map_ram(uint8_t val)
if (val & 8) t3100e_log("X8X ");
if (val & 16) t3100e_log("UPPER_IS_XMS ");
t3100e_log("\n");
#endif
/* Bit 2 controls size of conventional memory */
if (val & 4)
@@ -632,7 +634,7 @@ static uint16_t ems_read_ramw(uint32_t addr, void *priv)
struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *)priv;
int pg = addr_to_page(addr);
if (pg < 0) return 0xFF;
if (pg < 0) return 0xFFFF;
//t3100e_log("ems_read_ramw addr=%05x ", addr);
addr = regs->page_exec[pg] + (addr & 0x3FFF);
//t3100e_log("-> %06x val=%04x\n", addr, *(uint16_t *)&ram[addr]);
@@ -645,7 +647,7 @@ static uint32_t ems_read_raml(uint32_t addr, void *priv)
struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *)priv;
int pg = addr_to_page(addr);
if (pg < 0) return 0xFF;
if (pg < 0) return 0xFFFFFFFF;
addr = regs->page_exec[pg] + (addr & 0x3FFF);
return *(uint32_t *)&ram[addr];
}

View File

@@ -29,6 +29,8 @@
#include <86box/86box.h>
#include "cpu.h"
#include <86box/timer.h>
#include <86box/device.h>
#include <86box/cassette.h>
#include <86box/io.h>
#include <86box/nmi.h>
#include <86box/pic.h>
@@ -614,6 +616,11 @@ kbd_write(uint16_t port, uint8_t val, void *priv)
case 0x61:
pcjr->pb = val;
timer_process();
if (cassette != NULL)
pc_cas_set_motor(cassette, (pcjr->pb & 0x08) == 0);
speaker_update();
speaker_gated = val & 1;
speaker_enable = val & 2;
@@ -657,10 +664,14 @@ kbd_read(uint16_t port, void *priv)
case 0x61:
ret = pcjr->pb;
break;
case 0x62:
ret = (pcjr->latched ? 1 : 0);
ret |= 0x02; /*Modem card not installed*/
if ((pcjr->pb & 0x08) || (cassette == NULL))
ret |= (ppispeakon ? 0x10 : 0);
else
ret |= (pc_cas_get_inp(cassette) ? 0x10 : 0);
ret |= (ppispeakon ? 0x10 : 0);
ret |= (ppispeakon ? 0x20 : 0);
ret |= (pcjr->data ? 0x40: 0);
@@ -824,6 +835,7 @@ machine_pcjr_init(const machine_t *model)
cpu_set();
/* Initialize the video controller. */
video_reset(gfxcard);
loadfont("roms/video/mda/mda.rom", 0);
mem_mapping_add(&pcjr->mapping, 0xb8000, 0x08000,
vid_read, NULL, NULL,

View File

@@ -811,8 +811,13 @@ vid_poll(void *priv)
}
} else {
for (c = 0; c < 8; c++) {
buffer32->line[(vid->displine << 1)][(x << 3) + c + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 3) + c + 8] =
cols[(fontdat[chr][vid->sc & 7] & (1 << (c ^ 7))) ? 1 : 0];
if (vid->sc == 8) {
buffer32->line[(vid->displine << 1)][(x << 3) + c + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 3) + c + 8] =
cols[(fontdat[chr][7] & (1 << (c ^ 7))) ? 1 : 0];
} else {
buffer32->line[(vid->displine << 1)][(x << 3) + c + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 3) + c + 8] =
cols[(fontdat[chr][vid->sc & 7] & (1 << (c ^ 7))) ? 1 : 0];
}
}
}
if (drawcursor) {
@@ -844,9 +849,15 @@ vid_poll(void *priv)
cols[0];
} else {
for (c = 0; c < 8; c++) {
buffer32->line[(vid->displine << 1)][(x << 4) + (c << 1) + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + (c << 1) + 8] =
buffer32->line[(vid->displine << 1)][(x << 4) + (c << 1) + 1 + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + (c << 1) + 1 + 8] =
cols[(fontdat[chr][vid->sc & 7] & (1 << (c ^ 7))) ? 1 : 0];
if (vid->sc == 8) {
buffer32->line[(vid->displine << 1)][(x << 4) + (c << 1) + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + (c << 1) + 8] =
buffer32->line[(vid->displine << 1)][(x << 4) + (c << 1) + 1 + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + (c << 1) + 1 + 8] =
cols[(fontdat[chr][7] & (1 << (c ^ 7))) ? 1 : 0];
} else {
buffer32->line[(vid->displine << 1)][(x << 4) + (c << 1) + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + (c << 1) + 8] =
buffer32->line[(vid->displine << 1)][(x << 4) + (c << 1) + 1 + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + (c << 1) + 1 + 8] =
cols[(fontdat[chr][vid->sc & 7] & (1 << (c ^ 7))) ? 1 : 0];
}
}
}
if (drawcursor) {
@@ -1509,6 +1520,8 @@ machine_tandy1k_init(const machine_t *model, int type)
if (fdc_type == FDC_INTERNAL)
device_add(&fdc_xt_tandy_device);
video_reset(gfxcard);
switch(type) {
case TYPE_TANDY:
keyboard_set_table(scancode_tandy);

View File

@@ -99,6 +99,9 @@ static int key_queue_start = 0,
video_timings_t timing_m19_vid = {VIDEO_ISA, 8, 16, 32, 8, 16, 32};
const device_t m19_vid_device;
#ifdef ENABLE_M24VID_LOG
int m24vid_do_log = ENABLE_M24VID_LOG;
@@ -530,6 +533,8 @@ m19_vid_speed_changed(void *priv)
static void
m19_vid_init(m19_vid_t *vid)
{
device_context(&m19_vid_device);
/* int display_type; */
vid->mode = OLIVETTI_OGC_MODE;
@@ -541,23 +546,23 @@ m19_vid_init(m19_vid_t *vid)
loadfont_ex("roms/machines/m19/BIOS.BIN", 1, 90);
/* composite is not working yet */
vid->ogc.cga.composite = 0; // (display_type != CGA_RGB);
/* vid->ogc.cga.snow_enabled = device_get_config_int("snow_enabled"); */
vid->ogc.cga.revision = device_get_config_int("composite_type");
vid->ogc.cga.snow_enabled = device_get_config_int("snow_enabled");
vid->ogc.cga.vram = malloc(0x8000);
/* cga_comp_init(vid->ogc.cga.revision); */
/* vid->ogc.cga.rgb_type = device_get_config_int("rgb_type"); */
/* cga_palette = (vid->ogc.cga.rgb_type << 1); */
cga_palette = 0;
vid->ogc.cga.rgb_type = device_get_config_int("rgb_type");
cga_palette = (vid->ogc.cga.rgb_type << 1);
cgapal_rebuild();
ogc_mdaattr_rebuild();
/* color display */
/* if (device_get_config_int("rgb_type")==0 || device_get_config_int("rgb_type") == 4) */
vid->ogc.mono_display = 1;
/* else */
/* vid->ogc.mono_display = 1; */
if (device_get_config_int("rgb_type")==0 || device_get_config_int("rgb_type") == 4)
vid->ogc.mono_display = 0;
else
vid->ogc.mono_display = 1;
/* OGC emulation part end */
/* Plantronics emulation part begin*/
@@ -577,6 +582,8 @@ m19_vid_init(m19_vid_t *vid)
io_sethandler(0x03d0, 0x0010, m19_vid_in, NULL, NULL, m19_vid_out, NULL, NULL, vid);
vid->mode = OLIVETTI_OGC_MODE;
device_context_restore();
}
@@ -590,6 +597,37 @@ const device_t m24_kbd_device = {
{ NULL }, NULL, NULL
};
const device_config_t m19_vid_config[] =
{
{
/* Olivetti / ATT compatible displays */
"rgb_type", "RGB type", CONFIG_SELECTION, "", CGA_RGB, "", { 0 },
{
{
"Color", 0
},
{
"Green Monochrome", 1
},
{
"Amber Monochrome", 2
},
{
"Gray Monochrome", 3
},
{
""
}
}
},
{
"snow_enabled", "Snow emulation", CONFIG_BINARY, "", 1,
},
{
"", "", -1
}
};
const device_t m19_vid_device = {
"Olivetti M19 graphics card",
0, 0,
@@ -597,7 +635,7 @@ const device_t m19_vid_device = {
{ NULL },
m19_vid_speed_changed,
NULL,
NULL
m19_vid_config
};
const device_t *
@@ -708,6 +746,7 @@ int
machine_xt_m24_init(const machine_t *model)
{
int ret;
m24_kbd_t *m24_kbd;
ret = bios_load_interleaved("roms/machines/m24/olivetti_m24_version_1.43_low.bin",
"roms/machines/m24/olivetti_m24_version_1.43_high.bin",
@@ -716,11 +755,6 @@ machine_xt_m24_init(const machine_t *model)
if (bios_only || !ret)
return ret;
if (gfxcard == VID_INTERNAL)
device_add(&ogc_m24_device);
m24_kbd_t *m24_kbd;
m24_kbd = (m24_kbd_t *) malloc(sizeof(m24_kbd_t));
memset(m24_kbd, 0x00, sizeof(m24_kbd_t));
@@ -733,9 +767,6 @@ machine_xt_m24_init(const machine_t *model)
/* Address 66-67 = mainboard dip-switch settings */
io_sethandler(0x0066, 2, m24_read, NULL, NULL, NULL, NULL, NULL, NULL);
m24_kbd_init(m24_kbd);
device_add_ex(&m24_kbd_device, m24_kbd);
/* FIXME: make sure this is correct?? */
device_add(&at_nvr_device);
@@ -743,6 +774,14 @@ machine_xt_m24_init(const machine_t *model)
nmi_init();
video_reset(gfxcard);
if (gfxcard == VID_INTERNAL)
device_add(&ogc_m24_device);
m24_kbd_init(m24_kbd);
device_add_ex(&m24_kbd_device, m24_kbd);
return ret;
}
@@ -818,16 +857,21 @@ machine_xt_m19_init(const machine_t *model)
machine_common_init(model);
pit_ctr_set_out_func(&pit->counters[1], pit_refresh_timer_xt);
/* On-board FDC cannot be disabled */
device_add(&fdc_xt_device);
nmi_init();
video_reset(gfxcard);
m19_vid_init(vid);
device_add_ex(&m19_vid_device, vid);
device_add(&keyboard_xt_olivetti_device);
nmi_init();
pit_set_clock(14318184.0);
return ret;
}

View File

@@ -119,6 +119,7 @@ typedef struct t1000_t
int dispon;
int vsynctime;
uint8_t video_options;
uint8_t backlight, invert;
uint8_t *vram;
} t1000_t;
@@ -588,8 +589,23 @@ static void t1000_recalcattrs(t1000_t *t1000)
* are bold */
/* Set up colours */
blue = makecol(0x2D, 0x39, 0x5A);
grey = makecol(0x85, 0xa0, 0xD6);
if (t1000->invert) {
if (t1000->backlight) {
grey = makecol(0x2D, 0x39, 0x5A);
blue = makecol(0x85, 0xa0, 0xD6);
} else {
grey = makecol(0x0f, 0x21, 0x3f);
blue = makecol(0x1C, 0x71, 0x31);
}
} else {
if (t1000->backlight) {
blue = makecol(0x2D, 0x39, 0x5A);
grey = makecol(0x85, 0xa0, 0xD6);
} else {
blue = makecol(0x0f, 0x21, 0x3f);
grey = makecol(0x1C, 0x71, 0x31);
}
}
/* Initialise the attribute mapping. Start by defaulting everything
* to grey on blue, and with bold set by bit 3 */
@@ -682,6 +698,9 @@ static void *t1000_init(const device_t *info)
t1000->internal = 1;
t1000->backlight = device_get_config_int("backlight");
t1000->invert = device_get_config_int("invert");
/* 16k video RAM */
t1000->vram = malloc(0x4000);
@@ -740,6 +759,12 @@ static const device_config_t t1000_config[] =
},
.default_int = 0
},
{
"backlight", "Enable backlight", CONFIG_BINARY, "", 1
},
{
"invert", "Invert colors", CONFIG_BINARY, "", 0
},
{
.type = -1
}

View File

@@ -27,6 +27,8 @@
#include <86box/86box.h>
#include <86box/device.h>
#include <86box/timer.h>
#include <86box/cassette.h>
#include <86box/cartridge.h>
#include <86box/dma.h>
#include <86box/pic.h>
#include <86box/pit.h>
@@ -82,11 +84,19 @@ machine_init_ex(int m)
AT = IS_AT(machine);
PCI = IS_ARCH(machine, MACHINE_BUS_PCI);
cpu_set();
pc_speed_changed();
/* Reset the memory state. */
mem_reset();
smbase = is_am486dxl ? 0x00060000 : 0x00030000;
lpt_init();
if (cassette_enable)
device_add(&cassette_device);
cart_reset();
}
/* All good, boot the machine! */
@@ -132,7 +142,5 @@ machine_common_init(const machine_t *model)
pic_init();
dma_init();
cpu_set();
pit_common_init(!!AT, pit_irq0_timer, NULL);
}

View File

@@ -107,7 +107,7 @@ const machine_t machines[] = {
/* 8088 Machines */
{ "[8088] IBM PC (1981)", "ibmpc", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 16, 64, 16, 0, machine_pc_init, NULL },
{ "[8088] IBM PC (1982)", "ibmpc82", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 256, 256, 256, 0, machine_pc82_init, NULL },
{ "[8088] IBM PCjr", "ibmpcjr", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 4772728, 4772728, 0, 0, 0, 0, MACHINE_PC | MACHINE_VIDEO_FIXED, 128, 640, 128, 0, machine_pcjr_init, pcjr_get_device },
{ "[8088] IBM PCjr", "ibmpcjr", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 4772728, 4772728, 0, 0, 0, 0, MACHINE_PC | MACHINE_VIDEO_FIXED | MACHINE_CARTRIDGE, 128, 640, 128, 0, machine_pcjr_init, pcjr_get_device },
{ "[8088] IBM XT (1982)", "ibmxt", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 64, 256, 64, 0, machine_xt_init, NULL },
{ "[8088] IBM XT (1986)", "ibmxt86", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 256, 640, 64, 0, machine_xt86_init, NULL },
{ "[8088] American XT Computer", "americxt", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 64, 640, 64, 0, machine_xt_americxt_init, NULL },
@@ -120,7 +120,7 @@ const machine_t machines[] = {
{ "[8088] Juko ST", "jukopc", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 64, 640, 64, 0, machine_xt_jukopc_init, NULL },
{ "[8088] Multitech PC-700", "pc700", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 128, 640, 64, 0, machine_xt_pc700_init, NULL },
{ "[8088] NCR PC4i", "pc4i", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 256, 640, 256, 0, machine_xt_pc4i_init, NULL },
{ "[8088] Olivetti M19", "m19", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC | MACHINE_VIDEO_FIXED, 256, 640, 256, 0, machine_xt_m19_init, NULL },
{ "[8088] Olivetti M19", "m19", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 4772728, 7159092, 0, 0, 0, 0, MACHINE_PC | MACHINE_VIDEO_FIXED, 256, 640, 256, 0, machine_xt_m19_init, m19_get_device },
{ "[8088] OpenXT", "openxt", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 64, 640, 64, 0, machine_xt_openxt_init, NULL },
{ "[8088] Philips P3105/NMS9100", "p3105", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC | MACHINE_XTA, 256, 768, 256, 0, machine_xt_p3105_init, NULL },
{ "[8088] Phoenix XT clone", "pxxt", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 64, 640, 64, 0, machine_xt_pxxt_init, NULL },

View File

@@ -175,13 +175,14 @@ static uint8_t
sst_read_id(uint32_t addr, void *p)
{
sst_t *dev = (sst_t *) p;
uint8_t ret = 0xff;
if ((addr & 0xffff) == 0)
return SST_ID_MANUFACTURER; /* SST */
ret = SST_ID_MANUFACTURER; /* SST */
else if ((addr & 0xffff) == 1)
return dev->id;
else
return 0xff;
ret = dev->id;
return ret;
}
@@ -237,7 +238,10 @@ sst_write(uint32_t addr, uint8_t val, void *p)
case 2:
case 5:
/* 3rd and 6th Bus Write Cycle */
if ((addr & 0x7fff) == 0x5555)
if ((dev->command_state == 5) && (val == SST_SECTOR_ERASE)) {
/* Sector erase - can be on any address. */
sst_new_command(dev, addr, val);
} else if ((addr & 0x7fff) == 0x5555)
sst_new_command(dev, addr, val);
else
dev->command_state = 0;

View File

@@ -299,7 +299,9 @@ typedef struct {
int8_t stat;
uint8_t cent, def,
flags, read_addr;
flags, read_addr,
wp_0d, wp_32,
pad, pad0;
uint8_t addr[8], wp[2],
bank[8], *lock;
@@ -587,14 +589,6 @@ nvr_reg_write(uint16_t reg, uint8_t val, void *priv)
break;
case RTC_REGD: /* R/O */
/* VT82C686A/B have an ACPI register bit controlled by 0D bit 7.
This is overwritten on read, but testing shows BIOSes will
immediately check the ACPI register after writing to this. */
if (local->cent == RTC_CENTURY_VIA) {
nvr->regs[RTC_REGD] &= ~0x80;
if (val & 0x80)
nvr->regs[RTC_REGD] |= 0x80;
}
break;
case 0x2e:
@@ -609,6 +603,11 @@ nvr_reg_write(uint16_t reg, uint8_t val, void *priv)
}
/*FALLTHROUGH*/
case 0x32:
if ((reg == 0x32) && (local->cent == RTC_CENTURY_VIA) && local->wp_32)
break;
/* FALLTHROUGH */
default: /* non-RTC registers are just NVRAM */
if ((reg == 0x2c) && (local->flags & FLAG_LS_HACK))
nvr->new = 0;
@@ -686,9 +685,8 @@ nvr_read(uint16_t addr, void *priv)
cycles -= ISA_CYCLES(8);
if (local->bank[addr_id] == 0xff)
return 0xff;
if (addr & 1) switch(local->addr[addr_id]) {
ret = 0xff;
else if (addr & 1) switch(local->addr[addr_id]) {
case RTC_REGA:
ret = (nvr->regs[RTC_REGA] & 0x7f) | local->stat;
break;
@@ -700,8 +698,9 @@ nvr_read(uint16_t addr, void *priv)
break;
case RTC_REGD:
nvr->regs[RTC_REGD] |= REGD_VRT;
ret = nvr->regs[RTC_REGD];
/* Bits 6-0 of this register always read 0. Bit 7 is battery state,
we should always return it set, as that means the battery is OK. */
ret = REGD_VRT;
break;
case 0x2c:
@@ -886,6 +885,18 @@ nvr_wp_set(int set, int h, nvr_t *nvr)
}
void
nvr_via_wp_set(int set, int reg, nvr_t *nvr)
{
local_t *local = (local_t *) nvr->data;
if (reg == 0x0d)
local->wp_0d = set;
else
local->wp_32 = set;
}
void
nvr_bank_set(int base, uint8_t bank, nvr_t *nvr)
{
@@ -906,6 +917,17 @@ nvr_lock_set(int base, int size, int lock, nvr_t *nvr)
}
static void
nvr_at_reset(void *priv)
{
nvr_t *nvr = (nvr_t *) priv;
/* These bits are reset on reset. */
nvr->regs[RTC_REGB] &= ~(REGB_PIE | REGB_AIE | REGB_UIE | REGB_SQWE);
nvr->regs[RTC_REGC] &= ~(REGC_PF | REGC_AF | REGC_UF | REGC_IRQF);
}
static void *
nvr_at_init(const device_t *info)
{
@@ -990,6 +1012,10 @@ nvr_at_init(const device_t *info)
timer_add(&local->update_timer, timer_update, nvr, 0);
timer_add(&local->rtc_timer, timer_intr, nvr, 0);
/* On power on, if the oscillator is disabled, it's reenabled. */
if ((nvr->regs[RTC_REGA] & 0x70) == 0x00)
nvr->regs[RTC_REGA] = (nvr->regs[RTC_REGA] & 0x8f) | 0x20;
nvr_at_reset(nvr);
timer_load_count(nvr);
timer_set_delay_u64(&local->rtc_timer, RTCCONST);
@@ -1039,7 +1065,7 @@ const device_t at_nvr_old_device = {
"PC/AT NVRAM (No century)",
DEVICE_ISA | DEVICE_AT,
0,
nvr_at_init, nvr_at_close, NULL,
nvr_at_init, nvr_at_close, nvr_at_reset,
{ NULL }, nvr_at_speed_changed,
NULL
};
@@ -1048,7 +1074,7 @@ const device_t at_nvr_device = {
"PC/AT NVRAM",
DEVICE_ISA | DEVICE_AT,
1,
nvr_at_init, nvr_at_close, NULL,
nvr_at_init, nvr_at_close, nvr_at_reset,
{ NULL }, nvr_at_speed_changed,
NULL
};
@@ -1057,7 +1083,7 @@ const device_t ps_nvr_device = {
"PS/1 or PS/2 NVRAM",
DEVICE_PS2,
2,
nvr_at_init, nvr_at_close, NULL,
nvr_at_init, nvr_at_close, nvr_at_reset,
{ NULL }, nvr_at_speed_changed,
NULL
};
@@ -1066,7 +1092,7 @@ const device_t amstrad_nvr_device = {
"Amstrad NVRAM",
DEVICE_ISA | DEVICE_AT,
3,
nvr_at_init, nvr_at_close, NULL,
nvr_at_init, nvr_at_close, nvr_at_reset,
{ NULL }, nvr_at_speed_changed,
NULL
};
@@ -1075,7 +1101,7 @@ const device_t ibmat_nvr_device = {
"IBM AT NVRAM",
DEVICE_ISA | DEVICE_AT,
4,
nvr_at_init, nvr_at_close, NULL,
nvr_at_init, nvr_at_close, nvr_at_reset,
{ NULL }, nvr_at_speed_changed,
NULL
};
@@ -1084,7 +1110,7 @@ const device_t piix4_nvr_device = {
"Intel PIIX4 PC/AT NVRAM",
DEVICE_ISA | DEVICE_AT,
9,
nvr_at_init, nvr_at_close, NULL,
nvr_at_init, nvr_at_close, nvr_at_reset,
{ NULL }, nvr_at_speed_changed,
NULL
};
@@ -1093,7 +1119,7 @@ const device_t ls486e_nvr_device = {
"Lucky Star LS-486E PC/AT NVRAM",
DEVICE_ISA | DEVICE_AT,
13,
nvr_at_init, nvr_at_close, NULL,
nvr_at_init, nvr_at_close, nvr_at_reset,
{ NULL }, nvr_at_speed_changed,
NULL
};
@@ -1102,7 +1128,7 @@ const device_t ami_apollo_nvr_device = {
"AMI Apollo PC/AT NVRAM",
DEVICE_ISA | DEVICE_AT,
14,
nvr_at_init, nvr_at_close, NULL,
nvr_at_init, nvr_at_close, nvr_at_reset,
{ NULL }, nvr_at_speed_changed,
NULL
};
@@ -1111,7 +1137,7 @@ const device_t via_nvr_device = {
"VIA PC/AT NVRAM",
DEVICE_ISA | DEVICE_AT,
15,
nvr_at_init, nvr_at_close, NULL,
nvr_at_init, nvr_at_close, nvr_at_reset,
{ NULL }, nvr_at_speed_changed,
NULL
};

View File

@@ -378,6 +378,7 @@ pci_set_mirq(uint8_t mirq, int level)
if (level && (pci_irq_hold[irq_line] & (1ULL << irq_bit))) {
/* IRQ already held, do nothing. */
pci_log("pci_set_mirq(%02X): MIRQ is already holding the IRQ\n", mirq);
picintlevel(1 << irq_line);
return;
}
pci_log("pci_set_mirq(%02X): MIRQ not yet holding the IRQ\n", mirq);
@@ -392,6 +393,7 @@ pci_set_mirq(uint8_t mirq, int level)
picint(1 << irq_line);
} else if (level && pci_irq_hold[irq_line]) {
pci_log("pci_set_mirq(%02X): IRQ line already being held\n", mirq);
picintlevel(1 << irq_line);
}
/* If the IRQ is level-triggered, mark that this MIRQ is holding it. */
@@ -450,6 +452,7 @@ pci_set_irq(uint8_t card, uint8_t pci_int)
if (level && (pci_irq_hold[irq_line] & (1ULL << slot))) {
/* IRQ already held, do nothing. */
pci_log("pci_set_irq(%02X, %02X): Card is already holding the IRQ\n", card, pci_int);
picintlevel(1 << irq_line);
return;
}
pci_log("pci_set_irq(%02X, %02X): Card not yet holding the IRQ\n", card, pci_int);
@@ -464,6 +467,7 @@ pci_set_irq(uint8_t card, uint8_t pci_int)
picint(1 << irq_line);
} else if (level && pci_irq_hold[irq_line]) {
pci_log("pci_set_irq(%02X, %02X): IRQ line already being held\n", card, pci_int);
picintlevel(1 << irq_line);
}
/* If the IRQ is level-triggered, mark that this card is holding it. */

View File

@@ -27,6 +27,7 @@
#include "cpu.h"
#include <86box/device.h>
#include <86box/timer.h>
#include <86box/cassette.h>
#include <86box/dma.h>
#include <86box/io.h>
#include <86box/nmi.h>
@@ -734,6 +735,9 @@ pit_speaker_timer(int new_out, int old_out)
{
int l;
if (cassette != NULL)
pc_cas_set_out(cassette, new_out);
speaker_update();
l = pit->counters[2].l ? pit->counters[2].l : 0x10000;

View File

@@ -82,7 +82,7 @@ static void random_twist(uint32_t *val)
uint8_t random_generate(void)
{
uint16_t r = 0;
r = (rand() ^ ROTATE_LEFT(preconst, rand() % 32)) % 256;
r = (RDTSC() ^ ROTATE_LEFT(preconst, rand() % 32)) % 256;
random_twist(&preconst);
return (r & 0xff);
}

View File

@@ -26,6 +26,7 @@
#define HAVE_STDARG_H
#include <86box/86box.h>
#include <86box/device.h>
#include <86box/machine.h>
#include <86box/hdc.h>
#include <86box/hdd.h>
#include <86box/plat.h>
@@ -45,8 +46,9 @@
#endif
int scsi_card_current = 0;
int scsi_card_last = 0;
int scsi_card_current[SCSI_BUS_MAX] = { 0, 0 };
static uint8_t next_scsi_bus = 0;
typedef const struct {
@@ -88,6 +90,27 @@ static SCSI_CARD scsi_cards[] = {
};
void
scsi_reset(void)
{
next_scsi_bus = 0;
}
uint8_t
scsi_get_bus(void)
{
uint8_t ret = next_scsi_bus;
if (next_scsi_bus >= SCSI_BUS_MAX)
return 0xff;
next_scsi_bus++;
return ret;
}
int
scsi_card_available(int card)
{
@@ -139,10 +162,21 @@ scsi_card_get_from_internal_name(char *s)
void
scsi_card_init(void)
{
if (!scsi_cards[scsi_card_current].device)
return;
int i = 0, max = SCSI_BUS_MAX;
device_add(scsi_cards[scsi_card_current].device);
/* On-board SCSI controllers get the first bus, so if one is present,
increase our instance number here. */
if (machines[machine].flags & MACHINE_SCSI)
max--;
scsi_card_last = scsi_card_current;
/* Do not initialize any controllers if we have do not have any SCSI
bus left. */
if (max > 0) {
for (i = 0; i < max; i++) {
if (!scsi_cards[scsi_card_current[i]].device)
continue;
device_add_inst(scsi_cards[scsi_card_current[i]].device, i + 1);
}
}
}

View File

@@ -40,6 +40,7 @@
#include <86box/fdc.h>
#include <86box/isapnp.h>
#include <86box/scsi.h>
#include <86box/scsi_device.h>
#include <86box/scsi_aha154x.h>
#include <86box/scsi_x54x.h>
@@ -964,6 +965,7 @@ aha_init(const device_t *info)
/* Call common initializer. */
dev = x54x_init(info);
dev->bus = scsi_get_bus();
/*
* Set up the (initial) I/O address, IRQ and DMA info.
@@ -976,7 +978,7 @@ aha_init(const device_t *info)
dev->Irq = device_get_config_int("irq");
dev->DmaChannel = device_get_config_int("dma");
dev->rom_addr = device_get_config_hex20("bios_addr");
if (!(dev->bus & DEVICE_MCA))
if (!(dev->card_bus & DEVICE_MCA))
dev->fdc_address = device_get_config_hex16("fdc_addr");
else
dev->fdc_address = 0;
@@ -1121,7 +1123,7 @@ aha_init(const device_t *info)
/* Initialize the device. */
x54x_device_reset(dev);
if (!(dev->bus & DEVICE_MCA) && !(dev->flags & X54X_ISAPNP)) {
if (!(dev->card_bus & DEVICE_MCA) && !(dev->flags & X54X_ISAPNP)) {
/* Register our address space. */
x54x_io_set(dev, dev->Base, 4);

View File

@@ -559,13 +559,13 @@ buslogic_param_len(void *p)
static void
BuslogicSCSIBIOSDMATransfer(ESCMD *ESCSICmd, uint8_t TargetID, int dir, int transfer_size)
BuslogicSCSIBIOSDMATransfer(x54x_t *dev, ESCMD *ESCSICmd, uint8_t TargetID, int dir, int transfer_size)
{
uint32_t DataPointer = ESCSICmd->DataPointer;
int DataLength = ESCSICmd->DataLength;
uint32_t Address;
uint32_t TransferLength;
scsi_device_t *dev = &scsi_devices[TargetID];
scsi_device_t *sd = &scsi_devices[dev->bus][TargetID];
if (ESCSICmd->DataDirection == 0x03) {
/* Non-data command. */
@@ -577,16 +577,16 @@ BuslogicSCSIBIOSDMATransfer(ESCMD *ESCSICmd, uint8_t TargetID, int dir, int tran
/* If the control byte is 0x00, it means that the transfer direction is set up by the SCSI command without
checking its length, so do this procedure for both read/write commands. */
if ((DataLength > 0) && (dev->buffer_length > 0)) {
if ((DataLength > 0) && (sd->buffer_length > 0)) {
Address = DataPointer;
TransferLength = MIN(DataLength, dev->buffer_length);
TransferLength = MIN(DataLength, sd->buffer_length);
if (dir && ((ESCSICmd->DataDirection == CCB_DATA_XFER_OUT) || (ESCSICmd->DataDirection == 0x00))) {
buslogic_log("BusLogic BIOS DMA: Reading %i bytes from %08X\n", TransferLength, Address);
dma_bm_read(Address, (uint8_t *)dev->sc->temp_buffer, TransferLength, transfer_size);
dma_bm_read(Address, (uint8_t *)sd->sc->temp_buffer, TransferLength, transfer_size);
} else if (!dir && ((ESCSICmd->DataDirection == CCB_DATA_XFER_IN) || (ESCSICmd->DataDirection == 0x00))) {
buslogic_log("BusLogic BIOS DMA: Writing %i bytes at %08X\n", TransferLength, Address);
dma_bm_write(Address, (uint8_t *)dev->sc->temp_buffer, TransferLength, transfer_size);
dma_bm_write(Address, (uint8_t *)sd->sc->temp_buffer, TransferLength, transfer_size);
}
}
}
@@ -603,7 +603,7 @@ BuslogicSCSIBIOSRequestSetup(x54x_t *dev, uint8_t *CmdBuf, uint8_t *DataInBuf, u
uint8_t target_id = 0;
#endif
int phase;
scsi_device_t *sd = &scsi_devices[ESCSICmd->TargetId];
scsi_device_t *sd = &scsi_devices[dev->bus][ESCSICmd->TargetId];
DataInBuf[0] = DataInBuf[1] = 0;
@@ -654,7 +654,7 @@ BuslogicSCSIBIOSRequestSetup(x54x_t *dev, uint8_t *CmdBuf, uint8_t *DataInBuf, u
phase = sd->phase;
if (phase != SCSI_PHASE_STATUS) {
BuslogicSCSIBIOSDMATransfer(ESCSICmd, ESCSICmd->TargetId, (phase == SCSI_PHASE_DATA_OUT), dev->transfer_size);
BuslogicSCSIBIOSDMATransfer(dev, ESCSICmd, ESCSICmd->TargetId, (phase == SCSI_PHASE_DATA_OUT), dev->transfer_size);
scsi_device_command_phase1(sd);
}
@@ -664,7 +664,7 @@ BuslogicSCSIBIOSRequestSetup(x54x_t *dev, uint8_t *CmdBuf, uint8_t *DataInBuf, u
if (sd->status == SCSI_STATUS_OK) {
DataInBuf[2] = CCB_COMPLETE;
DataInBuf[3] = SCSI_STATUS_OK;
} else if (scsi_devices[ESCSICmd->TargetId].status == SCSI_STATUS_CHECK_CONDITION) {
} else if (scsi_devices[dev->bus][ESCSICmd->TargetId].status == SCSI_STATUS_CHECK_CONDITION) {
DataInBuf[2] = CCB_COMPLETE;
DataInBuf[3] = SCSI_STATUS_CHECK_CONDITION;
}
@@ -704,14 +704,14 @@ buslogic_cmds(void *p)
memset(dev->DataBuf, 0, 8);
for (i = 8; i < 15; i++) {
dev->DataBuf[i - 8] = 0;
if (scsi_device_present(&scsi_devices[i]) && (i != buslogic_get_host_id(dev)))
if (scsi_device_present(&scsi_devices[dev->bus][i]) && (i != buslogic_get_host_id(dev)))
dev->DataBuf[i - 8] |= 1;
}
dev->DataReplyLeft = 8;
break;
case 0x24:
for (i = 0; i < 15; i++) {
if (scsi_device_present(&scsi_devices[i]) && (i != buslogic_get_host_id(dev)))
if (scsi_device_present(&scsi_devices[dev->bus][i]) && (i != buslogic_get_host_id(dev)))
TargetsPresentMask |= (1 << i);
}
dev->DataBuf[0] = TargetsPresentMask & 0xFF;
@@ -1532,13 +1532,14 @@ buslogic_init(const device_t *info)
/* Call common initializer. */
dev = x54x_init(info);
dev->bus = scsi_get_bus();
dev->ven_data = malloc(sizeof(buslogic_data_t));
memset(dev->ven_data, 0x00, sizeof(buslogic_data_t));
bl = (buslogic_data_t *) dev->ven_data;
dev->bus = info->flags;
dev->card_bus = info->flags;
if (!(info->flags & DEVICE_MCA) && !(info->flags & DEVICE_PCI)) {
dev->Base = device_get_config_hex16("base");
dev->Irq = device_get_config_int("irq");
@@ -1668,7 +1669,7 @@ buslogic_init(const device_t *info)
break;
}
if ((dev->Base != 0) && !(dev->bus & DEVICE_MCA) && !(dev->bus & DEVICE_PCI)) {
if ((dev->Base != 0) && !(dev->card_bus & DEVICE_MCA) && !(dev->card_bus & DEVICE_PCI)) {
x54x_io_set(dev, dev->Base, 4);
}

View File

@@ -798,12 +798,13 @@ scsi_cdrom_sense_clear(scsi_cdrom_t *dev, int command)
static void
scsi_cdrom_set_phase(scsi_cdrom_t *dev, uint8_t phase)
{
uint8_t scsi_id = dev->drv->scsi_device_id;
uint8_t scsi_bus = (dev->drv->scsi_device_id >> 4) & 0x0f;
uint8_t scsi_id = dev->drv->scsi_device_id & 0x0f;
if (dev->drv->bus_type != CDROM_BUS_SCSI)
return;
scsi_devices[scsi_id].phase = phase;
scsi_devices[scsi_bus][scsi_id].phase = phase;
}
@@ -1417,9 +1418,11 @@ scsi_cdrom_command(scsi_common_t *sc, uint8_t *cdb)
int32_t blen = 0, *BufLen;
uint8_t *b;
uint32_t profiles[2] = { MMC_PROFILE_CD_ROM, MMC_PROFILE_DVD_ROM };
uint8_t scsi_bus = (dev->drv->scsi_device_id >> 4) & 0x0f;
uint8_t scsi_id = dev->drv->scsi_device_id & 0x0f;
if (dev->drv->bus_type == CDROM_BUS_SCSI) {
BufLen = &scsi_devices[dev->drv->scsi_device_id].buffer_length;
BufLen = &scsi_devices[scsi_bus][scsi_id].buffer_length;
dev->status &= ~ERR_STAT;
} else {
BufLen = &blen;
@@ -2687,10 +2690,18 @@ scsi_cdrom_drive_reset(int c)
scsi_cdrom_t *dev;
scsi_device_t *sd;
ide_t *id;
uint8_t scsi_bus = (drv->scsi_device_id >> 4) & 0x0f;
uint8_t scsi_id = drv->scsi_device_id & 0x0f;
/* Make sure to ignore any SCSI CD-ROM drive that has an out of range ID. */
if ((drv->bus_type == CDROM_BUS_SCSI) && (drv->scsi_device_id >= SCSI_ID_MAX))
return;
if (drv->bus_type == CDROM_BUS_SCSI) {
/* Make sure to ignore any SCSI CD-ROM drive that has an out of range SCSI bus. */
if (scsi_bus >= SCSI_BUS_MAX)
return;
/* Make sure to ignore any SCSI CD-ROM drive that has an out of range ID. */
if (scsi_id >= SCSI_ID_MAX)
return;
}
/* Make sure to ignore any ATAPI CD-ROM drive that has an out of range IDE channel. */
if ((drv->bus_type == CDROM_BUS_ATAPI) && (drv->ide_channel > 7))
@@ -2717,7 +2728,7 @@ scsi_cdrom_drive_reset(int c)
if (drv->bus_type == CDROM_BUS_SCSI) {
/* SCSI CD-ROM, attach to the SCSI bus. */
sd = &scsi_devices[drv->scsi_device_id];
sd = &scsi_devices[scsi_bus][scsi_id];
sd->sc = (scsi_common_t *) dev;
sd->command = scsi_cdrom_command;

View File

@@ -27,7 +27,7 @@
#include <86box/scsi_device.h>
scsi_device_t scsi_devices[SCSI_ID_MAX];
scsi_device_t scsi_devices[SCSI_BUS_MAX][SCSI_ID_MAX];
uint8_t scsi_null_device_sense[18] = { 0x70,0,SENSE_ILLEGAL_REQUEST,0,0,0,0,0,0,0,0,0,ASC_INV_LUN,0,0,0,0,0 };
@@ -176,13 +176,15 @@ scsi_device_identify(scsi_device_t *dev, uint8_t lun)
void
scsi_device_close_all(void)
{
int i;
int i, j;
scsi_device_t *dev;
for (i = 0; i < SCSI_ID_MAX; i++) {
dev = &(scsi_devices[i]);
if (dev->command_stop && dev->sc)
dev->command_stop(dev->sc);
for (i = 0; i < SCSI_BUS_MAX; i++) {
for (j = 0; j < SCSI_ID_MAX; j++) {
dev = &(scsi_devices[i][j]);
if (dev->command_stop && dev->sc)
dev->command_stop(dev->sc);
}
}
}
@@ -190,13 +192,15 @@ scsi_device_close_all(void)
void
scsi_device_init(void)
{
int i;
int i, j;
scsi_device_t *dev;
for (i = 0; i < SCSI_ID_MAX; i++) {
dev = &(scsi_devices[i]);
for (i = 0; i < SCSI_BUS_MAX; i++) {
for (j = 0; j < SCSI_ID_MAX; j++) {
dev = &(scsi_devices[i][j]);
memset(dev, 0, sizeof(scsi_device_t));
dev->type = SCSI_NONE;
memset(dev, 0, sizeof(scsi_device_t));
dev->type = SCSI_NONE;
}
}
}

View File

@@ -347,12 +347,13 @@ scsi_disk_sense_clear(scsi_disk_t *dev, int command)
static void
scsi_disk_set_phase(scsi_disk_t *dev, uint8_t phase)
{
uint8_t scsi_id = dev->drv->scsi_id;
uint8_t scsi_bus = (dev->drv->scsi_id >> 4) & 0x0f;
uint8_t scsi_id = dev->drv->scsi_id & 0x0f;
if (dev->drv->bus != HDD_BUS_SCSI)
return;
scsi_devices[scsi_id].phase = phase;
scsi_devices[scsi_bus][scsi_id].phase = phase;
}
@@ -572,8 +573,10 @@ scsi_disk_command(scsi_common_t *sc, uint8_t *cdb)
char device_identify[9] = { '8', '6', 'B', '_', 'H', 'D', '0', '0', 0 };
char device_identify_ex[15] = { '8', '6', 'B', '_', 'H', 'D', '0', '0', ' ', 'v', '1', '.', '0', '0', 0 };
int block_desc = 0;
uint8_t scsi_bus = (dev->drv->scsi_id >> 4) & 0x0f;
uint8_t scsi_id = dev->drv->scsi_id & 0x0f;
BufLen = &scsi_devices[dev->drv->scsi_id].buffer_length;
BufLen = &scsi_devices[scsi_bus][scsi_id].buffer_length;
last_sector = hdd_image_get_last_sector(dev->id);
@@ -1073,8 +1076,10 @@ static uint8_t
scsi_disk_phase_data_out(scsi_common_t *sc)
{
scsi_disk_t *dev = (scsi_disk_t *) sc;
uint8_t scsi_bus = (dev->drv->scsi_id >> 4) & 0x0f;
uint8_t scsi_id = dev->drv->scsi_id & 0x0f;
int i;
int32_t *BufLen = &scsi_devices[dev->drv->scsi_id].buffer_length;
int32_t *BufLen = &scsi_devices[scsi_bus][scsi_id].buffer_length;
uint32_t last_sector = hdd_image_get_last_sector(dev->id);
uint32_t c, h, s, last_to_write = 0;
uint16_t block_desc_len, pos;
@@ -1215,13 +1220,21 @@ scsi_disk_hard_reset(void)
int c;
scsi_disk_t *dev;
scsi_device_t *sd;
uint8_t scsi_bus, scsi_id;
for (c = 0; c < HDD_NUM; c++) {
if (hdd[c].bus == HDD_BUS_SCSI) {
scsi_disk_log("SCSI disk hard_reset drive=%d\n", c);
scsi_bus = (hdd[c].scsi_id >> 4) & 0x0f;
scsi_id = hdd[c].scsi_id & 0x0f;
/* Make sure to ignore any SCSI disk that has an out of range SCSI bus. */
if (scsi_bus >= SCSI_BUS_MAX)
continue;
/* Make sure to ignore any SCSI disk that has an out of range ID. */
if (hdd[c].scsi_id >= SCSI_ID_MAX)
if (scsi_id >= SCSI_ID_MAX)
continue;
/* Make sure to ignore any SCSI disk whose image file name is empty. */
@@ -1240,7 +1253,7 @@ scsi_disk_hard_reset(void)
dev = (scsi_disk_t *) hdd[c].priv;
/* SCSI disk, attach to the SCSI bus. */
sd = &scsi_devices[hdd[c].scsi_id];
sd = &scsi_devices[scsi_bus][scsi_id];
sd->sc = (scsi_common_t *) dev;
sd->command = scsi_disk_command;
@@ -1268,10 +1281,14 @@ scsi_disk_close(void)
{
scsi_disk_t *dev;
int c;
uint8_t scsi_bus, scsi_id;
for (c = 0; c < HDD_NUM; c++) {
if (hdd[c].bus == HDD_BUS_SCSI) {
memset(&scsi_devices[hdd[c].scsi_id], 0x00, sizeof(scsi_device_t));
scsi_bus = (hdd[c].scsi_id >> 4) & 0x0f;
scsi_id = hdd[c].scsi_id & 0x0f;
memset(&scsi_devices[scsi_bus][scsi_id], 0x00, sizeof(scsi_device_t));
hdd_image_close(c);

View File

@@ -124,7 +124,7 @@ typedef struct {
int8_t bios_ver;
uint8_t block_count, block_count_num;
uint8_t status_ctrl;
uint8_t pad[2];
uint8_t bus, pad;
rom_t bios_rom;
mem_mapping_t mapping;
@@ -236,7 +236,7 @@ ncr_reset(ncr5380_t *ncr_dev, ncr_t *ncr)
timer_stop(&ncr_dev->timer);
for (int i = 0; i < 8; i++)
scsi_device_reset(&scsi_devices[i]);
scsi_device_reset(&scsi_devices[ncr_dev->bus][i]);
ncr_irq(ncr_dev, ncr, 0);
}
@@ -318,7 +318,7 @@ ncr_bus_read(ncr5380_t *ncr_dev)
if (ncr->wait_data) {
ncr->wait_data--;
if (!ncr->wait_data) {
dev = &scsi_devices[ncr->target_id];
dev = &scsi_devices[ncr_dev->bus][ncr->target_id];
SET_BUS_STATE(ncr, ncr->new_phase);
phase = (ncr->cur_bus & SCSI_PHASE_MESSAGE_IN);
@@ -360,7 +360,7 @@ ncr_bus_update(void *priv, int bus)
{
ncr5380_t *ncr_dev = (ncr5380_t *)priv;
ncr_t *ncr = &ncr_dev->ncr;
scsi_device_t *dev = &scsi_devices[ncr->target_id];
scsi_device_t *dev = &scsi_devices[ncr_dev->bus][ncr->target_id];
double p;
uint8_t sel_data;
int msglen;
@@ -383,7 +383,7 @@ ncr_bus_update(void *priv, int bus)
ncr_log("Select - target ID = %i\n", ncr->target_id);
/*Once the device has been found and selected, mark it as busy*/
if ((ncr->target_id != (uint8_t)-1) && scsi_device_present(&scsi_devices[ncr->target_id])) {
if ((ncr->target_id != (uint8_t)-1) && scsi_device_present(&scsi_devices[ncr_dev->bus][ncr->target_id])) {
ncr->cur_bus |= BUS_BSY;
ncr->state = STATE_SELECT;
} else {
@@ -395,7 +395,7 @@ ncr_bus_update(void *priv, int bus)
case STATE_SELECT:
if (!(bus & BUS_SEL)) {
if (!(bus & BUS_ATN)) {
if ((ncr->target_id != (uint8_t)-1) && scsi_device_present(&scsi_devices[ncr->target_id])) {
if ((ncr->target_id != (uint8_t)-1) && scsi_device_present(&scsi_devices[ncr_dev->bus][ncr->target_id])) {
ncr_log("Device found at ID %i, Current Bus BSY=%02x\n", ncr->target_id, ncr->cur_bus);
ncr->state = STATE_COMMAND;
ncr->cur_bus = BUS_BSY | BUS_REQ;
@@ -434,7 +434,7 @@ ncr_bus_update(void *priv, int bus)
/*Reset data position to default*/
ncr->data_pos = 0;
dev = &scsi_devices[ncr->target_id];
dev = &scsi_devices[ncr_dev->bus][ncr->target_id];
ncr_log("SCSI Command 0x%02X for ID %d, status code=%02x\n", ncr->command[0], ncr->target_id, dev->status);
dev->buffer_length = -1;
@@ -462,7 +462,7 @@ ncr_bus_update(void *priv, int bus)
}
break;
case STATE_DATAIN:
dev = &scsi_devices[ncr->target_id];
dev = &scsi_devices[ncr_dev->bus][ncr->target_id];
if ((bus & BUS_ACK) && !(ncr->bus_in & BUS_ACK)) {
if (ncr->data_pos >= dev->buffer_length) {
ncr->cur_bus &= ~BUS_REQ;
@@ -487,7 +487,7 @@ ncr_bus_update(void *priv, int bus)
}
break;
case STATE_DATAOUT:
dev = &scsi_devices[ncr->target_id];
dev = &scsi_devices[ncr_dev->bus][ncr->target_id];
if ((bus & BUS_ACK) && !(ncr->bus_in & BUS_ACK)) {
dev->sc->temp_buffer[ncr->data_pos++] = BUS_GETDATA(bus);
@@ -514,7 +514,7 @@ ncr_bus_update(void *priv, int bus)
case STATE_STATUS:
if ((bus & BUS_ACK) && !(ncr->bus_in & BUS_ACK)) {
/*All transfers done, wait until next transfer*/
scsi_device_identify(&scsi_devices[ncr->target_id], SCSI_LUN_USE_CDB);
scsi_device_identify(&scsi_devices[ncr_dev->bus][ncr->target_id], SCSI_LUN_USE_CDB);
ncr->cur_bus &= ~BUS_REQ;
ncr->new_phase = SCSI_PHASE_MESSAGE_IN;
ncr->wait_data = 4;
@@ -542,9 +542,9 @@ ncr_bus_update(void *priv, int bus)
}
break;
case STATE_MESSAGE_ID:
if ((ncr->target_id != (uint8_t)-1) && scsi_device_present(&scsi_devices[ncr->target_id])) {
if ((ncr->target_id != (uint8_t)-1) && scsi_device_present(&scsi_devices[ncr_dev->bus][ncr->target_id])) {
ncr_log("Device found at ID %i on MSGOUT, Current Bus BSY=%02x\n", ncr->target_id, ncr->cur_bus);
scsi_device_identify(&scsi_devices[ncr->target_id], ncr->msglun);
scsi_device_identify(&scsi_devices[ncr_dev->bus][ncr->target_id], ncr->msglun);
ncr->state = STATE_COMMAND;
ncr->cur_bus = BUS_BSY | BUS_REQ;
ncr_log("CurBus BSY|REQ=%02x\n", ncr->cur_bus);
@@ -1091,7 +1091,7 @@ ncr_callback(void *priv)
{
ncr5380_t *ncr_dev = (ncr5380_t *)priv;
ncr_t *ncr = &ncr_dev->ncr;
scsi_device_t *dev = &scsi_devices[ncr->target_id];
scsi_device_t *dev = &scsi_devices[ncr_dev->bus][ncr->target_id];
ncr_log("DMA mode=%d, status ctrl = %02x\n", ncr->dma_mode, ncr_dev->status_ctrl);
@@ -1166,6 +1166,8 @@ ncr_init(const device_t *info)
ncr_dev->name = info->name;
ncr_dev->type = info->local;
ncr_dev->bus = scsi_get_bus();
switch(ncr_dev->type) {
case 0: /* Longshine LCS6821N */
ncr_dev->rom_addr = device_get_config_hex20("bios_addr");

View File

@@ -308,6 +308,8 @@ typedef struct {
uint32_t bios_mask;
uint8_t bus;
pc_timer_t timer;
#ifdef USE_WDTR
@@ -440,7 +442,7 @@ ncr53c8xx_soft_reset(ncr53c8xx_t *dev)
#ifdef USE_WDTR
dev->tr_set[i] = 0;
#endif
scsi_device_reset(&scsi_devices[i]);
scsi_device_reset(&scsi_devices[dev->bus][i]);
}
} else {
/* This is *NOT* a wide SCSI controller, so do not touch
@@ -449,7 +451,7 @@ ncr53c8xx_soft_reset(ncr53c8xx_t *dev)
#ifdef USE_WDTR
dev->tr_set[i] = 0;
#endif
scsi_device_reset(&scsi_devices[i]);
scsi_device_reset(&scsi_devices[dev->bus][i]);
}
}
}
@@ -613,7 +615,7 @@ ncr53c8xx_disconnect(ncr53c8xx_t *dev)
{
scsi_device_t *sd;
sd = &scsi_devices[dev->sdid];
sd = &scsi_devices[dev->bus][dev->sdid];
dev->scntl1 &= ~NCR_SCNTL1_CON;
dev->sstat1 &= ~PHASE_MASK;
@@ -659,7 +661,7 @@ ncr53c8xx_do_dma(ncr53c8xx_t *dev, int out, uint8_t id)
uint32_t addr, tdbc;
int count;
scsi_device_t *sd = &scsi_devices[id];
scsi_device_t *sd = &scsi_devices[dev->bus][id];
if ((!scsi_device_present(sd))) {
ncr53c8xx_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: Device not present when attempting to do DMA\n", id, dev->current_lun, dev->last_command);
@@ -697,7 +699,7 @@ ncr53c8xx_do_dma(ncr53c8xx_t *dev, int out, uint8_t id)
dev->buffer_pos += count;
if (dev->temp_buf_len <= 0) {
scsi_device_command_phase1(&scsi_devices[id]);
scsi_device_command_phase1(&scsi_devices[dev->bus][id]);
#ifdef ENABLE_NCR53C8XX_LOG
if (out)
ncr53c8xx_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: SCSI Command Phase 1 on PHASE_DO\n", id, dev->current_lun, dev->last_command);
@@ -750,7 +752,7 @@ ncr53c8xx_do_command(ncr53c8xx_t *dev, uint8_t id)
dev->sfbr = buf[0];
dev->command_complete = 0;
sd = &scsi_devices[id];
sd = &scsi_devices[dev->bus][id];
if (!scsi_device_present(sd) || (dev->current_lun > 0)) {
ncr53c8xx_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: Bad Selection\n", id, dev->current_lun, buf[0]);
ncr53c8xx_bad_selection(dev, id);
@@ -769,7 +771,7 @@ ncr53c8xx_do_command(ncr53c8xx_t *dev, uint8_t id)
if ((buf[1] & 0xe0) != (dev->current_lun << 5))
buf[1] = (buf[1] & 0x1f) | (dev->current_lun << 5);
scsi_device_command_phase0(&scsi_devices[dev->current->tag], buf);
scsi_device_command_phase0(&scsi_devices[dev->bus][dev->current->tag], buf);
dev->hba_private = (void *)dev->current;
dev->waiting = 0;
@@ -785,12 +787,12 @@ ncr53c8xx_do_command(ncr53c8xx_t *dev, uint8_t id)
if ((sd->phase == SCSI_PHASE_DATA_IN) && (sd->buffer_length > 0)) {
ncr53c8xx_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: PHASE_DI\n", id, dev->current_lun, buf[0]);
ncr53c8xx_set_phase(dev, PHASE_DI);
ncr53c8xx_timer_on(dev, sd, scsi_device_get_callback(&scsi_devices[dev->current->tag]));
ncr53c8xx_timer_on(dev, sd, scsi_device_get_callback(&scsi_devices[dev->bus][dev->current->tag]));
return 1;
} else if ((sd->phase == SCSI_PHASE_DATA_OUT) && (sd->buffer_length > 0)) {
ncr53c8xx_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: PHASE_DO\n", id, buf[0]);
ncr53c8xx_set_phase(dev, PHASE_DO);
ncr53c8xx_timer_on(dev, sd, scsi_device_get_callback(&scsi_devices[dev->current->tag]));
ncr53c8xx_timer_on(dev, sd, scsi_device_get_callback(&scsi_devices[dev->bus][dev->current->tag]));
return 1;
} else {
ncr53c8xx_command_complete(dev, sd->status);
@@ -913,7 +915,7 @@ ncr53c8xx_do_msgout(ncr53c8xx_t *dev, uint8_t id)
#endif
scsi_device_t *sd;
sd = &scsi_devices[id];
sd = &scsi_devices[dev->bus][id];
#ifdef ENABLE_NCR53C8XX_LOG
current_tag = id;
@@ -1169,7 +1171,7 @@ again:
}
dev->sstat0 |= NCR_SSTAT0_WOA;
dev->scntl1 &= ~NCR_SCNTL1_IARB;
if (!scsi_device_present(&scsi_devices[id])) {
if (!scsi_device_present(&scsi_devices[dev->bus][id])) {
ncr53c8xx_bad_selection(dev, id);
break;
}
@@ -2513,6 +2515,8 @@ ncr53c8xx_init(const device_t *info)
dev = malloc(sizeof(ncr53c8xx_t));
memset(dev, 0x00, sizeof(ncr53c8xx_t));
dev->bus = scsi_get_bus();
dev->chip_rev = 0;
dev->chip = info->local & 0xff;

View File

@@ -168,6 +168,7 @@ typedef struct {
int deferred_complete;
uint32_t dma;
uint8_t ti_buf[TI_BUFSZ];
uint8_t bus;
uint8_t id, lun;
uint8_t cmdbuf[ESP_CMDBUF_SZ];
uint32_t cmdlen;
@@ -289,7 +290,7 @@ esp_get_cmd(esp_t *dev, uint8_t *buf, uint8_t buflen)
dev->ti_rptr = 0;
dev->ti_wptr = 0;
if (scsi_device_present(&scsi_devices[dev->id]) && (dev->lun > 0)) {
if (scsi_device_present(&scsi_devices[dev->bus][dev->id]) && (dev->lun > 0)) {
/* We only support LUN 0 */
dev->rregs[ESP_RSTAT] = 0;
dev->rregs[ESP_RINTR] = INTR_DC;
@@ -298,7 +299,7 @@ esp_get_cmd(esp_t *dev, uint8_t *buf, uint8_t buflen)
return 0;
}
scsi_device_identify(&scsi_devices[dev->id], dev->lun);
scsi_device_identify(&scsi_devices[dev->bus][dev->id], dev->lun);
return dmalen;
}
@@ -308,7 +309,7 @@ esp_do_busid_cmd(esp_t *dev, uint8_t *buf, uint8_t busid)
{
scsi_device_t *sd;
sd = &scsi_devices[busid];
sd = &scsi_devices[dev->bus][busid];
sd->buffer_length = -1;
@@ -388,7 +389,7 @@ esp_hard_reset(esp_t *dev)
timer_stop(&dev->timer);
for (int i = 0; i < 8; i++)
scsi_device_reset(&scsi_devices[i]);
scsi_device_reset(&scsi_devices[dev->bus][i]);
}
static void
@@ -536,7 +537,7 @@ static void
handle_ti(void *priv)
{
esp_t *dev = (esp_t *)priv;
scsi_device_t *sd = &scsi_devices[dev->id];
scsi_device_t *sd = &scsi_devices[dev->bus][dev->id];
uint32_t dmalen;
if (dev->dma) {
@@ -1430,6 +1431,8 @@ dc390_init(const device_t *info)
dev = malloc(sizeof(esp_t));
memset(dev, 0x00, sizeof(esp_t));
dev->bus = scsi_get_bus();
dev->PCIBase = 0;
dev->MMIOBase = 0;

View File

@@ -143,7 +143,7 @@ typedef struct {
int lun_id;
} dev_id[SCSI_ID_MAX];
uint8_t last_status;
uint8_t last_status, bus;
uint8_t cdb[12];
int cdb_len;
int cdb_id;
@@ -488,7 +488,7 @@ spock_process_imm_cmd(spock_t *scsi)
spock_log("Reset Command\n");
if ((scsi->attention & 0x0f) == 0x0f) { /*Adapter reset*/
for (i = 0; i < 8; i++)
scsi_device_reset(&scsi_devices[i]);
scsi_device_reset(&scsi_devices[scsi->bus][i]);
spock_log("Adapter Reset\n");
if (!scsi->adapter_reset && scsi->bios_ver) /*The early 1990 bios must have its boot drive
@@ -798,7 +798,7 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb)
break;
case 2: /* Wait */
if (scsi->scsi_state == SCSI_STATE_IDLE && scsi_device_present(&scsi_devices[scsi->cdb_id])) {
if (scsi->scsi_state == SCSI_STATE_IDLE && scsi_device_present(&scsi_devices[scsi->bus][scsi->cdb_id])) {
if (scsi->last_status == SCSI_STATUS_OK) {
scsi->scb_state = 3;
spock_log("Status is Good on device ID %d, timer = %i\n", scsi->cdb_id, scsi->cmd_timer);
@@ -816,7 +816,7 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb)
dma_bm_write(scb->term_status_block_addr + 0xb*2, (uint8_t *)&term_stat_block_addrb, 2, 2);
dma_bm_write(scb->term_status_block_addr + 0xc*2, (uint8_t *)&term_stat_block_addrc, 2, 2);
}
} else if (scsi->scsi_state == SCSI_STATE_IDLE && !scsi_device_present(&scsi_devices[scsi->cdb_id])) {
} else if (scsi->scsi_state == SCSI_STATE_IDLE && !scsi_device_present(&scsi_devices[scsi->bus][scsi->cdb_id])) {
uint16_t term_stat_block_addr7 = (0xc << 8) | 2;
uint16_t term_stat_block_addr8 = 0x10;
spock_set_irq(scsi, scsi->scb_id, IRQ_TYPE_COMMAND_FAIL);
@@ -854,7 +854,7 @@ spock_process_scsi(spock_t *scsi, scb_t *scb)
case SCSI_STATE_SELECT:
spock_log("Selecting ID %d\n", scsi->cdb_id);
if ((scsi->cdb_id != (uint8_t)-1) && scsi_device_present(&scsi_devices[scsi->cdb_id])) {
if ((scsi->cdb_id != (uint8_t)-1) && scsi_device_present(&scsi_devices[scsi->bus][scsi->cdb_id])) {
scsi->scsi_state = SCSI_STATE_SEND_COMMAND;
spock_log("Device selected at ID %i\n", scsi->cdb_id);
} else {
@@ -869,7 +869,7 @@ spock_process_scsi(spock_t *scsi, scb_t *scb)
break;
case SCSI_STATE_SEND_COMMAND:
sd = &scsi_devices[scsi->cdb_id];
sd = &scsi_devices[scsi->bus][scsi->cdb_id];
memset(scsi->temp_cdb, 0x00, 12);
if (scsi->cdb_len < 12) {
@@ -1086,7 +1086,7 @@ spock_mca_reset(void *priv)
/* Reset all devices on controller reset. */
for (i = 0; i < 8; i++)
scsi_device_reset(&scsi_devices[i]);
scsi_device_reset(&scsi_devices[scsi->bus][i]);
scsi->adapter_reset = 0;
}
@@ -1097,7 +1097,9 @@ spock_init(const device_t *info)
int c;
spock_t *scsi = malloc(sizeof(spock_t));
memset(scsi, 0x00, sizeof(spock_t));
scsi->bus = scsi_get_bus();
scsi->irq = 14;
scsi->bios_ver = device_get_config_int("bios_ver");

View File

@@ -85,7 +85,7 @@ x54x_irq(x54x_t *dev, int set)
else
irq = dev->Irq;
if (dev->bus & DEVICE_PCI) {
if (dev->card_bus & DEVICE_PCI) {
x54x_log("PCI IRQ: %02X, PCI_INTA\n", dev->pci_slot);
if (set)
pci_set_irq(dev->pci_slot, PCI_INTA);
@@ -155,9 +155,9 @@ clear_irq(x54x_t *dev)
static void
target_check(uint8_t id)
target_check(x54x_t *dev, uint8_t id)
{
if (! scsi_device_valid(&scsi_devices[id]))
if (! scsi_device_valid(&scsi_devices[dev->bus][id]))
fatal("BIOS INT13 device on ID %02i has disappeared\n", id);
}
@@ -432,7 +432,7 @@ x54x_bios_command(x54x_t *x54x, uint8_t max_id, BIOSCMD *cmd, int8_t islba)
if (!ret) {
/* Get pointer to selected device. */
dev = &scsi_devices[cmd->id];
dev = &scsi_devices[x54x->bus][cmd->id];
dev->buffer_length = 0;
if (! scsi_device_present(dev)) {
@@ -459,7 +459,7 @@ x54x_bios_command(x54x_t *x54x, uint8_t max_id, BIOSCMD *cmd, int8_t islba)
break;
case 0x01: /* Read Status of Last Operation */
target_check(cmd->id);
target_check(x54x, cmd->id);
/*
* Assuming 14 bytes because that is the default
@@ -479,7 +479,7 @@ x54x_bios_command(x54x_t *x54x, uint8_t max_id, BIOSCMD *cmd, int8_t islba)
case 0x03: /* Write Desired Sectors from Memory */
case 0x04: /* Verify Desired Sectors */
case 0x0c: /* Seek */
target_check(cmd->id);
target_check(x54x, cmd->id);
cdb[0] = bios_cmd_to_scsi[cmd->command];
cdb[1] = (cmd->lun & 7) << 5;
@@ -519,7 +519,7 @@ x54x_bios_command(x54x_t *x54x, uint8_t max_id, BIOSCMD *cmd, int8_t islba)
case 0x07: /* Format Unit */
case 0x10: /* Test Drive Ready */
case 0x11: /* Recalibrate */
target_check(cmd->id);
target_check(x54x, cmd->id);
cdb[0] = bios_cmd_to_scsi[cmd->command];
cdb[1] = (cmd->lun & 7) << 5;
@@ -529,7 +529,7 @@ x54x_bios_command(x54x_t *x54x, uint8_t max_id, BIOSCMD *cmd, int8_t islba)
case 0x08: /* Read Drive Parameters */
case 0x15: /* Read DASD Type */
target_check(cmd->id);
target_check(x54x, cmd->id);
dev->buffer_length = 6;
@@ -758,7 +758,7 @@ x54x_set_residue(x54x_t *dev, Req_t *req, int32_t TransferLength)
{
uint32_t Residue = 0;
addr24 Residue24;
int32_t BufLen = scsi_devices[req->TargetID].buffer_length;
int32_t BufLen = scsi_devices[dev->bus][req->TargetID].buffer_length;
uint8_t bytes[4] = { 0, 0, 0, 0 };
if ((req->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND_RES) ||
@@ -792,7 +792,7 @@ x54x_buf_dma_transfer(x54x_t *dev, Req_t *req, int Is24bit, int TransferLength,
uint32_t DataPointer, DataLength;
uint32_t SGEntryLength = (Is24bit ? sizeof(SGE) : sizeof(SGE32));
uint32_t Address, i;
int32_t BufLen = scsi_devices[req->TargetID].buffer_length;
int32_t BufLen = scsi_devices[dev->bus][req->TargetID].buffer_length;
uint8_t read_from_host = (dir && ((req->CmdBlock.common.ControlByte == CCB_DATA_XFER_OUT) || (req->CmdBlock.common.ControlByte == 0x00)));
uint8_t write_to_host = (!dir && ((req->CmdBlock.common.ControlByte == CCB_DATA_XFER_IN) || (req->CmdBlock.common.ControlByte == 0x00)));
int sg_pos = 0;
@@ -824,11 +824,11 @@ x54x_buf_dma_transfer(x54x_t *dev, Req_t *req, int Is24bit, int TransferLength,
if (read_from_host && DataToTransfer) {
x54x_log("Reading S/G segment %i: length %i, pointer %08X\n", i, DataToTransfer, Address);
dma_bm_read(Address, &(scsi_devices[req->TargetID].sc->temp_buffer[sg_pos]), DataToTransfer, dev->transfer_size);
dma_bm_read(Address, &(scsi_devices[dev->bus][req->TargetID].sc->temp_buffer[sg_pos]), DataToTransfer, dev->transfer_size);
}
else if (write_to_host && DataToTransfer) {
x54x_log("Writing S/G segment %i: length %i, pointer %08X\n", i, DataToTransfer, Address);
dma_bm_write(Address, &(scsi_devices[req->TargetID].sc->temp_buffer[sg_pos]), DataToTransfer, dev->transfer_size);
dma_bm_write(Address, &(scsi_devices[dev->bus][req->TargetID].sc->temp_buffer[sg_pos]), DataToTransfer, dev->transfer_size);
}
else
x54x_log("No action on S/G segment %i: length %i, pointer %08X\n", i, DataToTransfer, Address);
@@ -848,9 +848,9 @@ x54x_buf_dma_transfer(x54x_t *dev, Req_t *req, int Is24bit, int TransferLength,
if ((DataLength > 0) && (BufLen > 0) && (req->CmdBlock.common.ControlByte < 0x03)) {
if (read_from_host)
dma_bm_read(Address, scsi_devices[req->TargetID].sc->temp_buffer, MIN(BufLen, (int) DataLength), dev->transfer_size);
dma_bm_read(Address, scsi_devices[dev->bus][req->TargetID].sc->temp_buffer, MIN(BufLen, (int) DataLength), dev->transfer_size);
else if (write_to_host)
dma_bm_write(Address, scsi_devices[req->TargetID].sc->temp_buffer, MIN(BufLen, (int) DataLength), dev->transfer_size);
dma_bm_write(Address, scsi_devices[dev->bus][req->TargetID].sc->temp_buffer, MIN(BufLen, (int) DataLength), dev->transfer_size);
}
}
}
@@ -896,7 +896,7 @@ SenseBufferFree(x54x_t *dev, Req_t *req, int Copy)
uint8_t temp_sense[256];
if (SenseLength && Copy) {
scsi_device_request_sense(&scsi_devices[req->TargetID], temp_sense, SenseLength);
scsi_device_request_sense(&scsi_devices[dev->bus][req->TargetID], temp_sense, SenseLength);
/*
* The sense address, in 32-bit mode, is located in the
@@ -925,7 +925,7 @@ x54x_scsi_cmd(x54x_t *dev)
uint32_t i, target_cdb_len = 12;
scsi_device_t *sd;
sd = &scsi_devices[req->TargetID];
sd = &scsi_devices[dev->bus][req->TargetID];
target_cdb_len = 12;
dev->target_data_len = x54x_get_length(dev, req, bit24);
@@ -965,7 +965,7 @@ x54x_scsi_cmd(x54x_t *dev)
else
dev->callback_sub_phase = 2;
x54x_log("scsi_devices[%02i].Status = %02X\n", req->TargetID, sd->status);
x54x_log("scsi_devices[%02i][%02i].Status = %02X\n", dev->bus, req->TargetID, sd->status);
}
@@ -977,7 +977,7 @@ x54x_scsi_cmd_phase1(x54x_t *dev)
uint8_t bit24 = !!req->Is24bit;
scsi_device_t *sd;
sd = &scsi_devices[req->TargetID];
sd = &scsi_devices[dev->bus][req->TargetID];
if (dev->scsi_cmd_phase != SCSI_PHASE_STATUS) {
if ((dev->temp_cdb[0] != 0x03) || (req->CmdBlock.common.ControlByte != 0x03)) {
@@ -992,7 +992,7 @@ x54x_scsi_cmd_phase1(x54x_t *dev)
}
dev->callback_sub_phase = 3;
x54x_log("scsi_devices[%02i].Status = %02X\n", req->TargetID, sd->status);
x54x_log("scsi_devices[%02xi][%02i].Status = %02X\n", x54x->bus, req->TargetID, sd->status);
}
@@ -1003,7 +1003,7 @@ x54x_request_sense(x54x_t *dev)
uint32_t SenseBufferAddress;
scsi_device_t *sd;
sd = &scsi_devices[req->TargetID];
sd = &scsi_devices[dev->bus][req->TargetID];
if (dev->scsi_cmd_phase != SCSI_PHASE_STATUS) {
if ((dev->temp_cdb[0] == 0x03) && (req->CmdBlock.common.ControlByte == 0x03)) {
@@ -1011,7 +1011,7 @@ x54x_request_sense(x54x_t *dev)
sd->buffer_length = ConvertSenseLength(req->CmdBlock.common.RequestSenseLength);
if ((sd->status != SCSI_STATUS_OK) && (sd->buffer_length > 0)) {
SenseBufferAddress = SenseBufferPointer(req);
dma_bm_write(SenseBufferAddress, scsi_devices[req->TargetID].sc->temp_buffer, sd->buffer_length, dev->transfer_size);
dma_bm_write(SenseBufferAddress, scsi_devices[dev->bus][req->TargetID].sc->temp_buffer, sd->buffer_length, dev->transfer_size);
x54x_add_to_period(dev, sd->buffer_length);
}
scsi_device_command_phase1(sd);
@@ -1033,7 +1033,7 @@ x54x_request_sense(x54x_t *dev)
}
dev->callback_sub_phase = 4;
x54x_log("scsi_devices[%02i].Status = %02X\n", req->TargetID, sd->status);
x54x_log("scsi_devices[%02i][%02i].Status = %02X\n", dev->bus, req->TargetID, sd->status);
}
@@ -1056,7 +1056,7 @@ x54x_notify(x54x_t *dev)
Req_t *req = &dev->Req;
scsi_device_t *sd;
sd = &scsi_devices[req->TargetID];
sd = &scsi_devices[dev->bus][req->TargetID];
x54x_mbo_free(dev);
@@ -1088,7 +1088,7 @@ x54x_req_setup(x54x_t *dev, uint32_t CCBPointer, Mailbox32_t *Mailbox32)
req->LUN = req->Is24bit ? req->CmdBlock.old.Lun : req->CmdBlock.new.Lun;
id = req->TargetID;
sd = &scsi_devices[id];
sd = &scsi_devices[dev->bus][id];
lun = req->LUN;
if ((id > dev->max_id) || (lun > 7)) {
x54x_log("SCSI Target ID %i or LUN %i is not valid\n",id,lun);
@@ -1466,7 +1466,7 @@ x54x_reset(x54x_t *dev)
/* Reset all devices on controller reset. */
for (i = 0; i < 16; i++)
scsi_device_reset(&scsi_devices[i]);
scsi_device_reset(&scsi_devices[dev->bus][i]);
if (dev->ven_reset)
dev->ven_reset(dev);
@@ -1522,7 +1522,7 @@ x54x_out(uint16_t port, uint8_t val, void *priv)
if (val & CTRL_SCRST) {
/* Reset all devices on SCSI bus reset. */
for (i = 0; i < 16; i++)
scsi_device_reset(&scsi_devices[i]);
scsi_device_reset(&scsi_devices[dev->bus][i]);
}
if (val & CTRL_IRST) {
@@ -1699,7 +1699,7 @@ x54x_out(uint16_t port, uint8_t val, void *priv)
if (i == host_id) continue;
/* TODO: Query device for LUN's. */
if (scsi_device_present(&scsi_devices[i]))
if (scsi_device_present(&scsi_devices[dev->bus][i]))
dev->DataBuf[i] |= 1;
}
dev->DataReplyLeft = i;
@@ -1846,9 +1846,9 @@ x54x_is_32bit(x54x_t *dev)
{
int bit32 = 0;
if (dev->bus & DEVICE_PCI)
if (dev->card_bus & DEVICE_PCI)
bit32 = 1;
else if ((dev->bus & DEVICE_MCA) && (dev->flags & X54X_32BIT))
else if ((dev->card_bus & DEVICE_MCA) && (dev->flags & X54X_32BIT))
bit32 = 1;
return bit32;
@@ -1939,7 +1939,7 @@ x54x_init(const device_t *info)
memset(dev, 0x00, sizeof(x54x_t));
dev->type = info->local;
dev->bus = info->flags;
dev->card_bus = info->flags;
dev->callback_phase = 0;
timer_add(&dev->ResetCB, x54x_reset_poll, dev, 0);

View File

@@ -244,6 +244,81 @@ static uint8_t sb_awe32_pnp_rom[] = {
0x79, 0x00 /* end tag, dummy checksum (filled in by isapnp_add_card) */
};
static uint8_t sb_awe64_gold_pnp_rom[] = {
0x0e, 0x8c, 0x00, 0x9e, 0x00, 0x00, 0x00, 0x00, 0x00, /* CTL009E, dummy checksum (filled in by isapnp_add_card) */
0x0a, 0x10, 0x20, /* PnP version 1.0, vendor version 2.0 */
0x82, 0x16, 0x00, 'C', 'r', 'e', 'a', 't', 'i', 'v', 'e', ' ', 'S', 'B', ' ', 'A', 'W', 'E', '6', '4', ' ', 'G', 'o', 'l', 'd', /* ANSI identifier */
0x16, 0x0e, 0x8c, 0x00, 0x44, 0x00, 0xa9, /* logical device CTL0044, supports vendor-specific registers 0x38/0x3A/0x3C/0x3F */
0x82, 0x05, 0x00, 'A', 'u', 'd', 'i', 'o', /* ANSI identifier */
0x31, 0x00, /* start dependent functions, preferred */
0x22, 0x20, 0x00, /* IRQ 5 */
0x2a, 0x02, 0x0c, /* DMA 1, compatibility, no count by word, count by byte, is bus master, 8-bit only */
0x2a, 0x20, 0x16, /* DMA 5, compatibility, count by word, no count by byte, is bus master, 16-bit only */
0x47, 0x01, 0x20, 0x02, 0x20, 0x02, 0x01, 0x10, /* I/O 0x220, decodes 16-bit, 1-byte alignment, 16 addresses */
0x47, 0x01, 0x30, 0x03, 0x30, 0x03, 0x01, 0x02, /* I/O 0x330, decodes 16-bit, 1-byte alignment, 2 addresses */
0x47, 0x01, 0x88, 0x03, 0xf8, 0x03, 0x01, 0x04, /* I/O 0x388-0x3F8, decodes 16-bit, 1-byte alignment, 4 addresses */
0x30, /* start dependent functions, acceptable */
0x22, 0xa0, 0x06, /* IRQ 5/7/9/10 */
0x2a, 0x0b, 0x0c, /* DMA 0/1/3, compatibility, no count by word, count by byte, is bus master, 8-bit only */
0x2a, 0xe0, 0x16, /* DMA 5/6/7, compatibility, count by word, no count by byte, is bus master, 16-bit only */
0x47, 0x01, 0x20, 0x02, 0x80, 0x02, 0x20, 0x10, /* I/O 0x220-0x280, decodes 16-bit, 32-byte alignment, 16 addresses */
0x47, 0x01, 0x00, 0x03, 0x30, 0x03, 0x30, 0x02, /* I/O 0x300-0x330, decodes 16-bit, 48-byte alignment, 2 addresses */
0x47, 0x01, 0x88, 0x03, 0xf8, 0x03, 0x01, 0x04, /* I/O 0x388-0x3F8, decodes 16-bit, 1-byte alignment, 4 addresses */
0x30, /* start dependent functions, acceptable */
0x22, 0xa0, 0x06, /* IRQ 5/7/9/10 */
0x2a, 0x0b, 0x0c, /* DMA 0/1/3, compatibility, no count by word, count by byte, is bus master, 8-bit only */
0x2a, 0xe0, 0x16, /* DMA 5/6/7, compatibility, count by word, no count by byte, is bus master, 16-bit only */
0x47, 0x01, 0x20, 0x02, 0x80, 0x02, 0x20, 0x10, /* I/O 0x220-0x280, decodes 16-bit, 32-byte alignment, 16 addresses */
0x47, 0x01, 0x00, 0x03, 0x30, 0x03, 0x30, 0x02, /* I/O 0x300-0x330, decodes 16-bit, 48-byte alignment, 2 addresses */
0x30, /* start dependent functions, acceptable */
0x22, 0xa0, 0x06, /* IRQ 5/7/9/10 */
0x2a, 0x0b, 0x0c, /* DMA 0/1/3, compatibility, no count by word, count by byte, is bus master, 8-bit only */
0x2a, 0xe0, 0x16, /* DMA 5/6/7, compatibility, count by word, no count by byte, is bus master, 16-bit only */
0x47, 0x01, 0x20, 0x02, 0x80, 0x02, 0x20, 0x10, /* I/O 0x220-0x280, decodes 16-bit, 32-byte alignment, 16 addresses */
0x30, /* start dependent functions, acceptable */
0x22, 0xa0, 0x06, /* IRQ 5/7/9/10 */
0x2a, 0x0b, 0x0c, /* DMA 0/1/3, compatibility, no count by word, count by byte, is bus master, 8-bit only */
0x47, 0x01, 0x20, 0x02, 0x80, 0x02, 0x20, 0x10, /* I/O 0x220-0x280, decodes 16-bit, 32-byte alignment, 16 addresses */
0x47, 0x01, 0x00, 0x03, 0x30, 0x03, 0x30, 0x02, /* I/O 0x300-0x330, decodes 16-bit, 48-byte alignment, 2 addresses */
0x47, 0x01, 0x88, 0x03, 0xf8, 0x03, 0x01, 0x04, /* I/O 0x388-0x3F8, decodes 16-bit, 1-byte alignment, 4 addresses */
0x30, /* start dependent functions, acceptable */
0x22, 0xa0, 0x06, /* IRQ 5/7/9/10 */
0x2a, 0x0b, 0x0c, /* DMA 0/1/3, compatibility, no count by word, count by byte, is bus master, 8-bit only */
0x47, 0x01, 0x20, 0x02, 0x80, 0x02, 0x20, 0x10, /* I/O 0x220-0x280, decodes 16-bit, 32-byte alignment, 16 addresses */
0x47, 0x01, 0x00, 0x03, 0x30, 0x03, 0x30, 0x02, /* I/O 0x300-0x330, decodes 16-bit, 48-byte alignment, 2 addresses */
0x30, /* start dependent functions, acceptable */
0x22, 0xa0, 0x06, /* IRQ 5/7/9/10 */
0x2a, 0x0b, 0x0c, /* DMA 0/1/3, compatibility, no count by word, count by byte, is bus master, 8-bit only */
0x47, 0x01, 0x20, 0x02, 0x80, 0x02, 0x20, 0x10, /* I/O 0x220-0x280, decodes 16-bit, 32-byte alignment, 16 addresses */
0x31, 0x02, /* start dependent functions, sub-optimal */
0x22, 0xa0, 0x06, /* IRQ 5/7/9/10 */
0x2a, 0x0b, 0x0c, /* DMA 0/1/3, compatibility, no count by word, count by byte, is bus master, 8-bit only */
0x2a, 0xe0, 0x16, /* DMA 5/6/7, compatibility, count by word, no count by byte, is bus master, 16-bit only */
0x47, 0x01, 0x20, 0x02, 0x80, 0x02, 0x20, 0x10, /* I/O 0x220-0x280, decodes 16-bit, 32-byte alignment, 16 addresses */
0x47, 0x01, 0x00, 0x03, 0x30, 0x03, 0x30, 0x02, /* I/O 0x300-0x330, decodes 16-bit, 48-byte alignment, 2 addresses */
0x47, 0x01, 0x88, 0x03, 0x94, 0x03, 0x04, 0x04, /* I/O 0x388-0x394, decodes 16-bit, 4-byte alignment, 4 addresses */
0x38, /* end dependent functions */
0x15, 0x0e, 0x8c, 0x70, 0x02, 0x00, /* logical device CTL7002 */
0x1c, 0x41, 0xd0, 0xb0, 0x2f, /* compatible device PNPB02F */
0x82, 0x04, 0x00, 'G', 'a', 'm', 'e', /* ANSI identifier */
0x47, 0x01, 0x00, 0x02, 0x00, 0x02, 0x01, 0x08, /* I/O 0x200, decodes 16-bit, 1-byte alignment, 8 addresses */
0x16, 0x0e, 0x8c, 0x00, 0x23, 0x00, 0xa9, /* logical device CTL0023, supports vendor-specific registers 0x38/0x3A/0x3C/0x3F */
0x82, 0x09, 0x00, 'W', 'a', 'v', 'e', 'T', 'a', 'b', 'l', 'e', /* ANSI identifier */
0x31, 0x00, /* start dependent functions, preferred */
0x47, 0x01, 0x20, 0x06, 0x20, 0x06, 0x01, 0x04, /* I/O 0x620, decodes 16-bit, 1-byte alignment, 4 addresses */
0x47, 0x01, 0x20, 0x0a, 0x20, 0x0a, 0x01, 0x04, /* I/O 0xA20, decodes 16-bit, 1-byte alignment, 4 addresses */
0x47, 0x01, 0x20, 0x0e, 0x20, 0x0e, 0x01, 0x04, /* I/O 0xE20, decodes 16-bit, 1-byte alignment, 4 addresses */
0x30, /* start dependent functions, acceptable */
0x47, 0x01, 0x20, 0x06, 0x80, 0x06, 0x20, 0x04, /* I/O 0x620-0x680, decodes 16-bit, 32-byte alignment, 4 addresses */
0x47, 0x01, 0x20, 0x0a, 0x80, 0x0a, 0x20, 0x04, /* I/O 0xA20-0xA80, decodes 16-bit, 32-byte alignment, 4 addresses */
0x47, 0x01, 0x20, 0x0e, 0x80, 0x0e, 0x20, 0x04, /* I/O 0xE20-0xE80, decodes 16-bit, 32-byte alignment, 4 addresses */
0x38, /* end dependent functions */
0x79, 0x00 /* end tag, dummy checksum (filled in by isapnp_add_card) */
};
#ifdef ENABLE_SB_LOG
@@ -1302,6 +1377,27 @@ sb_awe32_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *pr
}
static void
sb_awe64_gold_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *priv)
{
sb_t *sb = (sb_t *) priv;
switch (ld) {
case 0: /* Audio */
sb_16_pnp_config_changed(0, config, sb);
break;
case 1: /* Game */
sb_16_pnp_config_changed(1, config, sb);
break;
case 2: /* WaveTable */
emu8k_change_addr(&sb->emu8k, (config->activate && (config->io[0].base != ISAPNP_IO_DISABLED)) ? config->io[0].base : 0);
break;
}
}
void *
sb_1_init(const device_t *info)
{
@@ -1754,7 +1850,7 @@ sb_awe32_init(const device_t *info)
if (sb->opl_enabled)
opl3_init(&sb->opl);
sb_dsp_init(&sb->dsp, SB16 + 1, SB_SUBTYPE_DEFAULT, sb);
sb_dsp_init(&sb->dsp, SBAWE32, SB_SUBTYPE_DEFAULT, sb);
sb_dsp_setaddr(&sb->dsp, addr);
sb_dsp_setirq(&sb->dsp, device_get_config_int("irq"));
sb_dsp_setdma8(&sb->dsp, device_get_config_int("dma"));
@@ -1804,7 +1900,7 @@ sb_awe32_pnp_init(const device_t *info)
sb->opl_enabled = 1;
opl3_init(&sb->opl);
sb_dsp_init(&sb->dsp, SB16 + 1, SB_SUBTYPE_DEFAULT, sb);
sb_dsp_init(&sb->dsp, ((info->local == 2) ? SBAWE64 : SBAWE32), SB_SUBTYPE_DEFAULT, sb);
sb_ct1745_mixer_reset(sb);
sb->mixer_enabled = 1;
@@ -1823,7 +1919,9 @@ sb_awe32_pnp_init(const device_t *info)
sb->gameport = gameport_add(&gameport_pnp_device);
if (info->local == 1)
if (info->local == 2)
isapnp_add_card(sb_awe64_gold_pnp_rom, sizeof(sb_awe64_gold_pnp_rom), sb_awe64_gold_pnp_config_changed, NULL, NULL, NULL, sb);
else if (info->local == 1)
isapnp_add_card(sb_32_pnp_rom, sizeof(sb_32_pnp_rom), sb_awe32_pnp_config_changed, NULL, NULL, NULL, sb);
else
isapnp_add_card(sb_awe32_pnp_rom, sizeof(sb_awe32_pnp_rom), sb_awe32_pnp_config_changed, NULL, NULL, NULL, sb);
@@ -2458,6 +2556,45 @@ static const device_config_t sb_awe32_pnp_config[] =
}
};
static const device_config_t sb_awe64_gold_config[] =
{
{
"onboard_ram", "Onboard RAM", CONFIG_SELECTION, "", 4096, "", { 0 },
{
{
"None", 0
},
{
"512 KB", 512
},
{
"2 MB", 2048
},
{
"4 MB", 4096
},
{
"8 MB", 8192
},
{
"28 MB", 28*1024
},
{
""
}
}
},
{
"receive_input", "Receive input (SB MIDI)", CONFIG_BINARY, "", 1
},
{
"receive_input401", "Receive input (MPU-401)", CONFIG_BINARY, "", 0
},
{
"", "", -1
}
};
const device_t sb_1_device =
{
"Sound Blaster v1.0",
@@ -2604,3 +2741,15 @@ const device_t sb_awe32_pnp_device =
NULL,
sb_awe32_pnp_config
};
const device_t sb_awe64_gold_device =
{
"Sound Blaster AWE64 Gold",
DEVICE_ISA | DEVICE_AT,
2,
sb_awe32_pnp_init, sb_awe32_close, NULL,
{ sb_awe32_available },
sb_speed_changed,
NULL,
sb_awe64_gold_config
};

View File

@@ -66,7 +66,7 @@ static int sb_commands[256]=
char sb16_copyright[] = "COPYRIGHT (C) CREATIVE TECHNOLOGY LTD, 1992.";
uint16_t sb_dsp_versions[] = {0, 0, 0x105, 0x200, 0x201, 0x300, 0x302, 0x405, 0x40d};
uint16_t sb_dsp_versions[] = {0, 0, 0x105, 0x200, 0x201, 0x300, 0x302, 0x405, 0x40d, 0x410};
/*These tables were 'borrowed' from DOSBox*/
@@ -314,7 +314,7 @@ sb_doreset(sb_dsp_t *dsp)
sb_commands[8] = 1;
sb_commands[9] = 1;
} else {
if (dsp->sb_type==SB16)
if ((dsp->sb_type >= SB16) && (dsp->sb_type < SBAWE64))
sb_commands[8] = 1;
else
sb_commands[8] = -1;

View File

@@ -99,6 +99,7 @@ static const SOUND_CARD sound_cards[] =
{ "sb32_pnp", &sb_32_pnp_device },
{ "sbawe32", &sb_awe32_device },
{ "sbawe32_pnp", &sb_awe32_pnp_device },
{ "sbawe64_gold", &sb_awe64_gold_device },
#if defined(DEV_BRANCH) && defined(USE_PAS16)
{ "pas16", &pas16_device },
#endif

View File

@@ -253,6 +253,7 @@ typedef struct mach64_t
int overlay_v_acc;
uint8_t thread_run;
void *i2c, *ddc;
} mach64_t;
@@ -931,7 +932,7 @@ static void fifo_thread(void *param)
{
mach64_t *mach64 = (mach64_t *)param;
while (1)
while (mach64->thread_run)
{
thread_set_event(mach64->fifo_not_full_event);
thread_wait_event(mach64->wake_fifo_thread, -1);
@@ -3364,6 +3365,7 @@ static void *mach64_common_init(const device_t *info)
mach64->wake_fifo_thread = thread_create_event();
mach64->fifo_not_full_event = thread_create_event();
mach64->thread_run = 1;
mach64->fifo_thread = thread_create(fifo_thread, mach64);
mach64->i2c = i2c_gpio_init("ddc_ati_mach64");
@@ -3455,7 +3457,9 @@ void mach64_close(void *p)
svga_close(&mach64->svga);
thread_kill(mach64->fifo_thread);
mach64->thread_run = 0;
thread_set_event(mach64->wake_fifo_thread);
thread_wait(mach64->fifo_thread, -1);
thread_destroy_event(mach64->wake_fifo_thread);
thread_destroy_event(mach64->fifo_not_full_event);

View File

@@ -36,7 +36,7 @@
typedef struct {
mem_mapping_t mapping;
uint8_t crtc[32];
uint8_t crtc[32], charbuffer[4096];
int crtcreg;
uint8_t ctrl,
@@ -63,6 +63,8 @@ typedef struct {
int vsynctime;
int vadj;
int lp_ff;
int cols[256][2][2];
uint8_t *vram;
@@ -123,36 +125,58 @@ hercules_out(uint16_t addr, uint8_t val, void *priv)
dev->crtc[10] = 0xb;
dev->crtc[11] = 0xc;
}
#if 0
if (old ^ val)
recalc_timings(dev);
#else
if (old != val) {
if ((dev->crtcreg < 0xe) || (dev->crtcreg > 0x10)) {
fullchange = changeframecount;
recalc_timings(dev);
}
}
#endif
break;
case 0x03b8:
old = dev->ctrl;
if (!(dev->ctrl2 & 0x01) && !(val & 0x02))
val = (val & 0xfd) | (dev->ctrl & 0x02);
if (!(dev->ctrl2 & 0x02) && !(val & 0x80))
val = (val & 0x7f) | (dev->ctrl & 0x80);
dev->ctrl = val;
/* Prevent setting of bits if they are disabled in CTRL2. */
if ((old & 0x02) && !(val & 0x02))
dev->ctrl &= 0xfd;
else if ((val & 0x02) && (dev->ctrl2 & 0x01))
dev->ctrl |= 0x02;
if ((old & 0x80) && !(val & 0x80))
dev->ctrl &= 0x7f;
else if ((val & 0x80) && (dev->ctrl2 & 0x02))
dev->ctrl |= 0x80;
dev->ctrl = (dev->ctrl & 0x82) | (val & 0x7d);
if (old ^ val)
recalc_timings(dev);
break;
case 0x03b9:
case 0x03bb:
dev->lp_ff = !(addr & 0x0002);
break;
case 0x03bf:
old = dev->ctrl2;
dev->ctrl2 = val;
/* According to the Programmer's guide to the Hercules graphics cars
by David B. Doty from 1988, the CTRL2 modes (bits 1,0) are as follow:
- 00: DIAG: Text mode only, only page 0 accessible;
- 01: HALF: Graphics mode allowed, only page 0 accessible;
- 11: FULL: Graphics mode allowed, both pages accessible. */
if (val & 0x01)
mem_mapping_set_exec(&dev->mapping, dev->vram);
else
mem_mapping_set_exec(&dev->mapping, NULL);
if (val & 0x02)
mem_mapping_set_addr(&dev->mapping, 0xb0000, 0x10000);
else
mem_mapping_set_addr(&dev->mapping, 0xb0000, 0x08000);
if (old ^ val)
recalc_timings(dev);
break;
default:
@@ -180,19 +204,18 @@ hercules_in(uint16_t addr, void *priv)
case 0x03b5:
case 0x03b7:
ret = dev->crtc[dev->crtcreg];
if (dev->crtcreg == 12)
ret = (dev->ma >> 8) & 0x3f;
else
ret = dev->ma & 0xff;
break;
case 0x03ba:
ret = 0x72; /* Hercules ident */
#if 0
if (dev->stat & 0x08)
ret |= 0x88;
#else
ret = 0x70; /* Hercules ident */
ret |= (dev->lp_ff ? 2 : 0);
ret |= (dev->stat & 0x01);
if (dev->stat & 0x08)
ret |= 0x80;
#endif
if ((dev->stat & 0x09) == 0x01)
ret |= (dev->stat & 0x01);
if ((ret & 0x81) == 0x80)
ret |= 0x08;
break;
@@ -222,9 +245,11 @@ hercules_write(uint32_t addr, uint8_t val, void *priv)
hercules_t *dev = (hercules_t *)priv;
if (dev->ctrl2 & 0x01)
dev->vram[addr & 0xffff] = val;
addr &= 0xffff;
else
dev->vram[addr & 0x0fff] = val;
addr &= 0x0fff;
dev->vram[addr] = val;
hercules_waitstates(dev);
}
@@ -234,13 +259,18 @@ static uint8_t
hercules_read(uint32_t addr, void *priv)
{
hercules_t *dev = (hercules_t *)priv;
uint8_t ret = 0xff;
if (dev->ctrl2 & 0x01)
return(dev->vram[addr & 0xffff]);
addr &= 0xffff;
else
return(dev->vram[addr & 0x0fff]);
addr &= 0x0fff;
hercules_waitstates(dev);
ret = dev->vram[addr];
return ret;
}
@@ -250,6 +280,7 @@ hercules_poll(void *priv)
hercules_t *dev = (hercules_t *)priv;
uint8_t chr, attr;
uint16_t ca, dat;
uint16_t pa;
int oldsc, blink;
int x, c, oldvc;
int drawcursor;
@@ -267,21 +298,18 @@ hercules_poll(void *priv)
if (dev->dispon) {
if (dev->displine < dev->firstline) {
dev->firstline = dev->displine;
video_wait_for_buffer();
dev->firstline = dev->displine;
video_wait_for_buffer();
}
dev->lastline = dev->displine;
// if ((dev->ctrl & 2) && (dev->ctrl2 & 1)) {
if (dev->ctrl & 2) {
if (dev->ctrl & 0x02) {
ca = (dev->sc & 3) * 0x2000;
// if ((dev->ctrl & 0x80) && (dev->ctrl2 & 2))
if (dev->ctrl & 0x80)
ca += 0x8000;
for (x = 0; x < dev->crtc[1]; x++) {
if (dev->ctrl & 8)
// dat = (dev->vram[((dev->ma << 1) & 0x1fff) + ca] << 8) | dev->vram[((dev->ma << 1) & 0x1fff) + ca + 1];
dat = (dev->vram[((dev->ma << 1) & 0x1fff) + ca] << 8) | dev->vram[((dev->ma << 1) & 0x1fff) + ca + 1];
else
dat = 0;
@@ -294,8 +322,10 @@ hercules_poll(void *priv)
} else {
for (x = 0; x < dev->crtc[1]; x++) {
if (dev->ctrl & 8) {
chr = dev->vram[(dev->ma << 1) & 0xfff];
attr = dev->vram[((dev->ma << 1) + 1) & 0xfff];
/* Undocumented behavior: page 1 in text mode means characters are read
from page 1 and attributes from page 0. */
chr = dev->charbuffer[x << 1];
attr = dev->charbuffer[(x << 1) + 1];
} else
chr = attr = 0;
drawcursor = ((dev->ma == ca) && dev->con && dev->cursoron);
@@ -313,7 +343,10 @@ hercules_poll(void *priv)
else
buffer32->line[dev->displine][(x * 9) + 8] = dev->cols[attr][blink][0];
}
dev->ma++;
if (dev->ctrl2 & 0x01)
dev->ma = (dev->ma + 1) & 0x3fff;
else
dev->ma = (dev->ma + 1) & 0x7ff;
if (drawcursor) {
for (c = 0; c < 9; c++)
@@ -332,6 +365,9 @@ hercules_poll(void *priv)
} else {
timer_advance_u64(&dev->timer, dev->dispontime);
if (dev->dispon)
dev->stat &= ~1;
dev->linepos = 0;
if (dev->vsynctime) {
dev->vsynctime--;
@@ -349,42 +385,51 @@ hercules_poll(void *priv)
dev->sc++;
dev->sc &= 31;
dev->ma = dev->maback;
dev->vadj--;
if (! dev->vadj) {
dev->dispon = 1;
dev->ma = dev->maback = (dev->crtc[13] | (dev->crtc[12] << 8)) & 0x3fff;
dev->sc = 0;
}
} else if (dev->sc == dev->crtc[9] || ((dev->crtc[8] & 3) == 3 && dev->sc == (dev->crtc[9] >> 1))) {
} else if (((dev->crtc[8] & 3) != 3 && dev->sc == dev->crtc[9]) || ((dev->crtc[8] & 3) == 3 && dev->sc == (dev->crtc[9] >> 1))) {
dev->maback = dev->ma;
dev->sc = 0;
oldvc = dev->vc;
dev->vc++;
dev->vc &= 127;
if (dev->vc == dev->crtc[6])
dev->dispon = 0;
if (oldvc == dev->crtc[4]) {
dev->vc = 0;
dev->vadj = dev->crtc[5];
if (! dev->vadj)
if (! dev->vadj) {
dev->dispon = 1;
if (! dev->vadj)
dev->ma = dev->maback = (dev->crtc[13] | (dev->crtc[12] << 8)) & 0x3fff;
if ((dev->crtc[10] & 0x60) == 0x20)
dev->cursoron = 0;
else
dev->cursoron = dev->blink & 16;
}
switch (dev->crtc[10] & 0x60) {
case 0x20:
dev->cursoron = 0;
break;
case 0x60:
dev->cursoron = dev->blink & 0x10;
break;
default:
dev->cursoron = dev->blink & 0x08;
break;
}
}
if (dev->vc == dev->crtc[7]) {
dev->dispon = 0;
dev->displine = 0;
dev->vsynctime = 16;//(crtcm[3]>>4)+1;
if ((dev->crtc[8] & 3) == 3)
dev->vsynctime = ((int32_t)dev->crtc[4] * ((dev->crtc[9] >> 1) + 1)) + dev->crtc[5] - dev->crtc[7] + 1;
else
dev->vsynctime = ((int32_t)dev->crtc[4] * (dev->crtc[9] + 1)) + dev->crtc[5] - dev->crtc[7] + 1;
if (dev->crtc[7]) {
// if ((dev->ctrl & 2) && (dev->ctrl2 & 1))
if (dev->ctrl & 2)
if (dev->ctrl & 0x02)
x = dev->crtc[1] << 4;
else
x = dev->crtc[1] * 9;
@@ -404,7 +449,8 @@ hercules_poll(void *priv)
video_blit_memtoscreen_8(0, dev->firstline, 0, ysize, xsize, ysize);
frames++;
if ((dev->ctrl & 2) && (dev->ctrl2 & 1)) {
// if ((dev->ctrl & 2) && (dev->ctrl2 & 1)) {
if (dev->ctrl & 0x02) {
video_res_x = dev->crtc[1] * 16;
video_res_y = dev->crtc[6] * 4;
video_bpp = 1;
@@ -424,12 +470,15 @@ hercules_poll(void *priv)
dev->ma = dev->maback;
}
if (dev->dispon)
dev->stat &= ~1;
if ((dev->sc == (dev->crtc[10] & 31) ||
((dev->crtc[8] & 3)==3 && dev->sc == ((dev->crtc[10] & 31) >> 1))))
dev->con = 1;
if (dev->dispon && !(dev->ctrl & 0x02)) {
for (x = 0; x < (dev->crtc[1] << 1); x++) {
pa = (dev->ctrl & 0x80) ? ((x & 1) ? 0x0000 : 0x8000) : 0x0000;
dev->charbuffer[x] = dev->vram[(((dev->ma << 1) + x) & 0x3fff) + pa];
}
}
}
}
@@ -447,9 +496,9 @@ hercules_init(const device_t *info)
timer_add(&dev->timer, hercules_poll, dev, 1);
mem_mapping_add(&dev->mapping, 0xb0000, 0x10000,
mem_mapping_add(&dev->mapping, 0xb0000, 0x08000,
hercules_read,NULL,NULL, hercules_write,NULL,NULL,
dev->vram, MEM_MAPPING_EXTERNAL, dev);
NULL /*dev->vram*/, MEM_MAPPING_EXTERNAL, dev);
io_sethandler(0x03b0, 16,
hercules_in,NULL,NULL, hercules_out,NULL,NULL, dev);

View File

@@ -502,6 +502,8 @@ typedef struct mystique_t
mutex_t *lock;
} dma;
uint8_t thread_run;
void *i2c, *i2c_ddc, *ddc;
} mystique_t;
@@ -2354,7 +2356,7 @@ fifo_thread(void *p)
{
mystique_t *mystique = (mystique_t *)p;
while (1) {
while (mystique->thread_run) {
thread_set_event(mystique->fifo_not_full_event);
thread_wait_event(mystique->wake_fifo_thread, -1);
thread_reset_event(mystique->wake_fifo_thread);
@@ -5008,6 +5010,7 @@ mystique_init(const device_t *info)
mystique->wake_fifo_thread = thread_create_event();
mystique->fifo_not_full_event = thread_create_event();
mystique->thread_run = 1;
mystique->fifo_thread = thread_create(fifo_thread, mystique);
mystique->dma.lock = thread_create_mutex();
@@ -5031,7 +5034,9 @@ mystique_close(void *p)
{
mystique_t *mystique = (mystique_t *)p;
thread_kill(mystique->fifo_thread);
mystique->thread_run = 0;
thread_set_event(mystique->wake_fifo_thread);
thread_wait(mystique->fifo_thread, -1);
thread_destroy_event(mystique->wake_fifo_thread);
thread_destroy_event(mystique->fifo_not_full_event);
thread_close_mutex(mystique->dma.lock);

View File

@@ -319,7 +319,7 @@ typedef struct s3_t
int enable_8514;
volatile int busy, force_busy;
uint8_t serialport;
uint8_t thread_run, serialport;
void *i2c, *ddc;
} s3_t;
@@ -1509,7 +1509,7 @@ fifo_thread(void *param)
{
s3_t *s3 = (s3_t *)param;
while (1)
while (s3->thread_run)
{
thread_set_event(s3->fifo_not_full_event);
thread_wait_event(s3->wake_fifo_thread, -1);
@@ -6170,7 +6170,8 @@ static void *s3_init(const device_t *info)
case S3_DIAMOND_STEALTH_SE:
svga->decode_mask = (4 << 20) - 1;
s3->id = 0xe1; /*Trio32*/
s3->id_ext = s3->id_ext_pci = 0x10;
s3->id_ext = 0x10;
s3->id_ext_pci = 0x11;
s3->packed_mmio = 1;
svga->clock_gen = s3;
@@ -6235,6 +6236,7 @@ static void *s3_init(const device_t *info)
s3->wake_fifo_thread = thread_create_event();
s3->fifo_not_full_event = thread_create_event();
s3->thread_run = 1;
s3->fifo_thread = thread_create(fifo_thread, s3);
return s3;
@@ -6341,7 +6343,9 @@ static void s3_close(void *p)
svga_close(&s3->svga);
thread_kill(s3->fifo_thread);
s3->thread_run = 0;
thread_set_event(s3->wake_fifo_thread);
thread_wait(s3->fifo_thread, -1);
thread_destroy_event(s3->wake_fifo_thread);
thread_destroy_event(s3->fifo_not_full_event);

View File

@@ -288,6 +288,8 @@ typedef struct virge_t
uint8_t subsys_stat, subsys_cntl, advfunc_cntl;
uint8_t render_thread_run, fifo_thread_run;
uint8_t serialport;
void *i2c, *ddc;
@@ -1122,7 +1124,7 @@ static void fifo_thread(void *param)
{
virge_t *virge = (virge_t *)param;
while (1)
while (virge->fifo_thread_run)
{
thread_set_event(virge->fifo_not_full_event);
thread_wait_event(virge->wake_fifo_thread, -1);
@@ -3235,7 +3237,7 @@ static void render_thread(void *param)
{
virge_t *virge = (virge_t *)param;
while (1)
while (virge->render_thread_run)
{
thread_wait_event(virge->wake_render_thread, -1);
thread_reset_event(virge->wake_render_thread);
@@ -3897,10 +3899,12 @@ static void *s3_virge_init(const device_t *info)
virge->wake_render_thread = thread_create_event();
virge->wake_main_thread = thread_create_event();
virge->not_full_event = thread_create_event();
virge->render_thread_run = 1;
virge->render_thread = thread_create(render_thread, virge);
virge->wake_fifo_thread = thread_create_event();
virge->fifo_not_full_event = thread_create_event();
virge->fifo_thread_run = 1;
virge->fifo_thread = thread_create(fifo_thread, virge);
virge->i2c = i2c_gpio_init("ddc_s3_virge");
@@ -3915,12 +3919,16 @@ static void s3_virge_close(void *p)
{
virge_t *virge = (virge_t *)p;
thread_kill(virge->render_thread);
virge->render_thread_run = 0;
thread_set_event(virge->wake_render_thread);
thread_wait(virge->render_thread, -1);
thread_destroy_event(virge->not_full_event);
thread_destroy_event(virge->wake_main_thread);
thread_destroy_event(virge->wake_render_thread);
thread_kill(virge->fifo_thread);
virge->fifo_thread_run = 0;
thread_set_event(virge->wake_fifo_thread);
thread_wait(virge->fifo_thread, -1);
thread_destroy_event(virge->wake_fifo_thread);
thread_destroy_event(virge->fifo_not_full_event);

View File

@@ -976,12 +976,18 @@ void *voodoo_card_init()
voodoo->render_not_full_event[1] = thread_create_event();
voodoo->render_not_full_event[2] = thread_create_event();
voodoo->render_not_full_event[3] = thread_create_event();
voodoo->fifo_thread_run = 1;
voodoo->fifo_thread = thread_create(voodoo_fifo_thread, voodoo);
voodoo->render_thread_run[0] = 1;
voodoo->render_thread[0] = thread_create(voodoo_render_thread_1, voodoo);
if (voodoo->render_threads >= 2)
if (voodoo->render_threads >= 2) {
voodoo->render_thread_run[1] = 1;
voodoo->render_thread[1] = thread_create(voodoo_render_thread_2, voodoo);
}
if (voodoo->render_threads == 4) {
voodoo->render_thread_run[2] = 1;
voodoo->render_thread[2] = thread_create(voodoo_render_thread_3, voodoo);
voodoo->render_thread_run[3] = 1;
voodoo->render_thread[3] = thread_create(voodoo_render_thread_4, voodoo);
}
voodoo->swap_mutex = thread_create_mutex();
@@ -1094,12 +1100,18 @@ void *voodoo_2d3d_card_init(int type)
voodoo->render_not_full_event[1] = thread_create_event();
voodoo->render_not_full_event[2] = thread_create_event();
voodoo->render_not_full_event[3] = thread_create_event();
voodoo->fifo_thread_run = 1;
voodoo->fifo_thread = thread_create(voodoo_fifo_thread, voodoo);
voodoo->render_thread_run[0] = 1;
voodoo->render_thread[0] = thread_create(voodoo_render_thread_1, voodoo);
if (voodoo->render_threads >= 2)
if (voodoo->render_threads >= 2) {
voodoo->render_thread_run[1] = 1;
voodoo->render_thread[1] = thread_create(voodoo_render_thread_2, voodoo);
}
if (voodoo->render_threads == 4) {
voodoo->render_thread_run[2] = 1;
voodoo->render_thread[2] = thread_create(voodoo_render_thread_3, voodoo);
voodoo->render_thread_run[3] = 1;
voodoo->render_thread[3] = thread_create(voodoo_render_thread_4, voodoo);
}
voodoo->swap_mutex = thread_create_mutex();
@@ -1243,13 +1255,24 @@ void voodoo_card_close(voodoo_t *voodoo)
#endif */
thread_kill(voodoo->fifo_thread);
thread_kill(voodoo->render_thread[0]);
if (voodoo->render_threads >= 2)
thread_kill(voodoo->render_thread[1]);
voodoo->fifo_thread_run = 0;
thread_set_event(voodoo->wake_fifo_thread);
thread_wait(voodoo->fifo_thread, -1);
voodoo->render_thread_run[0] = 0;
thread_set_event(voodoo->wake_render_thread[0]);
thread_wait(voodoo->render_thread[0], -1);
if (voodoo->render_threads >= 2) {
voodoo->render_thread_run[1] = 0;
thread_set_event(voodoo->wake_render_thread[1]);
thread_wait(voodoo->render_thread[1], -1);
}
if (voodoo->render_threads == 4) {
thread_kill(voodoo->render_thread[2]);
thread_kill(voodoo->render_thread[3]);
voodoo->render_thread_run[2] = 0;
thread_set_event(voodoo->wake_render_thread[2]);
thread_wait(voodoo->render_thread[2], -1);
voodoo->render_thread_run[3] = 0;
thread_set_event(voodoo->wake_render_thread[3]);
thread_wait(voodoo->render_thread[3], -1);
}
thread_destroy_event(voodoo->fifo_not_full_event);
thread_destroy_event(voodoo->wake_main_thread);

View File

@@ -204,7 +204,7 @@ void voodoo_fifo_thread(void *param)
{
voodoo_t *voodoo = (voodoo_t *)param;
while (1)
while (voodoo->fifo_thread_run)
{
thread_set_event(voodoo->fifo_not_full_event);
thread_wait_event(voodoo->wake_fifo_thread, -1);

View File

@@ -1605,7 +1605,7 @@ static void render_thread(void *param, int odd_even)
{
voodoo_t *voodoo = (voodoo_t *)param;
while (1)
while (voodoo->render_thread_run[odd_even])
{
thread_set_event(voodoo->render_not_full_event[odd_even]);
thread_wait_event(voodoo->wake_render_thread[odd_even], -1);

View File

@@ -113,6 +113,7 @@ int video_graytype = 0;
static int vid_type;
static const video_timings_t *vid_timings;
static uint32_t cga_2_table[16];
static uint8_t thread_run = 0;
PALETTE cgapal = {
@@ -430,7 +431,7 @@ void blit_thread(void *param)
{
int yy;
while (1) {
while (thread_run) {
thread_wait_event(blit_data.wake_blit_thread, -1);
thread_reset_event(blit_data.wake_blit_thread);
MTR_BEGIN("video", "blit_thread");
@@ -880,6 +881,7 @@ video_init(void)
blit_data.wake_blit_thread = thread_create_event();
blit_data.blit_complete = thread_create_event();
blit_data.buffer_not_in_use = thread_create_event();
thread_run = 1;
blit_data.blit_thread = thread_create(blit_thread, NULL);
}
@@ -887,7 +889,9 @@ video_init(void)
void
video_close(void)
{
thread_kill(blit_data.blit_thread);
thread_run = 0;
thread_set_event(blit_data.wake_blit_thread);
thread_wait(blit_data.blit_thread, -1);
thread_destroy_event(blit_data.buffer_not_in_use);
thread_destroy_event(blit_data.blit_complete);
thread_destroy_event(blit_data.wake_blit_thread);

View File

@@ -45,6 +45,7 @@ MainMenu MENU DISCARDABLE
BEGIN
POPUP "&Action"
BEGIN
MENUITEM "&Keyboard requires capture", IDM_ACTION_KBD_REQ_CAPTURE
MENUITEM "&Right CTRL is left ALT", IDM_ACTION_RCTRL_IS_LALT
MENUITEM SEPARATOR
MENUITEM "&Hard Reset", IDM_ACTION_HRESET
@@ -58,6 +59,8 @@ BEGIN
END
POPUP "&View"
BEGIN
MENUITEM "&Hide status bar", IDM_VID_HIDE_STATUS_BAR
MENUITEM SEPARATOR
MENUITEM "&Resizeable window", IDM_VID_RESIZE
MENUITEM "R&emember size && position", IDM_VID_REMEMBER
MENUITEM SEPARATOR
@@ -186,6 +189,34 @@ BEGIN
MENUITEM SEPARATOR
END
CassetteSubmenu MENU DISCARDABLE
BEGIN
POPUP ""
BEGIN
MENUITEM "&New image...", IDM_CASSETTE_IMAGE_NEW
MENUITEM SEPARATOR
MENUITEM "&Existing image...", IDM_CASSETTE_IMAGE_EXISTING
MENUITEM "Existing image (&Write-protected)...", IDM_CASSETTE_IMAGE_EXISTING_WP
MENUITEM SEPARATOR
MENUITEM "&Record", IDM_CASSETTE_RECORD
MENUITEM "&Play", IDM_CASSETTE_PLAY
MENUITEM "&Rewind to the beginning", IDM_CASSETTE_REWIND
MENUITEM "&Fast forward to the end", IDM_CASSETTE_FAST_FORWARD
MENUITEM SEPARATOR
MENUITEM "E&ject", IDM_CASSETTE_EJECT
END
END
CartridgeSubmenu MENU DISCARDABLE
BEGIN
POPUP ""
BEGIN
MENUITEM "&Image...", IDM_CARTRIDGE_IMAGE
MENUITEM SEPARATOR
MENUITEM "E&ject", IDM_CARTRIDGE_EJECT
END
END
FloppySubmenu MENU DISCARDABLE
BEGIN
POPUP ""
@@ -548,32 +579,48 @@ BEGIN
BS_AUTOCHECKBOX | WS_TABSTOP,7,118,94,10
END
DLG_CFG_STORAGE DIALOG DISCARDABLE 107, 0, 267, 111
DLG_CFG_STORAGE DIALOG DISCARDABLE 107, 0, 267, 203
STYLE DS_CONTROL | WS_CHILD
FONT 9, "Segoe UI"
BEGIN
LTEXT "SCSI Controller:",IDT_1717,7,9,64,10
COMBOBOX IDC_COMBO_SCSI,64,7,155,120,CBS_DROPDOWNLIST |
LTEXT "HD Controller:",IDT_1718,7,9,64,10
COMBOBOX IDC_COMBO_HDC,64,7,155,120,CBS_DROPDOWNLIST |
WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "Configure",IDC_CONFIGURE_SCSI,222,7,38,12
PUSHBUTTON "Configure",IDC_CONFIGURE_HDC,222,7,38,12
LTEXT "HD Controller:",IDT_1718,7,28,64,10
COMBOBOX IDC_COMBO_HDC,64,26,155,120,CBS_DROPDOWNLIST |
LTEXT "FD Controller:",IDT_1768,7,28,64,10
COMBOBOX IDC_COMBO_FDC,64,26,155,120,CBS_DROPDOWNLIST |
WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "Configure",IDC_CONFIGURE_HDC,222,26,38,12
LTEXT "FD Controller:",IDT_1768,7,47,64,10
COMBOBOX IDC_COMBO_FDC,64,45,155,120,CBS_DROPDOWNLIST |
WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "Configure",IDC_CONFIGURE_FDC,222,45,38,12
PUSHBUTTON "Configure",IDC_CONFIGURE_FDC,222,26,38,12
CONTROL "Tertiary IDE Controller",IDC_CHECK_IDE_TER,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,7,66,199,10
PUSHBUTTON "Configure",IDC_BUTTON_IDE_TER,222,64,38,12
BS_AUTOCHECKBOX | WS_TABSTOP,7,47,199,10
PUSHBUTTON "Configure",IDC_BUTTON_IDE_TER,222,45,38,12
CONTROL "Quaternary IDE Controller",IDC_CHECK_IDE_QUA,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,7,85,199,10
PUSHBUTTON "Configure",IDC_BUTTON_IDE_QUA,222,83,38,12
BS_AUTOCHECKBOX | WS_TABSTOP,7,66,199,10
PUSHBUTTON "Configure",IDC_BUTTON_IDE_QUA,222,64,38,12
GROUPBOX "SCSI",IDC_GROUP_SCSI,7,85,253,93
LTEXT "Controller 1:",IDT_1763,16,102,48,10
COMBOBOX IDC_COMBO_SCSI_1,73,100,137,120,
CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "Configure",IDC_CONFIGURE_SCSI_1,213,100,38,12
LTEXT "Controller 2:",IDT_1764,16,121,48,10
COMBOBOX IDC_COMBO_SCSI_2,73,119,137,120,
CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "Configure",IDC_CONFIGURE_SCSI_2,213,119,38,12
LTEXT "Controller 3:",IDT_1765,16,140,48,10
COMBOBOX IDC_COMBO_SCSI_3,73,138,137,120,
CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "Configure",IDC_CONFIGURE_SCSI_3,213,138,38,12
LTEXT "Controller 4:",IDT_1766,16,159,48,10
COMBOBOX IDC_COMBO_SCSI_4,73,157,137,120,
CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "Configure",IDC_CONFIGURE_SCSI_4,213,157,38,12
CONTROL "Cassette",IDC_CHECK_CASSETTE,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,7,185,94,10
END
DLG_CFG_HARD_DISKS DIALOG DISCARDABLE 107, 0, 267, 154
@@ -796,6 +843,7 @@ END
81 ICON DISCARDABLE ICON_PATH "icons/hard_disk_active.ico"
96 ICON DISCARDABLE ICON_PATH "icons/network.ico"
97 ICON DISCARDABLE ICON_PATH "icons/network_active.ico"
104 ICON DISCARDABLE ICON_PATH "icons/cartridge.ico"
144 ICON DISCARDABLE ICON_PATH "icons/floppy_525_empty.ico"
145 ICON DISCARDABLE ICON_PATH "icons/floppy_525_empty_active.ico"
152 ICON DISCARDABLE ICON_PATH "icons/floppy_35_empty.ico"
@@ -808,6 +856,7 @@ END
185 ICON DISCARDABLE ICON_PATH "icons/mo_empty_active.ico"
192 ICON DISCARDABLE ICON_PATH "icons/cassette_empty.ico"
193 ICON DISCARDABLE ICON_PATH "icons/cassette_empty_active.ico"
232 ICON DISCARDABLE ICON_PATH "icons/cartridge_empty.ico"
240 ICON DISCARDABLE ICON_PATH "icons/machine.ico"
241 ICON DISCARDABLE ICON_PATH "icons/display.ico"
242 ICON DISCARDABLE ICON_PATH "icons/input_devices.ico"
@@ -1107,13 +1156,17 @@ BEGIN
IDS_2145 "You are loading an unsupported configuration"
IDS_2146 "CPU type filtering based on selected machine is disabled for this emulated machine.\n\nThis makes it possible to choose a CPU that is otherwise incompatible with the selected machine. However, you may run into incompatibilities with the machine BIOS or other software.\n\nEnabling this setting is not officially supported and any bug reports filed may be closed as invalid."
IDS_2147 "Continue"
IDS_2148 "Cassette: %s"
IDS_2149 "Cassette images (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0All files (*.*)\0*.*\0"
IDS_2150 "Cartridge %i: %ls"
IDS_2151 "Cartridge images (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0All files (*.*)\0*.*\0"
END
STRINGTABLE DISCARDABLE
BEGIN
IDS_4096 "Hard disk (%s)"
IDS_4097 "%01i:%01i"
IDS_4098 "%i"
IDS_4098 "%01i"
IDS_4099 "MFM/RLL or ESDI CD-ROM drives never existed"
IDS_4100 "Custom..."
IDS_4101 "Custom (large)..."
@@ -1150,6 +1203,7 @@ BEGIN
IDS_4132 "This could mean that the parent image was modified after the differencing image was created.\n\nIt can also happen if the image files were moved or copied, or by a bug in the program that created this disk.\n\nDo you want to fix the timestamps?"
IDS_4133 "Parent and child disk timestamps do not match"
IDS_4134 "Could not fix VHD timestamp."
IDS_4135 "%01i:%02i"
IDS_4352 "MFM/RLL"
IDS_4353 "XTA"
@@ -1163,7 +1217,7 @@ BEGIN
IDS_4610 "ESDI (%01i:%01i)"
IDS_4611 "IDE (%01i:%01i)"
IDS_4612 "ATAPI (%01i:%01i)"
IDS_4613 "SCSI (ID %02i)"
IDS_4613 "SCSI (%01i:%02i)"
IDS_5120 "CD-ROM %i (%s): %s"
@@ -1173,7 +1227,7 @@ BEGIN
IDS_5632 "Disabled"
IDS_5637 "ATAPI (%01i:%01i)"
IDS_5638 "SCSI (ID %02i)"
IDS_5638 "SCSI (%01i:%02i)"
IDS_5888 "160 kB"
IDS_5889 "180 kB"

BIN
src/win/icons/cartridge.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -69,6 +69,7 @@ HANDLE ghMutex;
LCID lang_id; /* current language ID used */
DWORD dwSubLangID;
int acp_utf8; /* Windows supports UTF-8 codepage */
volatile int cpu_thread_run = 1;
/* Local data. */
@@ -487,7 +488,7 @@ main_thread(void *param)
title_update = 1;
old_time = GetTickCount();
drawits = frames = 0;
while (!is_quit) {
while (!is_quit && cpu_thread_run) {
/* See if it is time to run a frame of code. */
new_time = GetTickCount();
drawits += (new_time - old_time);
@@ -512,7 +513,7 @@ main_thread(void *param)
// Sleep(1);
/* If needed, handle a screen resize. */
if (doresize && !video_fullscreen) {
if (doresize && !video_fullscreen && !is_quit) {
if (vid_resize & 2)
plat_resize(fixed_size_x, fixed_size_y);
else
@@ -520,6 +521,8 @@ main_thread(void *param)
doresize = 0;
}
}
is_quit = 1;
}
@@ -543,7 +546,7 @@ do_start(void)
win_log("Main timer precision: %llu\n", timer_freq);
/* Start the emulator, really. */
thMain = thread_create(main_thread, &is_quit);
thMain = thread_create(main_thread, NULL);
SetThreadPriority(thMain, THREAD_PRIORITY_HIGHEST);
}
@@ -552,16 +555,17 @@ do_start(void)
void
do_stop(void)
{
is_quit = 1;
/* Claim the video blitter. */
startblit();
plat_delay_ms(100);
if (source_hwnd)
PostMessage((HWND) (uintptr_t) source_hwnd, WM_HAS_SHUTDOWN, (WPARAM) 0, (LPARAM) hwndMain);
vid_apis[vid_api].close();
pc_close(thMain);
thMain = NULL;
if (source_hwnd)
PostMessage((HWND) (uintptr_t) source_hwnd, WM_HAS_SHUTDOWN, (WPARAM) 0, (LPARAM) hwndMain);
}
@@ -1072,7 +1076,10 @@ plat_setfullscreen(int on)
GetClientRect(hwndMain, &rect);
temp_x = rect.right - rect.left + 1;
temp_y = rect.bottom - rect.top + 1 - sbar_height;
if (hide_status_bar)
temp_y = rect.bottom - rect.top + 1;
else
temp_y = rect.bottom - rect.top + 1 - sbar_height;
} else {
if (dpi_scale) {
temp_x = MulDiv((vid_resize & 2) ? fixed_size_x : unscaled_size_x, dpi, 96);
@@ -1083,7 +1090,10 @@ plat_setfullscreen(int on)
}
/* Main Window. */
ResizeWindowByClientArea(hwndMain, temp_x, temp_y + sbar_height);
if (hide_status_bar)
ResizeWindowByClientArea(hwndMain, temp_x, temp_y);
else
ResizeWindowByClientArea(hwndMain, temp_x, temp_y + sbar_height);
}
/* Render window. */

View File

@@ -27,8 +27,12 @@
#include <string.h>
#include <stdlib.h>
#include <wchar.h>
#include <86box/86box.h>
#include <86box/config.h>
#include <86box/timer.h>
#include <86box/device.h>
#include <86box/cassette.h>
#include <86box/cartridge.h>
#include <86box/fdd.h>
#include <86box/hdd.h>
#include <86box/scsi_device.h>
@@ -41,6 +45,57 @@
#include <86box/win.h>
void
cassette_mount(char *fn, uint8_t wp)
{
pc_cas_set_fname(cassette, NULL);
memset(cassette_fname, 0, sizeof(cassette_fname));
cassette_ui_writeprot = wp;
pc_cas_set_fname(cassette, fn);
if (fn != NULL)
memcpy(cassette_fname, fn, MIN(511, strlen(fn)));
ui_sb_update_icon_state(SB_CASSETTE, (fn == NULL) ? 1 : 0);
media_menu_update_cassette();
ui_sb_update_tip(SB_CASSETTE);
config_save();
}
void
cassette_eject(void)
{
pc_cas_set_fname(cassette, NULL);
memset(cassette_fname, 0x00, sizeof(cassette_fname));
ui_sb_update_icon_state(SB_CASSETTE, 1);
media_menu_update_cassette();
ui_sb_update_tip(SB_CASSETTE);
config_save();
}
void
cartridge_mount(uint8_t id, char *fn, uint8_t wp)
{
cart_close(id);
cart_load(id, fn);
ui_sb_update_icon_state(SB_CARTRIDGE | id, strlen(cart_fns[id]) ? 0 : 1);
media_menu_update_cartridge(id);
ui_sb_update_tip(SB_CARTRIDGE | id);
config_save();
}
void
cartridge_eject(uint8_t id)
{
cart_close(id);
ui_sb_update_icon_state(SB_CARTRIDGE | id, 1);
media_menu_update_cartridge(id);
ui_sb_update_tip(SB_CARTRIDGE | id);
config_save();
}
void
floppy_mount(uint8_t id, char *fn, uint8_t wp)
{
@@ -53,6 +108,7 @@ floppy_mount(uint8_t id, char *fn, uint8_t wp)
config_save();
}
void
floppy_eject(uint8_t id)
{

View File

@@ -114,89 +114,92 @@ keyboard_handle(PRAWINPUT raw)
static int recv_lalt = 0, recv_ralt = 0, recv_tab = 0;
RAWKEYBOARD rawKB = raw->data.keyboard;
scancode = rawKB.MakeCode;
scancode = rawKB.MakeCode;
/* If it's not a scan code that starts with 0xE1 */
if (!(rawKB.Flags & RI_KEY_E1)) {
if (rawKB.Flags & RI_KEY_E0)
scancode |= 0x100;
if (kbd_req_capture && !mouse_capture && !video_fullscreen)
return;
/* Translate the scan code to 9-bit */
scancode = convert_scan_code(scancode);
/* If it's not a scan code that starts with 0xE1 */
if (!(rawKB.Flags & RI_KEY_E1)) {
if (rawKB.Flags & RI_KEY_E0)
scancode |= 0x100;
/* Remap it according to the list from the Registry */
if (scancode != scancode_map[scancode])
pclog("Scan code remap: %03X -> %03X\n", scancode, scancode);
scancode = scancode_map[scancode];
/* Translate the scan code to 9-bit */
scancode = convert_scan_code(scancode);
/* If it's not 0xFFFF, send it to the emulated
keyboard.
We use scan code 0xFFFF to mean a mapping that
has a prefix other than E0 and that is not E1 1D,
which is, for our purposes, invalid. */
if ((scancode == 0x00F) &&
!(rawKB.Flags & RI_KEY_BREAK) &&
(recv_lalt || recv_ralt) &&
!mouse_capture) {
/* We received a TAB while ALT was pressed, while the mouse
is not captured, suppress the TAB and send an ALT key up. */
if (recv_lalt) {
keyboard_input(0, 0x038);
/* Extra key press and release so the guest is not stuck in the
menu bar. */
keyboard_input(1, 0x038);
keyboard_input(0, 0x038);
recv_lalt = 0;
}
if (recv_ralt) {
keyboard_input(0, 0x138);
/* Extra key press and release so the guest is not stuck in the
menu bar. */
keyboard_input(1, 0x138);
keyboard_input(0, 0x138);
recv_ralt = 0;
}
} else if (((scancode == 0x038) || (scancode == 0x138)) &&
!(rawKB.Flags & RI_KEY_BREAK) &&
recv_tab &&
!mouse_capture) {
/* We received an ALT while TAB was pressed, while the mouse
is not captured, suppress the ALT and send a TAB key up. */
keyboard_input(0, 0x00F);
recv_tab = 0;
} else {
switch(scancode) {
case 0x00F:
recv_tab = !(rawKB.Flags & RI_KEY_BREAK);
break;
case 0x038:
recv_lalt = !(rawKB.Flags & RI_KEY_BREAK);
break;
case 0x138:
recv_ralt = !(rawKB.Flags & RI_KEY_BREAK);
break;
}
/* Remap it according to the list from the Registry */
if (scancode != scancode_map[scancode])
pclog("Scan code remap: %03X -> %03X\n", scancode, scancode);
scancode = scancode_map[scancode];
/* Translate right CTRL to left ALT if the user has so
chosen. */
if ((scancode == 0x11D) && rctrl_is_lalt)
scancode = 0x038;
/* Normal scan code pass through, pass it through as is if
it's not an invalid scan code. */
if (scancode != 0xFFFF)
keyboard_input(!(rawKB.Flags & RI_KEY_BREAK), scancode);
/* If it's not 0xFFFF, send it to the emulated
keyboard.
We use scan code 0xFFFF to mean a mapping that
has a prefix other than E0 and that is not E1 1D,
which is, for our purposes, invalid. */
if ((scancode == 0x00F) &&
!(rawKB.Flags & RI_KEY_BREAK) &&
(recv_lalt || recv_ralt) &&
!mouse_capture) {
/* We received a TAB while ALT was pressed, while the mouse
is not captured, suppress the TAB and send an ALT key up. */
if (recv_lalt) {
keyboard_input(0, 0x038);
/* Extra key press and release so the guest is not stuck in the
menu bar. */
keyboard_input(1, 0x038);
keyboard_input(0, 0x038);
recv_lalt = 0;
}
if (recv_ralt) {
keyboard_input(0, 0x138);
/* Extra key press and release so the guest is not stuck in the
menu bar. */
keyboard_input(1, 0x138);
keyboard_input(0, 0x138);
recv_ralt = 0;
}
} else if (((scancode == 0x038) || (scancode == 0x138)) &&
!(rawKB.Flags & RI_KEY_BREAK) &&
recv_tab &&
!mouse_capture) {
/* We received an ALT while TAB was pressed, while the mouse
is not captured, suppress the ALT and send a TAB key up. */
keyboard_input(0, 0x00F);
recv_tab = 0;
} else {
if (rawKB.MakeCode == 0x1D) {
scancode = scancode_map[0x100]; /* Translate E1 1D to 0x100 (which would
otherwise be E0 00 but that is invalid
anyway).
Also, take a potential mapping into
account. */
} else
scancode = 0xFFFF;
switch(scancode) {
case 0x00F:
recv_tab = !(rawKB.Flags & RI_KEY_BREAK);
break;
case 0x038:
recv_lalt = !(rawKB.Flags & RI_KEY_BREAK);
break;
case 0x138:
recv_ralt = !(rawKB.Flags & RI_KEY_BREAK);
break;
}
/* Translate right CTRL to left ALT if the user has so
chosen. */
if ((scancode == 0x11D) && rctrl_is_lalt)
scancode = 0x038;
/* Normal scan code pass through, pass it through as is if
it's not an invalid scan code. */
if (scancode != 0xFFFF)
keyboard_input(!(rawKB.Flags & RI_KEY_BREAK), scancode);
}
} else {
if (rawKB.MakeCode == 0x1D) {
scancode = scancode_map[0x100]; /* Translate E1 1D to 0x100 (which would
otherwise be E0 00 but that is invalid
anyway).
Also, take a potential mapping into
account. */
} else
scancode = 0xFFFF;
if (scancode != 0xFFFF)
keyboard_input(!(rawKB.Flags & RI_KEY_BREAK), scancode);
}
}

View File

@@ -8,6 +8,8 @@
#include <86box/config.h>
#include <86box/device.h>
#include <86box/timer.h>
#include <86box/cassette.h>
#include <86box/cartridge.h>
#include <86box/fdd.h>
#include <86box/fdd_86f.h>
#include <86box/hdc.h>
@@ -22,18 +24,23 @@
#include <86box/zip.h>
#include <86box/win.h>
#define MACHINE_HAS_IDE (machines[machine].flags & MACHINE_IDE_QUAD)
#define MACHINE_HAS_IDE (machines[machine].flags & MACHINE_IDE_QUAD)
#define MACHINE_HAS_SCSI (machines[machine].flags & MACHINE_SCSI_DUAL)
#define FDD_FIRST 0
#define CDROM_FIRST FDD_FIRST + FDD_NUM
#define ZIP_FIRST CDROM_FIRST + CDROM_NUM
#define MO_FIRST ZIP_FIRST + ZIP_NUM
#define CASSETTE_FIRST 0
#define CARTRIDGE_FIRST CASSETTE_FIRST + 1
#define FDD_FIRST CARTRIDGE_FIRST + 2
#define CDROM_FIRST FDD_FIRST + FDD_NUM
#define ZIP_FIRST CDROM_FIRST + CDROM_NUM
#define MO_FIRST ZIP_FIRST + ZIP_NUM
static HMENU media_menu, stbar_menu;
static HMENU menus[FDD_NUM + CDROM_NUM + ZIP_NUM + MO_NUM];
static HMENU menus[1 + 2 + FDD_NUM + CDROM_NUM + ZIP_NUM + MO_NUM];
static char index_map[255];
static void
media_menu_set_ids(HMENU hMenu, int id)
{
@@ -51,6 +58,7 @@ media_menu_set_ids(HMENU hMenu, int id)
}
}
/* Loads the submenu from resource by name */
static HMENU
media_menu_load_resource(wchar_t *lpName)
@@ -67,6 +75,51 @@ media_menu_load_resource(wchar_t *lpName)
return actual;
}
static void
media_menu_set_name_cassette(void)
{
wchar_t name[512], fn[512];
MENUITEMINFO mii = { 0 };
if (strlen(cassette_fname) == 0)
_swprintf(name, plat_get_string(IDS_2148), plat_get_string(IDS_2057));
else {
mbstoc16s(fn, cassette_fname, sizeof_w(fn));
_swprintf(name, plat_get_string(IDS_2148), fn);
}
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_STRING;
mii.dwTypeData = name;
SetMenuItemInfo(media_menu, (UINT_PTR)menus[CASSETTE_FIRST], FALSE, &mii);
}
static void
media_menu_set_name_cartridge(int drive)
{
wchar_t name[512], fn[512];
MENUITEMINFO mii = { 0 };
if (strlen(cart_fns[drive]) == 0) {
_swprintf(name, plat_get_string(IDS_2150),
drive + 1, plat_get_string(IDS_2057));
} else {
mbstoc16s(fn, cart_fns[drive], sizeof_w(fn));
_swprintf(name, plat_get_string(IDS_2150),
drive + 1, fn);
}
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_STRING;
mii.dwTypeData = name;
SetMenuItemInfo(media_menu, (UINT_PTR)menus[CARTRIDGE_FIRST + drive], FALSE, &mii);
}
static void
media_menu_set_name_floppy(int drive)
{
@@ -91,6 +144,7 @@ media_menu_set_name_floppy(int drive)
SetMenuItemInfo(media_menu, (UINT_PTR)menus[FDD_FIRST + drive], FALSE, &mii);
}
static void
media_menu_set_name_cdrom(int drive)
{
@@ -121,6 +175,7 @@ media_menu_set_name_cdrom(int drive)
SetMenuItemInfo(media_menu, (UINT_PTR)menus[CDROM_FIRST + drive], FALSE, &mii);
}
static void
media_menu_set_name_zip(int drive)
{
@@ -150,6 +205,7 @@ media_menu_set_name_zip(int drive)
SetMenuItemInfo(media_menu, (UINT_PTR)menus[ZIP_FIRST + drive], FALSE, &mii);
}
static void
media_menu_set_name_mo(int drive)
{
@@ -177,6 +233,53 @@ media_menu_set_name_mo(int drive)
SetMenuItemInfo(media_menu, (UINT_PTR)menus[MO_FIRST + drive], FALSE, &mii);
}
void
media_menu_update_cassette(void)
{
int i = CASSETTE_FIRST;
if (strlen(cassette_fname) == 0) {
EnableMenuItem(menus[i], IDM_CASSETTE_EJECT, MF_BYCOMMAND | MF_GRAYED);
EnableMenuItem(menus[i], IDM_CASSETTE_RECORD, MF_BYCOMMAND | MF_GRAYED);
EnableMenuItem(menus[i], IDM_CASSETTE_PLAY, MF_BYCOMMAND | MF_GRAYED);
CheckMenuItem(menus[i], IDM_CASSETTE_RECORD, MF_BYCOMMAND | MF_UNCHECKED);
CheckMenuItem(menus[i], IDM_CASSETTE_PLAY, MF_BYCOMMAND | MF_UNCHECKED);
EnableMenuItem(menus[i], IDM_CASSETTE_REWIND, MF_BYCOMMAND | MF_GRAYED);
EnableMenuItem(menus[i], IDM_CASSETTE_FAST_FORWARD, MF_BYCOMMAND | MF_GRAYED);
} else {
EnableMenuItem(menus[i], IDM_CASSETTE_EJECT, MF_BYCOMMAND | MF_ENABLED);
EnableMenuItem(menus[i], IDM_CASSETTE_RECORD, MF_BYCOMMAND | MF_ENABLED);
EnableMenuItem(menus[i], IDM_CASSETTE_PLAY, MF_BYCOMMAND | MF_ENABLED);
if (strcmp(cassette_mode, "save") == 0) {
CheckMenuItem(menus[i], IDM_CASSETTE_RECORD, MF_BYCOMMAND | MF_CHECKED);
CheckMenuItem(menus[i], IDM_CASSETTE_PLAY, MF_BYCOMMAND | MF_UNCHECKED);
} else {
CheckMenuItem(menus[i], IDM_CASSETTE_RECORD, MF_BYCOMMAND | MF_UNCHECKED);
CheckMenuItem(menus[i], IDM_CASSETTE_PLAY, MF_BYCOMMAND | MF_CHECKED);
}
EnableMenuItem(menus[i], IDM_CASSETTE_REWIND, MF_BYCOMMAND | MF_ENABLED);
EnableMenuItem(menus[i], IDM_CASSETTE_FAST_FORWARD, MF_BYCOMMAND | MF_ENABLED);
}
media_menu_set_name_cassette();
}
void
media_menu_update_cartridge(int id)
{
int i = CARTRIDGE_FIRST + id;
if (strlen(cart_fns[id]) == 0)
EnableMenuItem(menus[i], IDM_CARTRIDGE_EJECT | id, MF_BYCOMMAND | MF_GRAYED);
else
EnableMenuItem(menus[i], IDM_CARTRIDGE_EJECT | id, MF_BYCOMMAND | MF_ENABLED);
media_menu_set_name_cartridge(id);
}
void
media_menu_update_floppy(int id)
{
@@ -193,6 +296,7 @@ media_menu_update_floppy(int id)
media_menu_set_name_floppy(id);
}
void
media_menu_update_cdrom(int id)
{
@@ -220,6 +324,7 @@ media_menu_update_cdrom(int id)
media_menu_set_name_cdrom(id);
}
void
media_menu_update_zip(int id)
{
@@ -238,6 +343,7 @@ media_menu_update_zip(int id)
media_menu_set_name_zip(id);
}
void
media_menu_update_mo(int id)
{
@@ -256,6 +362,7 @@ media_menu_update_mo(int id)
media_menu_set_name_mo(id);
}
static void
media_menu_load_submenus()
{
@@ -263,6 +370,14 @@ media_menu_load_submenus()
int curr = 0;
menus[curr] = media_menu_load_resource(CASSETTE_SUBMENU_NAME);
media_menu_set_ids(menus[curr++], 0);
for(int i = 0; i < 2; i++) {
menus[curr] = media_menu_load_resource(CARTRIDGE_SUBMENU_NAME);
media_menu_set_ids(menus[curr++], i);
}
for(int i = 0; i < FDD_NUM; i++) {
menus[curr] = media_menu_load_resource(FLOPPY_SUBMENU_NAME);
media_menu_set_ids(menus[curr++], i);
@@ -284,42 +399,60 @@ media_menu_load_submenus()
}
}
static inline int
is_valid_cartridge(void)
{
return ((machines[machine].flags & MACHINE_CARTRIDGE) ? 1 : 0);
}
static inline int
is_valid_fdd(int i)
{
return fdd_get_type(i) != 0;
}
static inline int
is_valid_cdrom(int i)
{
if ((cdrom[i].bus_type == CDROM_BUS_ATAPI) && !MACHINE_HAS_IDE && memcmp(hdc_get_internal_name(hdc_current), "ide", 3))
return 0;
if ((cdrom[i].bus_type == CDROM_BUS_SCSI) && !MACHINE_HAS_SCSI && (scsi_card_current == 0))
if ((cdrom[i].bus_type == CDROM_BUS_SCSI) && !MACHINE_HAS_SCSI &&
(scsi_card_current[0] == 0) && (scsi_card_current[1] == 0) &&
(scsi_card_current[2] == 0) && (scsi_card_current[3] == 0))
return 0;
return cdrom[i].bus_type != 0;
}
static inline int
is_valid_zip(int i)
{
if ((zip_drives[i].bus_type == ZIP_BUS_ATAPI) && !MACHINE_HAS_IDE && memcmp(hdc_get_internal_name(hdc_current), "ide", 3))
return 0;
if ((zip_drives[i].bus_type == ZIP_BUS_SCSI) && !MACHINE_HAS_SCSI && (scsi_card_current == 0))
if ((zip_drives[i].bus_type == ZIP_BUS_SCSI) && !MACHINE_HAS_SCSI &&
(scsi_card_current[0] == 0) && (scsi_card_current[1] == 0) &&
(scsi_card_current[2] == 0) && (scsi_card_current[3] == 0))
return 0;
return zip_drives[i].bus_type != 0;
}
static inline int
is_valid_mo(int i)
{
if ((mo_drives[i].bus_type == MO_BUS_ATAPI) && !MACHINE_HAS_IDE && memcmp(hdc_get_internal_name(hdc_current), "ide", 3))
return 0;
if ((mo_drives[i].bus_type == MO_BUS_SCSI) && !MACHINE_HAS_SCSI && (scsi_card_current == 0))
if ((mo_drives[i].bus_type == MO_BUS_SCSI) && !MACHINE_HAS_SCSI &&
(scsi_card_current[0] == 0) && (scsi_card_current[1] == 0) &&
(scsi_card_current[2] == 0) && (scsi_card_current[3] == 0))
return 0;
return mo_drives[i].bus_type != 0;
}
void
media_menu_reset()
{
@@ -332,6 +465,20 @@ media_menu_reset()
/* Add new ones. */
int curr = 0;
if(cassette_enable) {
AppendMenu(media_menu, MF_POPUP | MF_STRING, (UINT_PTR)menus[curr], L"Test");
media_menu_update_cassette();
}
curr++;
for(int i = 0; i < 2; i++) {
if(is_valid_cartridge()) {
AppendMenu(media_menu, MF_POPUP | MF_STRING, (UINT_PTR)menus[curr], L"Test");
media_menu_update_cartridge(i);
}
curr++;
}
for(int i = 0; i < FDD_NUM; i++) {
if(is_valid_fdd(i)) {
AppendMenu(media_menu, MF_POPUP | MF_STRING, (UINT_PTR)menus[curr], L"Test");
@@ -365,6 +512,7 @@ media_menu_reset()
}
}
/* Initializes the Media menu in the main menu bar. */
static void
media_menu_main_init()
@@ -388,6 +536,7 @@ media_menu_main_init()
free(lpMenuName);
}
void
media_menu_init()
{
@@ -405,6 +554,7 @@ media_menu_init()
media_menu_reset();
}
int
media_menu_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
@@ -413,6 +563,60 @@ media_menu_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
id = LOWORD(wParam) & 0x00ff;
switch (LOWORD(wParam) & 0xff00) {
case IDM_CASSETTE_IMAGE_NEW:
ret = file_dlg_st(hwnd, IDS_2149, "", NULL, 1);
if (! ret) {
if (strlen(openfilestring) == 0)
cassette_mount(NULL, wp);
else
cassette_mount(openfilestring, wp);
}
break;
case IDM_CASSETTE_RECORD:
pc_cas_set_mode(cassette, 1);
CheckMenuItem(menus[CASSETTE_FIRST], IDM_CASSETTE_RECORD, MF_BYCOMMAND | MF_CHECKED);
CheckMenuItem(menus[CASSETTE_FIRST], IDM_CASSETTE_PLAY, MF_BYCOMMAND | MF_UNCHECKED);
break;
case IDM_CASSETTE_PLAY:
pc_cas_set_mode(cassette, 0);
CheckMenuItem(menus[CASSETTE_FIRST], IDM_CASSETTE_RECORD, MF_BYCOMMAND | MF_UNCHECKED);
CheckMenuItem(menus[CASSETTE_FIRST], IDM_CASSETTE_PLAY, MF_BYCOMMAND | MF_CHECKED);
break;
case IDM_CASSETTE_REWIND:
pc_cas_rewind(cassette);
break;
case IDM_CASSETTE_FAST_FORWARD:
pc_cas_append(cassette);
break;
case IDM_CASSETTE_IMAGE_EXISTING_WP:
wp = 1;
/* FALLTHROUGH */
case IDM_CASSETTE_IMAGE_EXISTING:
ret = file_dlg_st(hwnd, IDS_2149, cassette_fname, NULL, 0);
if (! ret) {
if (strlen(openfilestring) == 0)
cassette_mount(NULL, wp);
else
cassette_mount(openfilestring, wp);
}
break;
case IDM_CASSETTE_EJECT:
cassette_eject();
break;
case IDM_CARTRIDGE_IMAGE:
ret = file_dlg_st(hwnd, IDS_2151, cart_fns[id], NULL, 0);
if (! ret)
cartridge_mount(id, openfilestring, wp);
break;
case IDM_CARTRIDGE_EJECT:
cartridge_eject(id);
break;
case IDM_FLOPPY_IMAGE_NEW:
NewFloppyDialogCreate(hwnd, id, 0);
break;
@@ -422,9 +626,8 @@ media_menu_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
/* FALLTHROUGH */
case IDM_FLOPPY_IMAGE_EXISTING:
ret = file_dlg_st(hwnd, IDS_2109, floppyfns[id], NULL, 0);
if (! ret) {
if (! ret)
floppy_mount(id, openfilestring, wp);
}
break;
case IDM_FLOPPY_EJECT:
@@ -512,24 +715,42 @@ media_menu_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
return(1);
}
HMENU
media_menu_get_cassette(void)
{
return menus[CASSETTE_FIRST];
}
HMENU
media_menu_get_cartridge(int id)
{
return menus[CARTRIDGE_FIRST + id];
}
HMENU
media_menu_get_floppy(int id)
{
return menus[FDD_FIRST + id];
}
HMENU
media_menu_get_cdrom(int id)
{
return menus[CDROM_FIRST + id];
}
HMENU
media_menu_get_zip(int id)
{
return menus[ZIP_FIRST + id];
}
HMENU
media_menu_get_mo(int id)
{

View File

@@ -38,6 +38,7 @@
#include <86box/rom.h>
#include <86box/device.h>
#include <86box/timer.h>
#include <86box/cassette.h>
#include <86box/nvr.h>
#include <86box/machine.h>
#include <86box/gameport.h>
@@ -103,7 +104,8 @@ static int temp_lpt_devices[3];
static int temp_serial[4], temp_lpt[3];
/* Other peripherals category */
static int temp_fdc_card, temp_hdc, temp_scsi_card, temp_ide_ter, temp_ide_qua;
static int temp_fdc_card, temp_hdc, temp_ide_ter, temp_ide_qua, temp_cassette;
static int temp_scsi_card[SCSI_BUS_MAX];
static int temp_bugger;
static int temp_postcard;
static int temp_isartc;
@@ -136,7 +138,7 @@ static int settings_list_to_midi[20], settings_list_to_midi_in[20];
static int settings_list_to_hdc[20];
static int max_spt = 63, max_hpc = 255, max_tracks = 266305;
static uint64_t mfm_tracking, esdi_tracking, xta_tracking, ide_tracking, scsi_tracking[2];
static uint64_t mfm_tracking, esdi_tracking, xta_tracking, ide_tracking, scsi_tracking[8];
static uint64_t size;
static int hd_listview_items, hdc_id_to_listview_index[HDD_NUM];
static int no_update = 0, existing = 0, chs_enabled = 0;
@@ -368,22 +370,17 @@ win_settings_init(void)
for (i = 0; i < 4; i++)
temp_serial[i] = serial_enabled[i];
/* Other peripherals category */
temp_scsi_card = scsi_card_current;
/* Storage devices category */
for (i = 0; i < SCSI_BUS_MAX; i++)
temp_scsi_card[i] = scsi_card_current[i];
temp_fdc_card = fdc_type;
temp_hdc = hdc_current;
temp_ide_ter = ide_ter_enabled;
temp_ide_qua = ide_qua_enabled;
temp_bugger = bugger_enabled;
temp_postcard = postcard_enabled;
temp_isartc = isartc_type;
/* ISA memory boards. */
for (i = 0; i < ISAMEM_MAX; i++)
temp_isamem[i] = isamem_type[i];
temp_cassette = cassette_enable;
mfm_tracking = xta_tracking = esdi_tracking = ide_tracking = 0;
for (i = 0; i < 2; i++)
for (i = 0; i < 8; i++)
scsi_tracking[i] = 0;
/* Hard disks category */
@@ -431,6 +428,15 @@ win_settings_init(void)
scsi_tracking[mo_drives[i].scsi_device_id >> 3] |= (1 << ((mo_drives[i].scsi_device_id & 0x07) << 3));
}
/* Other peripherals category */
temp_bugger = bugger_enabled;
temp_postcard = postcard_enabled;
temp_isartc = isartc_type;
/* ISA memory boards. */
for (i = 0; i < ISAMEM_MAX; i++)
temp_isamem[i] = isamem_type[i];
temp_deviceconfig = 0;
}
@@ -484,19 +490,14 @@ win_settings_changed(void)
for (j = 0; j < 4; j++)
i = i || (temp_serial[j] != serial_enabled[j]);
/* Peripherals category */
i = i || (scsi_card_current != temp_scsi_card);
/* Storage devices category */
for (j = 0; j < SCSI_BUS_MAX; j++)
i = i || (temp_scsi_card[j] != scsi_card_current[j]);
i = i || (fdc_type != temp_fdc_card);
i = i || (hdc_current != temp_hdc);
i = i || (temp_ide_ter != ide_ter_enabled);
i = i || (temp_ide_qua != ide_qua_enabled);
i = i || (temp_bugger != bugger_enabled);
i = i || (temp_postcard != postcard_enabled);
i = i || (temp_isartc != isartc_type);
/* ISA memory boards. */
for (j = 0; j < ISAMEM_MAX; j++)
i = i || (temp_isamem[j] != isamem_type[j]);
i = i || (temp_cassette != cassette_enable);
/* Hard disks category */
i = i || memcmp(hdd, temp_hdd, HDD_NUM * sizeof(hard_disk_t));
@@ -513,6 +514,15 @@ win_settings_changed(void)
i = i || memcmp(zip_drives, temp_zip_drives, ZIP_NUM * sizeof(zip_drive_t));
i = i || memcmp(mo_drives, temp_mo_drives, MO_NUM * sizeof(mo_drive_t));
/* Other peripherals category */
i = i || (temp_bugger != bugger_enabled);
i = i || (temp_postcard != postcard_enabled);
i = i || (temp_isartc != isartc_type);
/* ISA memory boards. */
for (j = 0; j < ISAMEM_MAX; j++)
i = i || (temp_isamem[j] != isamem_type[j]);
i = i || !!temp_deviceconfig;
return i;
@@ -571,19 +581,14 @@ win_settings_save(void)
for (i = 0; i < 4; i++)
serial_enabled[i] = temp_serial[i];
/* Peripherals category */
scsi_card_current = temp_scsi_card;
/* Storage devices category */
for (i = 0; i < SCSI_BUS_MAX; i++)
scsi_card_current[i] = temp_scsi_card[i];
hdc_current = temp_hdc;
fdc_type = temp_fdc_card;
ide_ter_enabled = temp_ide_ter;
ide_qua_enabled = temp_ide_qua;
bugger_enabled = temp_bugger;
postcard_enabled = temp_postcard;
isartc_type = temp_isartc;
/* ISA memory boards. */
for (i = 0; i < ISAMEM_MAX; i++)
isamem_type[i] = temp_isamem[i];
cassette_enable = temp_cassette;
/* Hard disks category */
memcpy(hdd, temp_hdd, HDD_NUM * sizeof(hard_disk_t));
@@ -620,6 +625,15 @@ win_settings_save(void)
mo_drives[i].priv = NULL;
}
/* Other peripherals category */
bugger_enabled = temp_bugger;
postcard_enabled = temp_postcard;
isartc_type = temp_isartc;
/* ISA memory boards. */
for (i = 0; i < ISAMEM_MAX; i++)
isamem_type[i] = temp_isamem[i];
/* Mark configuration as changed. */
config_changed = 2;
@@ -1058,6 +1072,7 @@ static BOOL CALLBACK
win_settings_video_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
{
int c = 0, d = 0;
int e;
switch (message) {
case WM_INITDIALOG:
@@ -1095,7 +1110,8 @@ win_settings_video_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
}
settings_enable_window(hdlg, IDC_COMBO_VIDEO, !(machines[temp_machine].flags & MACHINE_VIDEO_ONLY));
settings_enable_window(hdlg, IDC_CONFIGURE_VID, video_card_has_config(temp_gfxcard));
e = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_VIDEO)];
settings_enable_window(hdlg, IDC_CONFIGURE_VID, video_card_has_config(e));
settings_enable_window(hdlg, IDC_CHECK_VOODOO, (machines[temp_machine].flags & MACHINE_BUS_PCI));
settings_set_check(hdlg, IDC_CHECK_VOODOO, temp_voodoo);
settings_enable_window(hdlg, IDC_BUTTON_VOODOO, (machines[temp_machine].flags & MACHINE_BUS_PCI) && temp_voodoo);
@@ -1532,7 +1548,7 @@ static BOOL CALLBACK
win_settings_storage_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
{
int c, d;
int is_at;
int e, is_at;
LPTSTR lptsTemp;
char *stransi;
const device_t *scsi_dev, *fdc_dev;
@@ -1613,7 +1629,8 @@ win_settings_storage_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
/*SCSI config*/
c = d = 0;
settings_reset_content(hdlg, IDC_COMBO_SCSI);
for (e = 0; e < SCSI_BUS_MAX; e++)
settings_reset_content(hdlg, IDC_COMBO_SCSI_1 + e);
while (1) {
generate_device_name(scsi_card_getdevice(c), scsi_card_get_internal_name(c), 1);
@@ -1624,13 +1641,17 @@ win_settings_storage_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
scsi_dev = scsi_card_getdevice(c);
if (device_is_valid(scsi_dev, machines[temp_machine].flags)) {
if (c == 0)
settings_add_string(hdlg, IDC_COMBO_SCSI, win_get_string(IDS_2103));
else
settings_add_string(hdlg, IDC_COMBO_SCSI, (LPARAM) device_name);
for (e = 0; e < SCSI_BUS_MAX; e++) {
if (c == 0)
settings_add_string(hdlg, IDC_COMBO_SCSI_1 + e, win_get_string(IDS_2103));
else
settings_add_string(hdlg, IDC_COMBO_SCSI_1 + e, (LPARAM) device_name);
if ((c == 0) || (c == temp_scsi_card[e]))
settings_set_cur_sel(hdlg, IDC_COMBO_SCSI_1 + e, d);
}
settings_list_to_device[0][d] = c;
if ((c == 0) || (c == temp_scsi_card))
settings_set_cur_sel(hdlg, IDC_COMBO_SCSI, d);
d++;
}
}
@@ -1638,8 +1659,10 @@ win_settings_storage_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
c++;
}
settings_enable_window(hdlg, IDC_COMBO_SCSI, d);
settings_enable_window(hdlg, IDC_CONFIGURE_SCSI, scsi_card_has_config(temp_scsi_card));
for (c = 0; c < SCSI_BUS_MAX; c++) {
settings_enable_window(hdlg, IDC_COMBO_SCSI_1 + c, d);
settings_enable_window(hdlg, IDC_CONFIGURE_SCSI_1 + c, scsi_card_has_config(temp_scsi_card[c]));
}
is_at = IS_AT(temp_machine);
settings_enable_window(hdlg, IDC_CHECK_IDE_TER, is_at);
settings_enable_window(hdlg, IDC_BUTTON_IDE_TER, is_at && temp_ide_ter);
@@ -1647,6 +1670,7 @@ win_settings_storage_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
settings_enable_window(hdlg, IDC_BUTTON_IDE_QUA, is_at && temp_ide_qua);
settings_set_check(hdlg, IDC_CHECK_IDE_TER, temp_ide_ter);
settings_set_check(hdlg, IDC_CHECK_IDE_QUA, temp_ide_qua);
settings_set_check(hdlg, IDC_CHECK_CASSETTE, temp_cassette);
free(stransi);
free(lptsTemp);
@@ -1675,14 +1699,16 @@ win_settings_storage_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
settings_enable_window(hdlg, IDC_CONFIGURE_HDC, hdc_has_config(temp_hdc));
break;
case IDC_CONFIGURE_SCSI:
temp_scsi_card = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_SCSI)];
temp_deviceconfig |= deviceconfig_open(hdlg, (void *)scsi_card_getdevice(temp_scsi_card));
case IDC_CONFIGURE_SCSI_1 ... IDC_CONFIGURE_SCSI_4:
c = LOWORD(wParam) - IDC_CONFIGURE_SCSI_1;
temp_scsi_card[c] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_SCSI_1 + c)];
temp_deviceconfig |= deviceconfig_inst_open(hdlg, (void *)scsi_card_getdevice(temp_scsi_card[c]), c + 1);
break;
case IDC_COMBO_SCSI:
temp_scsi_card = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_SCSI)];
settings_enable_window(hdlg, IDC_CONFIGURE_SCSI, scsi_card_has_config(temp_scsi_card));
case IDC_COMBO_SCSI_1 ... IDC_COMBO_SCSI_4:
c = LOWORD(wParam) - IDC_COMBO_SCSI_1;
temp_scsi_card[c] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_SCSI_1 + c)];
settings_enable_window(hdlg, IDC_CONFIGURE_SCSI_1 + c, scsi_card_has_config(temp_scsi_card[c]));
break;
case IDC_CHECK_IDE_TER:
@@ -1708,9 +1734,11 @@ win_settings_storage_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
case WM_SAVESETTINGS:
temp_hdc = settings_list_to_hdc[settings_get_cur_sel(hdlg, IDC_COMBO_HDC)];
temp_fdc_card = settings_list_to_fdc[settings_get_cur_sel(hdlg, IDC_COMBO_FDC)];
temp_scsi_card = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_SCSI)];
for (c = 0; c < SCSI_BUS_MAX; c++)
temp_scsi_card[c] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_SCSI_1 + c)];
temp_ide_ter = settings_get_check(hdlg, IDC_CHECK_IDE_TER);
temp_ide_qua = settings_get_check(hdlg, IDC_CHECK_IDE_QUA);
temp_cassette = settings_get_check(hdlg, IDC_CHECK_CASSETTE);
default:
return FALSE;
@@ -1898,8 +1926,8 @@ add_locations(HWND hdlg)
settings_add_string(hdlg, IDC_COMBO_HD_CHANNEL, (LPARAM) lptsTemp);
}
for (i = 0; i < 16; i++) {
wsprintf(lptsTemp, plat_get_string(IDS_4098), i);
for (i = 0; i < 64; i++) {
wsprintf(lptsTemp, plat_get_string(IDS_4135), i >> 4, i & 15);
settings_add_string(hdlg, IDC_COMBO_HD_ID, (LPARAM) lptsTemp);
}
@@ -1945,7 +1973,7 @@ next_free_scsi_id(uint8_t *id)
{
int64_t i;
for (i = 0; i < 16; i++) {
for (i = 0; i < 64; i++) {
if (!(scsi_tracking[i >> 3] & (0xffLL << ((i & 0x07) << 3LL)))) {
*id = i;
return;
@@ -2128,7 +2156,7 @@ win_settings_hard_disks_update_item(HWND hdlg, int i, int column)
wsprintf(szText, plat_get_string(IDS_4612), temp_hdd[i].ide_channel >> 1, temp_hdd[i].ide_channel & 1);
break;
case HDD_BUS_SCSI:
wsprintf(szText, plat_get_string(IDS_4613), temp_hdd[i].scsi_id);
wsprintf(szText, plat_get_string(IDS_4613), temp_hdd[i].scsi_id >> 4, temp_hdd[i].scsi_id >> 4 & 15);
break;
}
lvI.pszText = szText;
@@ -2202,7 +2230,7 @@ win_settings_hard_disks_recalc_list(HWND hdlg)
wsprintf(szText, plat_get_string(IDS_4612), temp_hdd[i].ide_channel >> 1, temp_hdd[i].ide_channel & 1);
break;
case HDD_BUS_SCSI:
wsprintf(szText, plat_get_string(IDS_4613), temp_hdd[i].scsi_id);
wsprintf(szText, plat_get_string(IDS_4613), temp_hdd[i].scsi_id >> 4, temp_hdd[i].scsi_id >> 4 & 15);
break;
}
lvI.pszText = szText;
@@ -3577,7 +3605,7 @@ win_settings_cdrom_drives_recalc_list(HWND hdlg)
lvI.iImage = 1;
break;
case CDROM_BUS_SCSI:
wsprintf(szText, plat_get_string(fsid), temp_cdrom[i].scsi_device_id);
wsprintf(szText, plat_get_string(fsid), temp_cdrom[i].scsi_device_id >> 4, temp_cdrom[i].scsi_device_id & 15);
lvI.pszText = szText;
lvI.iImage = 1;
break;
@@ -3634,7 +3662,7 @@ win_settings_mo_drives_recalc_list(HWND hdlg)
lvI.iImage = 1;
break;
case MO_BUS_SCSI:
wsprintf(szText, plat_get_string(fsid), temp_mo_drives[i].scsi_device_id);
wsprintf(szText, plat_get_string(fsid), temp_mo_drives[i].scsi_device_id >> 4, temp_mo_drives[i].scsi_device_id & 15);
lvI.pszText = szText;
lvI.iImage = 1;
break;
@@ -3697,7 +3725,7 @@ win_settings_zip_drives_recalc_list(HWND hdlg)
lvI.iImage = 1;
break;
case ZIP_BUS_SCSI:
wsprintf(szText, plat_get_string(fsid), temp_zip_drives[i].scsi_device_id);
wsprintf(szText, plat_get_string(fsid), temp_zip_drives[i].scsi_device_id >> 4, temp_zip_drives[i].scsi_device_id & 15);
lvI.pszText = szText;
lvI.iImage = 1;
break;
@@ -4008,7 +4036,7 @@ win_settings_cdrom_drives_update_item(HWND hdlg, int i)
lvI.iImage = 1;
break;
case CDROM_BUS_SCSI:
wsprintf(szText, plat_get_string(fsid), temp_cdrom[i].scsi_device_id);
wsprintf(szText, plat_get_string(fsid), temp_cdrom[i].scsi_device_id >> 4, temp_cdrom[i].scsi_device_id & 15);
lvI.pszText = szText;
lvI.iImage = 1;
break;
@@ -4061,7 +4089,7 @@ win_settings_mo_drives_update_item(HWND hdlg, int i)
lvI.iImage = 1;
break;
case MO_BUS_SCSI:
wsprintf(szText, plat_get_string(fsid), temp_mo_drives[i].scsi_device_id);
wsprintf(szText, plat_get_string(fsid), temp_mo_drives[i].scsi_device_id >> 4, temp_mo_drives[i].scsi_device_id & 15);
lvI.pszText = szText;
lvI.iImage = 1;
break;
@@ -4119,7 +4147,7 @@ win_settings_zip_drives_update_item(HWND hdlg, int i)
lvI.iImage = 1;
break;
case ZIP_BUS_SCSI:
wsprintf(szText, plat_get_string(fsid), temp_zip_drives[i].scsi_device_id);
wsprintf(szText, plat_get_string(fsid), temp_zip_drives[i].scsi_device_id >> 4, temp_zip_drives[i].scsi_device_id & 15);
lvI.pszText = szText;
lvI.iImage = 1;
break;
@@ -4156,8 +4184,8 @@ cdrom_add_locations(HWND hdlg)
settings_add_string(hdlg, IDC_COMBO_CD_SPEED, (LPARAM) lptsTemp);
}
for (i = 0; i < 16; i++) {
wsprintf(lptsTemp, plat_get_string(IDS_4098), i);
for (i = 0; i < 64; i++) {
wsprintf(lptsTemp, plat_get_string(IDS_4135), i >> 4, i & 15);
settings_add_string(hdlg, IDC_COMBO_CD_ID, (LPARAM) lptsTemp);
}
@@ -4224,8 +4252,8 @@ mo_add_locations(HWND hdlg)
settings_add_string(hdlg, IDC_COMBO_MO_BUS, win_get_string(combo_id_to_string_id(i)));
}
for (i = 0; i < 16; i++) {
wsprintf(lptsTemp, plat_get_string(IDS_4098), i);
for (i = 0; i < 64; i++) {
wsprintf(lptsTemp, plat_get_string(IDS_4135), i >> 4, i & 15);
settings_add_string(hdlg, IDC_COMBO_MO_ID, (LPARAM) lptsTemp);
}
@@ -4303,8 +4331,8 @@ zip_add_locations(HWND hdlg)
settings_add_string(hdlg, IDC_COMBO_ZIP_BUS, win_get_string(combo_id_to_string_id(i)));
}
for (i = 0; i < 16; i++) {
wsprintf(lptsTemp, plat_get_string(IDS_4098), i);
for (i = 0; i < 64; i++) {
wsprintf(lptsTemp, plat_get_string(IDS_4135), i >> 4, i & 15);
settings_add_string(hdlg, IDC_COMBO_ZIP_ID, (LPARAM) lptsTemp);
}

View File

@@ -34,6 +34,8 @@
#include <86box/device.h>
#include <86box/machine.h>
#include <86box/timer.h>
#include <86box/cassette.h>
#include <86box/cartridge.h>
#include <86box/hdd.h>
#include <86box/hdc.h>
#include <86box/fdd.h>
@@ -177,6 +179,53 @@ ui_sb_update_icon_state(int tag, int state)
}
static void
StatusBarCreateCassetteTip(int part)
{
WCHAR tempTip[512];
WCHAR fn[512];
if (strlen(cassette_fname) == 0)
_swprintf(tempTip, plat_get_string(IDS_2148), plat_get_string(IDS_2057));
else {
mbstoc16s(fn, cassette_fname, sizeof_w(fn));
_swprintf(tempTip, plat_get_string(IDS_2148), fn);
}
if (sbTips[part] != NULL) {
free(sbTips[part]);
sbTips[part] = NULL;
}
sbTips[part] = (WCHAR *)malloc((wcslen(tempTip) << 1) + 2);
wcscpy(sbTips[part], tempTip);
}
static void
StatusBarCreateCartridgeTip(int part)
{
WCHAR tempTip[512];
WCHAR fn[512];
int drive = sb_part_meanings[part] & 0xf;
if (strlen(cart_fns[drive]) == 0) {
_swprintf(tempTip, plat_get_string(IDS_2150),
drive+1, plat_get_string(IDS_2057));
} else {
mbstoc16s(fn, cart_fns[drive], sizeof_w(fn));
_swprintf(tempTip, plat_get_string(IDS_2150),
drive+1, fn);
}
if (sbTips[part] != NULL) {
free(sbTips[part]);
sbTips[part] = NULL;
}
sbTips[part] = (WCHAR *)malloc((wcslen(tempTip) << 1) + 2);
wcscpy(sbTips[part], tempTip);
}
static void
StatusBarCreateFloppyTip(int part)
{
@@ -364,6 +413,14 @@ ui_sb_update_tip(int meaning)
if (part != 0xff) {
switch(meaning & 0xf0) {
case SB_CASSETTE:
StatusBarCreateCassetteTip(part);
break;
case SB_CARTRIDGE:
StatusBarCreateCartridgeTip(part);
break;
case SB_FLOPPY:
StatusBarCreateFloppyTip(part);
break;
@@ -440,7 +497,7 @@ void
ui_sb_update_panes(void)
{
int i, id;
int mfm_int, xta_int, esdi_int, ide_int, scsi_int;
int cart_int, mfm_int, xta_int, esdi_int, ide_int, scsi_int;
int edge = 0;
int c_mfm, c_esdi, c_xta;
int c_ide, c_scsi;
@@ -454,6 +511,7 @@ ui_sb_update_panes(void)
sb_ready = 0;
}
cart_int = (machines[machine].flags & MACHINE_CARTRIDGE) ? 1 : 0;
mfm_int = (machines[machine].flags & MACHINE_MFM) ? 1 : 0;
xta_int = (machines[machine].flags & MACHINE_XTA) ? 1 : 0;
esdi_int = (machines[machine].flags & MACHINE_ESDI) ? 1 : 0;
@@ -492,6 +550,10 @@ ui_sb_update_panes(void)
memset(sb_map, 0xff, sizeof(sb_map));
sb_parts = 0;
if (cassette_enable)
sb_parts++;
if (cart_int)
sb_parts += 2;
for (i=0; i<FDD_NUM; i++) {
if (fdd_get_type(i) != 0)
sb_parts++;
@@ -503,8 +565,9 @@ ui_sb_update_panes(void)
!ide_int && memcmp(hdc_name, "ide", 3))
continue;
if ((cdrom[i].bus_type == CDROM_BUS_SCSI) &&
!scsi_int && (scsi_card_current == 0))
if ((cdrom[i].bus_type == CDROM_BUS_SCSI) && !scsi_int &&
(scsi_card_current[0] == 0) && (scsi_card_current[1] == 0) &&
(scsi_card_current[2] == 0) && (scsi_card_current[3] == 0))
continue;
if (cdrom[i].bus_type != 0)
sb_parts++;
@@ -515,8 +578,9 @@ ui_sb_update_panes(void)
!ide_int && memcmp(hdc_name, "ide", 3))
continue;
if ((zip_drives[i].bus_type == ZIP_BUS_SCSI) &&
!scsi_int && (scsi_card_current == 0))
if ((zip_drives[i].bus_type == ZIP_BUS_SCSI) && !scsi_int &&
(scsi_card_current[0] == 0) && (scsi_card_current[1] == 0) &&
(scsi_card_current[2] == 0) && (scsi_card_current[3] == 0))
continue;
if (zip_drives[i].bus_type != 0)
sb_parts++;
@@ -527,8 +591,9 @@ ui_sb_update_panes(void)
!ide_int && memcmp(hdc_name, "ide", 3))
continue;
if ((mo_drives[i].bus_type == MO_BUS_SCSI) &&
!scsi_int && (scsi_card_current == 0))
if ((mo_drives[i].bus_type == MO_BUS_SCSI) && !scsi_int &&
(scsi_card_current[0] == 0) && (scsi_card_current[1] == 0) &&
(scsi_card_current[2] == 0) && (scsi_card_current[3] == 0))
continue;
if (mo_drives[i].bus_type != 0)
sb_parts++;
@@ -545,7 +610,8 @@ ui_sb_update_panes(void)
sb_parts++;
if (c_ide && (ide_int || !memcmp(hdc_name, "xtide", 5) || !memcmp(hdc_name, "ide", 3)))
sb_parts++;
if (c_scsi && (scsi_int || (scsi_card_current != 0)))
if (c_scsi && (scsi_int || (scsi_card_current[0] != 0) || (scsi_card_current[1] != 0) ||
(scsi_card_current[2] != 0) || (scsi_card_current[3] != 0)))
sb_parts++;
if (do_net)
sb_parts++;
@@ -561,6 +627,22 @@ ui_sb_update_panes(void)
memset(sbTips, 0, sb_parts * sizeof(WCHAR *));
sb_parts = 0;
if (cassette_enable) {
edge += icon_width;
iStatusWidths[sb_parts] = edge;
sb_part_meanings[sb_parts] = SB_CASSETTE;
sb_map[SB_CASSETTE] = sb_parts;
sb_parts++;
}
for (i=0; i<2; i++) {
if (cart_int) {
edge += icon_width;
iStatusWidths[sb_parts] = edge;
sb_part_meanings[sb_parts] = SB_CARTRIDGE | i;
sb_map[SB_CARTRIDGE | i] = sb_parts;
sb_parts++;
}
}
for (i=0; i<FDD_NUM; i++) {
if (fdd_get_type(i) != 0) {
edge += icon_width;
@@ -575,8 +657,9 @@ ui_sb_update_panes(void)
if ((cdrom[i].bus_type == CDROM_BUS_ATAPI) &&
!ide_int && memcmp(hdc_name, "ide", 3))
continue;
if ((cdrom[i].bus_type == CDROM_BUS_SCSI) &&
!scsi_int && (scsi_card_current == 0))
if ((cdrom[i].bus_type == CDROM_BUS_SCSI) && !scsi_int &&
(scsi_card_current[0] == 0) && (scsi_card_current[1] == 0) &&
(scsi_card_current[2] == 0) && (scsi_card_current[3] == 0))
continue;
if (cdrom[i].bus_type != 0) {
edge += icon_width;
@@ -591,8 +674,9 @@ ui_sb_update_panes(void)
if ((zip_drives[i].bus_type == ZIP_BUS_ATAPI) &&
!ide_int && memcmp(hdc_name, "ide", 3))
continue;
if ((zip_drives[i].bus_type == ZIP_BUS_SCSI) &&
!scsi_int && (scsi_card_current == 0))
if ((zip_drives[i].bus_type == ZIP_BUS_SCSI) && !scsi_int &&
(scsi_card_current[0] == 0) && (scsi_card_current[1] == 0) &&
(scsi_card_current[2] == 0) && (scsi_card_current[3] == 0))
continue;
if (zip_drives[i].bus_type != 0) {
edge += icon_width;
@@ -607,8 +691,9 @@ ui_sb_update_panes(void)
if ((mo_drives[i].bus_type == MO_BUS_ATAPI) &&
!ide_int && memcmp(hdc_name, "ide", 3))
continue;
if ((mo_drives[i].bus_type == MO_BUS_SCSI) &&
!scsi_int && (scsi_card_current == 0))
if ((mo_drives[i].bus_type == MO_BUS_SCSI) && !scsi_int &&
(scsi_card_current[0] == 0) && (scsi_card_current[1] == 0) &&
(scsi_card_current[2] == 0) && (scsi_card_current[3] == 0))
continue;
if (mo_drives[i].bus_type != 0) {
edge += icon_width;
@@ -646,7 +731,8 @@ ui_sb_update_panes(void)
sb_map[SB_HDD | HDD_BUS_IDE] = sb_parts;
sb_parts++;
}
if (c_scsi && (scsi_int || (scsi_card_current != 0))) {
if (c_scsi && (scsi_int || (scsi_card_current[0] != 0) || (scsi_card_current[1] != 0) ||
(scsi_card_current[2] != 0) || (scsi_card_current[3] != 0))) {
edge += icon_width;
iStatusWidths[sb_parts] = edge;
sb_part_meanings[sb_parts] = SB_HDD | HDD_BUS_SCSI;
@@ -677,6 +763,18 @@ ui_sb_update_panes(void)
for (i=0; i<sb_parts; i++) {
switch (sb_part_meanings[i] & 0xf0) {
case SB_CASSETTE: /* Cassette */
sb_part_icons[i] = (strlen(cassette_fname) == 0) ? 128 : 0;
sb_part_icons[i] |= 64;
StatusBarCreateCassetteTip(i);
break;
case SB_CARTRIDGE: /* Cartridge */
sb_part_icons[i] = (strlen(cart_fns[sb_part_meanings[i] & 0xf]) == 0) ? 128 : 0;
sb_part_icons[i] |= 104;
StatusBarCreateCartridgeTip(i);
break;
case SB_FLOPPY: /* Floppy */
sb_part_icons[i] = (strlen(floppyfns[sb_part_meanings[i] & 0xf]) == 0) ? 128 : 0;
sb_part_icons[i] |= fdd_type_to_icon(fdd_get_type(sb_part_meanings[i] & 0xf));
@@ -750,6 +848,12 @@ StatusBarPopupMenu(HWND hwnd, POINT pt, int id)
ClientToScreen(hwnd, (LPPOINT) &pt);
switch(sb_part_meanings[id] & 0xF0) {
case SB_CASSETTE:
menu = media_menu_get_cassette();
break;
case SB_CARTRIDGE:
menu = media_menu_get_cartridge(sb_part_meanings[id] & 0x0F);
break;
case SB_FLOPPY:
menu = media_menu_get_floppy(sb_part_meanings[id] & 0x0F);
break;
@@ -798,6 +902,7 @@ StatusBarLoadIcon(HINSTANCE hInst) {
hIcon[i] = LoadImage(hInst, MAKEINTRESOURCE(i), IMAGE_ICON, x, x, LR_DEFAULTCOLOR);
for (i = 96; i < 98; i++)
hIcon[i] = LoadImage(hInst, MAKEINTRESOURCE(i), IMAGE_ICON, x, x, LR_DEFAULTCOLOR);
hIcon[104] = LoadImage(hInst, MAKEINTRESOURCE(104), IMAGE_ICON, x, x, LR_DEFAULTCOLOR);
for (i = 144; i < 146; i++)
hIcon[i] = LoadImage(hInst, MAKEINTRESOURCE(i), IMAGE_ICON, x, x, LR_DEFAULTCOLOR);
for (i = 152; i < 154; i++)
@@ -810,6 +915,7 @@ StatusBarLoadIcon(HINSTANCE hInst) {
hIcon[i] = LoadImage(hInst, MAKEINTRESOURCE(i), IMAGE_ICON, x, x, LR_DEFAULTCOLOR);
for (i = 192; i < 194; i++)
hIcon[i] = LoadImage(hInst, MAKEINTRESOURCE(i), IMAGE_ICON, x, x, LR_DEFAULTCOLOR);
hIcon[232] = LoadImage(hInst, MAKEINTRESOURCE(232), IMAGE_ICON, x, x, LR_DEFAULTCOLOR);
for (i = 243; i < 244; i++)
hIcon[i] = LoadImage(hInst, MAKEINTRESOURCE(i), IMAGE_ICON, x, x, LR_DEFAULTCOLOR);
}

View File

@@ -44,15 +44,6 @@ thread_create(void (*func)(void *param), void *param)
}
void
thread_kill(void *arg)
{
if (arg == NULL) return;
TerminateThread(arg, 0);
}
int
thread_wait(thread_t *arg, int timeout)
{

View File

@@ -67,6 +67,8 @@ int infocus = 1, button_down = 0;
int rctrl_is_lalt = 0;
int user_resize = 0;
int fixed_size_x = 0, fixed_size_y = 0;
int kbd_req_capture = 0;
int hide_status_bar = 0;
extern char openfilestring[512];
extern WCHAR wopenfilestring[512];
@@ -80,11 +82,9 @@ static int hook_enabled = 0;
#endif
static int manager_wm = 0;
static int save_window_pos = 0, pause_state = 0;
static int dpi = 96;
static int padded_frame = 0;
static int vis = -1;
static int dpi = 96;
static int padded_frame = 0;
static int vis = -1;
/* Per Monitor DPI Aware v2 APIs, Windows 10 v1703+ */
void* user32_handle = NULL;
@@ -177,6 +177,7 @@ video_toggle_option(HMENU h, int *val, int id)
device_force_redraw();
}
#if defined(DEV_BRANCH) && defined(USE_OPENGL)
/* Recursively finds and deletes target submenu */
static int
delete_submenu(HMENU parent, HMENU target)
@@ -204,6 +205,7 @@ delete_submenu(HMENU parent, HMENU target)
return 0;
}
#endif
static void
show_render_options_menu()
@@ -256,13 +258,8 @@ video_set_filter_menu(HMENU menu)
static void
ResetAllMenus(void)
{
#ifndef DEV_BRANCH
/* FIXME: until we fix these.. --FvK */
EnableMenuItem(menuMain, IDM_CONFIG_LOAD, MF_DISABLED);
EnableMenuItem(menuMain, IDM_CONFIG_SAVE, MF_DISABLED);
#endif
CheckMenuItem(menuMain, IDM_ACTION_RCTRL_IS_LALT, MF_UNCHECKED);
CheckMenuItem(menuMain, IDM_ACTION_KBD_REQ_CAPTURE, MF_UNCHECKED);
CheckMenuItem(menuMain, IDM_UPDATE_ICONS, MF_UNCHECKED);
@@ -290,6 +287,7 @@ ResetAllMenus(void)
# endif
#endif
CheckMenuItem(menuMain, IDM_VID_HIDE_STATUS_BAR, MF_UNCHECKED);
CheckMenuItem(menuMain, IDM_VID_FORCE43, MF_UNCHECKED);
CheckMenuItem(menuMain, IDM_VID_OVERSCAN, MF_UNCHECKED);
CheckMenuItem(menuMain, IDM_VID_INVERT, MF_UNCHECKED);
@@ -328,6 +326,7 @@ ResetAllMenus(void)
CheckMenuItem(menuMain, IDM_VID_GRAY_RGB+4, MF_UNCHECKED);
CheckMenuItem(menuMain, IDM_ACTION_RCTRL_IS_LALT, rctrl_is_lalt ? MF_CHECKED : MF_UNCHECKED);
CheckMenuItem(menuMain, IDM_ACTION_KBD_REQ_CAPTURE, kbd_req_capture ? MF_CHECKED : MF_UNCHECKED);
CheckMenuItem(menuMain, IDM_UPDATE_ICONS, update_icons ? MF_CHECKED : MF_UNCHECKED);
@@ -355,6 +354,7 @@ ResetAllMenus(void)
# endif
#endif
CheckMenuItem(menuMain, IDM_VID_HIDE_STATUS_BAR, hide_status_bar ? MF_CHECKED : MF_UNCHECKED);
CheckMenuItem(menuMain, IDM_VID_FORCE43, force_43?MF_CHECKED:MF_UNCHECKED);
CheckMenuItem(menuMain, IDM_VID_OVERSCAN, enable_overscan?MF_CHECKED:MF_UNCHECKED);
CheckMenuItem(menuMain, IDM_VID_INVERT, invert_display ? MF_CHECKED : MF_UNCHECKED);
@@ -406,7 +406,8 @@ LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
BOOL bControlKeyDown;
KBDLLHOOKSTRUCT *p;
if (nCode < 0 || nCode != HC_ACTION || (!mouse_capture && !video_fullscreen))
if (nCode < 0 || nCode != HC_ACTION ||
(!mouse_capture && !video_fullscreen) || (kbd_req_capture && !mouse_capture && !video_fullscreen))
return(CallNextHookEx(hKeyboardHook, nCode, wParam, lParam));
p = (KBDLLHOOKSTRUCT*)lParam;
@@ -475,9 +476,10 @@ plat_power_off(void)
/* Cleanly terminate all of the emulator's components so as
to avoid things like threads getting stuck. */
do_stop();
// do_stop();
cpu_thread_run = 0;
exit(-1);
// exit(-1);
}
#ifdef MTR_ENABLED
@@ -671,6 +673,12 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
config_save();
break;
case IDM_ACTION_KBD_REQ_CAPTURE:
kbd_req_capture ^= 1;
CheckMenuItem(hmenu, IDM_ACTION_KBD_REQ_CAPTURE, kbd_req_capture ? MF_CHECKED : MF_UNCHECKED);
config_save();
break;
case IDM_ACTION_PAUSE:
plat_pause(dopause ^ 1);
CheckMenuItem(menuMain, IDM_ACTION_PAUSE, dopause ? MF_CHECKED : MF_UNCHECKED);
@@ -694,6 +702,18 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
config_save();
break;
case IDM_VID_HIDE_STATUS_BAR:
hide_status_bar ^= 1;
CheckMenuItem(hmenu, IDM_VID_HIDE_STATUS_BAR, hide_status_bar ? MF_CHECKED : MF_UNCHECKED);
ShowWindow(hwndSBAR, hide_status_bar ? SW_HIDE : SW_SHOW);
GetWindowRect(hwnd, &rect);
if (hide_status_bar)
MoveWindow(hwnd, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top - sbar_height, TRUE);
else
MoveWindow(hwnd, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top + sbar_height, TRUE);
config_save();
break;
case IDM_VID_RESIZE:
vid_resize ^= 1;
CheckMenuItem(hmenu, IDM_VID_RESIZE, (vid_resize & 1) ? MF_CHECKED : MF_UNCHECKED);
@@ -712,7 +732,10 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
temp_y = unscaled_size_y;
}
ResizeWindowByClientArea(hwnd, temp_x, temp_y + sbar_height);
if (hide_status_bar)
ResizeWindowByClientArea(hwnd, temp_x, temp_y);
else
ResizeWindowByClientArea(hwnd, temp_x, temp_y + sbar_height);
if (mouse_capture) {
ClipCursor(&rect);
@@ -998,7 +1021,10 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
}
/* Main Window. */
ResizeWindowByClientArea(hwndMain, temp_x, temp_y + sbar_height);
if (hide_status_bar)
ResizeWindowByClientArea(hwndMain, temp_x, temp_y);
else
ResizeWindowByClientArea(hwndMain, temp_x, temp_y + sbar_height);
} else if (!user_resize)
doresize = 1;
break;
@@ -1028,14 +1054,29 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
if (!(pos->flags & SWP_NOSIZE) || !user_resize) {
plat_vidapi_enable(0);
MoveWindow(hwndSBAR, 0, rect.bottom - sbar_height, sbar_height, rect.right, TRUE);
MoveWindow(hwndRender, 0, 0, rect.right, rect.bottom - sbar_height, TRUE);
if (hide_status_bar)
MoveWindow(hwndRender, 0, 0, rect.right, rect.bottom, TRUE);
else {
MoveWindow(hwndSBAR, 0, rect.bottom - sbar_height, sbar_height, rect.right, TRUE);
MoveWindow(hwndRender, 0, 0, rect.right, rect.bottom - sbar_height, TRUE);
}
GetClientRect(hwndRender, &rect);
if (rect.right != scrnsz_x || rect.bottom != scrnsz_y) {
scrnsz_x = rect.right;
scrnsz_y = rect.bottom;
doresize = 1;
if (dpi_scale) {
temp_x = MulDiv(rect.right, 96, dpi);
temp_y = MulDiv(rect.bottom, 96, dpi);
if (temp_x != scrnsz_x || temp_y != scrnsz_y) {
scrnsz_x = temp_x;
scrnsz_y = temp_y;
doresize = 1;
}
} else {
if (rect.right != scrnsz_x || rect.bottom != scrnsz_y) {
scrnsz_x = rect.right;
scrnsz_y = rect.bottom;
doresize = 1;
}
}
plat_vidsize(rect.right, rect.bottom);
@@ -1401,6 +1442,8 @@ ui_init(int nCmdShow)
/* Get the actual height of the status bar */
GetWindowRect(hwndSBAR, &sbar_rect);
sbar_height = sbar_rect.bottom - sbar_rect.top;
if (hide_status_bar)
ShowWindow(hwndSBAR, SW_HIDE);
/* Set up main window for resizing if configured. */
if (vid_resize == 1)
@@ -1423,7 +1466,10 @@ ui_init(int nCmdShow)
scrnsz_x = fixed_size_x;
scrnsz_y = fixed_size_y;
}
ResizeWindowByClientArea(hwndMain, scrnsz_x, scrnsz_y + sbar_height);
if (hide_status_bar)
ResizeWindowByClientArea(hwndMain, scrnsz_x, scrnsz_y);
else
ResizeWindowByClientArea(hwndMain, scrnsz_x, scrnsz_y + sbar_height);
}
/* Reset all menus to their defaults. */
@@ -1528,10 +1574,10 @@ ui_init(int nCmdShow)
fatal("bRet is -1\n");
}
if (messages.message == WM_QUIT) {
is_quit = 1;
break;
}
/* On WM_QUIT, tell the CPU thread to stop running. That will then tell us
to stop running as well. */
if (messages.message == WM_QUIT)
cpu_thread_run = 0;
if (! TranslateAccelerator(hwnd, haccel, &messages))
{
@@ -1667,7 +1713,10 @@ plat_resize(int x, int y)
x = MulDiv(x, dpi, 96);
y = MulDiv(y, dpi, 96);
}
ResizeWindowByClientArea(hwndMain, x, y + sbar_height);
if (hide_status_bar)
ResizeWindowByClientArea(hwndMain, x, y);
else
ResizeWindowByClientArea(hwndMain, x, y + sbar_height);
}
}
@@ -1677,7 +1726,7 @@ plat_mouse_capture(int on)
{
RECT rect;
if (mouse_type == MOUSE_TYPE_NONE)
if (!kbd_req_capture && (mouse_type == MOUSE_TYPE_NONE))
return;
if (on && !mouse_capture) {