diff --git a/src/config.c b/src/config.c index d359f1b..44ee053 100644 --- a/src/config.c +++ b/src/config.c @@ -12,7 +12,7 @@ * it on Windows XP, and possibly also Vista. Use the * -DANSI_CFG for use on these systems. * - * Version: @(#)config.c 1.0.34 2018/10/05 + * Version: @(#)config.c 1.0.35 2018/10/07 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -831,7 +831,7 @@ load_other(const char *cat) bugger_enabled = !!config_get_int(cat, "bugger_enabled", 0); for (c = 0; c < ISAMEM_MAX; c++) { - sprintf(temp, "isamem%d_type", c); + sprintf(temp, "isamem%i_type", c); p = config_get_string(cat, temp, "none"); isamem_type[c] = isamem_get_from_internal_name(p); @@ -877,7 +877,7 @@ save_other(const char *cat) config_set_int(cat, "bugger_enabled", bugger_enabled); for (c = 0; c < ISAMEM_MAX; c++) { - sprintf(temp, "isamem%d_type", c); + sprintf(temp, "isamem%i_type", c); if (isamem_type[c] == 0) config_delete_var(cat, temp); else @@ -1032,7 +1032,7 @@ load_disks(const char *cat) static void save_disks(const char *cat) { - char temp[24], tmp2[64]; + char temp[128], tmp2[128]; const char *str; int c; diff --git a/src/cpu/codegen_x86-64.c b/src/cpu/codegen_x86-64.c index bf937f6..7e279c6 100644 --- a/src/cpu/codegen_x86-64.c +++ b/src/cpu/codegen_x86-64.c @@ -8,7 +8,7 @@ * * Dynamic Recompiler for Intel x64 systems. * - * Version: @(#)codegen_x86-64.c 1.0.2 2018/09/22 + * Version: @(#)codegen_x86-64.c 1.0.3 2018/10/07 * * Authors: Sarah Walker, * Miran Grca, @@ -940,7 +940,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t codeblock_t *block = &codeblock[block_current]; uint32_t op_32 = use32; uint32_t op_pc = new_pc; - OpFn *op_table = x86_dynarec_opcodes; + const OpFn *op_table = x86_dynarec_opcodes; RecompOpFn *recomp_op_table = recomp_opcodes; int opcode_shift = 0; int opcode_mask = 0x3ff; @@ -1003,7 +1003,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t break; case 0xd8: - op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_d8_a32 : x86_dynarec_opcodes_d8_a16; + op_table = (op_32 & 0x200) ? (OpFn *)x86_dynarec_opcodes_d8_a32 : (OpFn *)x86_dynarec_opcodes_d8_a16; recomp_op_table = recomp_opcodes_d8; opcode_shift = 3; opcode_mask = 0x1f; diff --git a/src/devices/scsi/scsi_ncr5380.c b/src/devices/scsi/scsi_ncr5380.c index 3a93ce9..d60fc61 100644 --- a/src/devices/scsi/scsi_ncr5380.c +++ b/src/devices/scsi/scsi_ncr5380.c @@ -11,7 +11,7 @@ * * NOTE: This code now only supports targets at LUN=0 !! * - * Version: @(#)scsi_ncr5380.c 1.0.8 2018/10/05 + * Version: @(#)scsi_ncr5380.c 1.0.9 2018/10/07 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -216,13 +216,15 @@ get_dev_id(uint8_t data) static int get_cmd_len(int cbyte) { - int len; + int len = 12; int group; - group = (cbyte>>5) & 7; + group = (cbyte >> 5) & 7; - if (group == 0) len = 6; - if (group == 1 || group == 2) len = 10; + if (group == 0) + len = 6; + if (group == 1 || group == 2) + len = 10; return(len); } @@ -881,6 +883,7 @@ ncr_callback(void *priv) ncr5380_t *ncr_dev = (ncr5380_t *)priv; ncr_t *ncr = &ncr_dev->ncr; scsi_device_t *dev = &SCSIDevices[ncr->target_id][ncr->target_lun]; + int64_t p; int c = 0; DEBUG("DMA mode=%d\n", ncr->dma_mode); @@ -928,79 +931,71 @@ ncr_callback(void *priv) } } } else if (ncr->state == STATE_COMMAND) { - int64_t p; - /*Command phase, make sure the ICR ACK bit is set to keep on, because the device must be acknowledged by ICR*/ DEBUG("NCR ICR for Command=%02x\n", ncr->bus_host & BUS_ACK); if (ncr->bus_host & BUS_ACK) { - /*Write command byte to the output data register*/ - ncr->command[ncr->command_pos++] = BUS_GETDATA(ncr->bus_host); + if (ncr->command_pos < get_cmd_len(ncr->command[0])) { + /*Write command byte to the output data register*/ + ncr->command[ncr->command_pos++] = BUS_GETDATA(ncr->bus_host); - ncr->new_phase = ncr->cur_bus & SCSI_PHASE_MESSAGE_IN; - ncr->clear_req = 3; - DEBUG("Current bus for command request=%02x\n", ncr->cur_bus & BUS_REQ); - ncr->cur_bus &= ~BUS_REQ; + ncr->new_phase = ncr->cur_bus & SCSI_PHASE_MESSAGE_IN; + ncr->clear_req = 3; + DEBUG("NCR: current bus for command request=%02x\n", ncr->cur_bus & BUS_REQ); + ncr->cur_bus &= ~BUS_REQ; - DEBUG("Command pos=%i, output data=%02x\n", ncr->command_pos, BUS_GETDATA(ncr->bus_host)); - if (get_cmd_len(ncr->command[0]) == ncr->command_pos) { - /*Reset data position to default*/ - ncr->data_pos = 0; - - dev = &SCSIDevices[ncr->target_id][ncr->target_lun]; + DEBUG("NCR: Command pos=%i, output data=%02x\n", ncr->command_pos, BUS_GETDATA(ncr->bus_host)); + if (get_cmd_len(ncr->command[0]) == ncr->command_pos) { + /*Reset data position to default*/ + ncr->data_pos = 0; - DEBUG("SCSI Command 0x%02X for ID %d, status code=%02x\n", ncr->command[0], ncr->target_id, dev->Status); + dev = &SCSIDevices[ncr->target_id][ncr->target_lun]; - dev->BufferLength = -1; + DEBUG("NCR: SCSI Command 0x%02X for ID %d, status code=%02x\n", ncr->command[0], ncr->target_id, dev->Status); - /*Now, execute the given SCSI command*/ - scsi_device_command_phase0(ncr->target_id, ncr->target_lun, ncr->command); + dev->BufferLength = -1; - DEBUG("SCSI ID %i: Command %02X: Buffer Length %i, SCSI Phase %02X\n", ncr->target_id, ncr->command[0], dev->BufferLength, dev->Phase); + /*Now, execute the given SCSI command*/ + scsi_device_command_phase0(ncr->target_id, ncr->target_lun, ncr->command); + DEBUG("NCR: SCSI ID %i: Command %02X: Buffer Length %i, SCSI Phase %02X\n", ncr->target_id, ncr->command[0], dev->BufferLength, dev->Phase); - if (dev->Status != SCSI_STATUS_OK) - ncr_dev->is_non_data_mode = 1; - - if (ncr_dev->is_non_data_mode) { - ncr_dev->is_non_data_mode = 0; - ncr->new_phase = SCSI_PHASE_STATUS; - ncr->wait_data = 4; - return; - } - - /*If the SCSI phase is Data In or Data Out, allocate the SCSI buffer based on the transfer length of the command*/ - if (dev->BufferLength && (dev->Phase == SCSI_PHASE_DATA_IN || dev->Phase == SCSI_PHASE_DATA_OUT)) { - dev->CmdBuffer = (uint8_t *)mem_alloc(dev->BufferLength); - - p = scsi_device_get_callback(ncr->target_id, ncr->target_lun); - if (p <= 0LL) { - ncr_dev->temp_period = (int64_t)(dev->BufferLength); - ncr_dev->media_period = 0; - ncr_dev->period = 0.2 * ((double) TIMER_USEC) * ((double) MIN(64, ncr_dev->temp_period)); + if (dev->Status != SCSI_STATUS_OK) + ncr_dev->is_non_data_mode = 1; + if (ncr_dev->is_non_data_mode) { + ncr_dev->is_non_data_mode = 0; + ncr->new_phase = SCSI_PHASE_STATUS; + ncr->wait_data = 4; + return; + } + /*If the SCSI phase is Data In or Data Out, allocate the SCSI buffer based on the transfer length of the command*/ + if (dev->BufferLength && (dev->Phase == SCSI_PHASE_DATA_IN || dev->Phase == SCSI_PHASE_DATA_OUT)) { + dev->CmdBuffer = (uint8_t *) malloc(dev->BufferLength); + p = scsi_device_get_callback(ncr->target_id, ncr->target_lun); + if (p <= 0LL) { + ncr_dev->temp_period = (int64_t)(dev->BufferLength); + ncr_dev->media_period = 0; + ncr_dev->period = 0.2 * ((double) TIMER_USEC) * ((double) MIN(64, ncr_dev->temp_period)); + } else { + ncr_dev->media_period += p; + ncr_dev->temp_period = dev->BufferLength; + ncr_dev->period = (p / ((double) ncr_dev->temp_period)) * ((double) MIN(64, ncr_dev->temp_period)); + } + } + if (dev->Phase == SCSI_PHASE_DATA_OUT) { + /* Write direction commands have delayed execution - only execute them after the bus has gotten all the data from the host. */ + DEBUG("NCR: Next state is data out\n"); + ncr->new_phase = SCSI_PHASE_DATA_OUT; + ncr->wait_data = 4; + ncr->clear_req = 4; } else { - ncr_dev->media_period += p; - ncr_dev->temp_period = dev->BufferLength; - ncr_dev->period = (p / ((double) ncr_dev->temp_period)) * ((double) MIN(64, ncr_dev->temp_period)); + /* Other command - execute immediately. */ + ncr->new_phase = dev->Phase; + if (ncr->new_phase == SCSI_PHASE_DATA_IN) + scsi_device_command_phase1(ncr->target_id, ncr->target_lun); + ncr->wait_data = 4; } } - - if (dev->Phase == SCSI_PHASE_DATA_OUT) { - /* Write direction commands have delayed execution - only execute them after the bus has gotten all the data from the host. */ - DEBUG("Next state is data out\n"); - ncr->new_phase = SCSI_PHASE_DATA_OUT; - ncr->wait_data = 4; - ncr->clear_req = 4; - } else { - /* Other command - execute immediately. */ - ncr->new_phase = dev->Phase; - - if (ncr->new_phase == SCSI_PHASE_DATA_IN) { - scsi_device_command_phase1(ncr->target_id, ncr->target_lun); - } - - ncr->wait_data = 4; - } - } + } } } else if (ncr->state == STATE_DATAIN) { dev = &SCSIDevices[ncr->target_id][ncr->target_lun]; diff --git a/src/devices/system/i82335.c b/src/devices/system/i82335.c index eb0c241..50a9a30 100644 --- a/src/devices/system/i82335.c +++ b/src/devices/system/i82335.c @@ -8,7 +8,7 @@ * * Intel 82335 SX emulation, used by the Phoenix 386 clone. * - * Version: @(#)i82335.c 1.0.4 2018/09/13 + * Version: @(#)i82335.c 1.0.5 2018/10/07 * * Authors: Fred N. van Kempen, * Miran Grca, diff --git a/src/devices/video/vid_oak_oti.c b/src/devices/video/vid_oak_oti.c index da68b78..0a1ca17 100644 --- a/src/devices/video/vid_oak_oti.c +++ b/src/devices/video/vid_oak_oti.c @@ -8,7 +8,7 @@ * * Oak OTI037C/67/077 emulation. * - * Version: @(#)vid_oak_oti.c 1.0.11 2018/10/05 + * Version: @(#)vid_oak_oti.c 1.0.12 2018/10/07 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -50,9 +50,17 @@ #include "vid_svga.h" -#define BIOS_37C_PATH L"video/oti/oti037c/bios.bin" -//#define BIOS_67_PATH L"video/oti/oti067.bin" -#define BIOS_77_PATH L"video/oti/oti077.vbi" +#define BIOS_037C_PATH L"video/oti/oti037c/bios.bin" +//#define BIOS_067_PATH L"video/oti/oti067.bin" +#define BIOS_077_PATH L"video/oti/oti077.vbi" + + +enum { + OTI_037C = 0, + OTI_067 = 2, + OTI_067_AMA932J, + OTI_077 = 5 +}; typedef struct { @@ -60,6 +68,7 @@ typedef struct { uint8_t enable_register; uint8_t pos; uint8_t indx; + uint8_t dipswitch_val; uint32_t vram_size; uint32_t vram_mask; @@ -72,38 +81,52 @@ typedef struct { } oti_t; +static const video_timings_t oti_timing = {VID_ISA,6,8,16,6,8,16}; + + static void oti_out(uint16_t addr, uint8_t val, void *priv) { oti_t *dev = (oti_t *)priv; svga_t *svga = &dev->svga; - uint8_t old, idx; + uint8_t old, idx, enable; - if (!(dev->enable_register & 1) && addr != 0x03c3) return; +INFO("OAK: out(%04x, %02x)\n", addr, val); + if (!dev->chip_id && !(dev->enable_register & 1) && (addr != 0x3C3)) + return; if ((((addr&0xfff0) == 0x03d0 || (addr&0xfff0) == 0x03b0) && addr < 0x3de) && !(svga->miscout & 1)) addr ^= 0x60; switch (addr) { case 0x03c3: - dev->enable_register = val & 1; - return; + if (! dev->chip_id) { + dev->enable_register = val & 1; + return; + } + break; case 0x03d4: - svga->crtcreg = val; + if (dev->chip_id) + svga->crtcreg = val & 0x3f; + else + svga->crtcreg = val; /* FIXME: The BIOS wants to set the test bit? */ return; case 0x03d5: - if (svga->crtcreg & 0x20) + if (dev->chip_id && (svga->crtcreg & 0x20)) return; - if (((svga->crtcreg & 31) < 7) && (svga->crtc[0x11] & 0x80)) + idx = svga->crtcreg; + if (! dev->chip_id) + idx &= 0x1f; + if ((idx < 7) && (svga->crtc[0x11] & 0x80)) return; - if (((svga->crtcreg & 31) == 7) && (svga->crtc[0x11] & 0x80)) + if ((idx == 7) && (svga->crtc[0x11] & 0x80)) val = (svga->crtc[7] & ~0x10) | (val & 0x10); - old = svga->crtc[svga->crtcreg & 31]; - svga->crtc[svga->crtcreg & 31] = val; + old = svga->crtc[idx]; + svga->crtc[idx] = val; if (old != val) { - if ((svga->crtcreg & 31) < 0x0e || (svga->crtcreg & 31) > 0x10) { + if ((idx < 0x0e) || (idx > 0x10)) { svga->fullchange = changeframecount; svga_recalctimings(svga); } @@ -111,22 +134,54 @@ oti_out(uint16_t addr, uint8_t val, void *priv) break; case 0x03de: - dev->indx = val; + if (dev->chip_id) + dev->indx = val & 0x1f; + else + dev->indx = val; return; case 0x03df: - idx = dev->indx & 0x1f; + idx = dev->indx; + if (! dev->chip_id) + idx &= 0x1f; dev->regs[idx] = val; switch (idx) { case 0x0d: - if (dev->chip_id) { + if (dev->chip_id == OTI_067) { svga->vram_display_mask = (val & 0xc) ? dev->vram_mask : 0x3ffff; + if (! (val & 0x80)) + svga->vram_display_mask = 0x3ffff; + if ((val & 0x80) && dev->vram_size == 256) mem_map_disable(&svga->mapping); else mem_map_enable(&svga->mapping); - if (!(val & 0x80)) - svga->vram_display_mask = 0x3ffff; + } else if (dev->chip_id == OTI_077) { + svga->vram_display_mask = (val & 0xc) ? dev->vram_mask : 0x3ffff; + switch ((val & 0xc0) >> 6) { + case 0x00: /* 256 kB of memory */ + default: + enable = (dev->vram_size >= 256); + if (val & 0xc) + svga->vram_display_mask = MIN(dev->vram_mask, 0x3ffff); + break; + case 0x01: /* 1 MB of memory */ + case 0x03: + enable = (dev->vram_size >= 1024); + if (val & 0xc) + svga->vram_display_mask = MIN(dev->vram_mask, 0x7ffff); + break; + case 0x02: /* 512 kB of memory */ + enable = (dev->vram_size >= 512); + if (val & 0xc) + svga->vram_display_mask = MIN(dev->vram_mask, 0xfffff); + break; + } + + if (enable) + mem_map_enable(&svga->mapping); + else + mem_map_disable(&svga->mapping); } else { if (val & 0x80) mem_map_disable(&svga->mapping); @@ -152,16 +207,28 @@ oti_in(uint16_t addr, void *priv) { oti_t *dev = (oti_t *)priv; svga_t *svga = &dev->svga; - uint8_t ret = 0xff; + uint8_t idx, ret = 0xff; - if (!(dev->enable_register & 1) && addr != 0x03c3) return ret; +INFO("OAK: in(%04x)", addr); + if (!dev->chip_id && !(dev->enable_register & 1) && + (addr != 0x3c3)) return 0xff; if ((((addr&0xfff0) == 0x03d0 || (addr&0xfff0) == 0x03b0) && addr < 0x3de) && !(svga->miscout & 1)) addr ^= 0x60; switch (addr) { + case 0x03c2: + if ((svga->vgapal[0].r + svga->vgapal[0].g + svga->vgapal[0].b) >= 0x50) + ret = 0; + else + ret = 0x10; + break; + case 0x03c3: - ret = dev->enable_register; + if (dev->chip_id) + ret = svga_in(addr, svga); + else + ret = dev->enable_register; break; case 0x03d4: @@ -169,15 +236,31 @@ oti_in(uint16_t addr, void *priv) break; case 0x03d5: - if (svga->crtcreg & 0x20) - ret = 0xff; - else - ret = svga->crtc[svga->crtcreg & 31]; + if (dev->chip_id) { + if (svga->crtcreg & 0x20) + ret = 0xff; + else + ret = svga->crtc[svga->crtcreg]; + } else + ret = svga->crtc[svga->crtcreg & 0x1f]; break; case 0x03da: + if (dev->chip_id) { + ret = svga_in(addr, svga); + break; + } + svga->attrff = 0; - svga->attrff = 0; + + /* + * The OTI-037C BIOS waits for bits 0 and 3 in 0x3da to go + * low, then reads 0x3da again and expects the diagnostic + * bits to equal the current border colour. As I understand + * it, the 0x3da active enable status does not include the + * border time, so this may be an area where OTI-037C is + * not entirely VGA compatible. + */ svga->cgastat &= ~0x30; /* copy color diagnostic info from the overscan color register */ @@ -210,23 +293,30 @@ oti_in(uint16_t addr, void *priv) svga->cgastat |= 0x20; break; } - return svga->cgastat; + ret = svga->cgastat; + break; case 0x03de: - ret = dev->indx | (dev->chip_id << 5); + ret = dev->indx; + if (dev->chip_id) + ret |= (dev->chip_id << 5); break; case 0x03df: - if ((dev->indx & 0x1f)==0x10) - ret = 0x18; - else - ret = dev->regs[dev->indx & 0x1f]; + idx = dev->indx; + if (! dev->chip_id) + idx &= 0x1f; + if (idx == 0x10) + ret = dev->dipswitch_val; + else + ret = dev->regs[idx]; break; default: ret = svga_in(addr, svga); break; } +INFO(" = %02x\n", ret); return(ret); } @@ -237,7 +327,8 @@ oti_pos_out(uint16_t addr, uint8_t val, void *priv) { oti_t *dev = (oti_t *)priv; - if ((val & 8) != (dev->pos & 8)) { +INFO("OAK: pos_out(%04x, %02x)\n", addr, val); + if ((val ^ dev->pos) & 8) { if (val & 8) io_sethandler(0x03c0, 32, oti_in,NULL,NULL, oti_out,NULL,NULL, dev); @@ -255,6 +346,7 @@ oti_pos_in(uint16_t addr, void *priv) { oti_t *dev = (oti_t *)priv; +INFO("OAK: pos_in(%04x) = %02x\n", addr, dev->pos); return(dev->pos); } @@ -300,27 +392,63 @@ oti_init(const device_t *info) memset(dev, 0x00, sizeof(oti_t)); dev->chip_id = info->local; + dev->dipswitch_val = 0x18; + fn = NULL; switch(dev->chip_id) { - case 0: - fn = BIOS_37C_PATH; + case OTI_037C: + fn = BIOS_037C_PATH; + dev->vram_size = 256; + dev->regs[0] = 0x08; /* FIXME: The BIOS wants to read this at index 0? This index is undocumented. */ break; - case 2: -#ifdef BIOS_67_PATH - fn = BIOS_67_PATH; + case OTI_067: +#ifdef BIOS_067_PATH + fn = BIOS_067_PATH; #else - fn = BIOS_77_PATH; + fn = BIOS_077_PATH; #endif + + dev->vram_size = device_get_config_int("memory"); + + /* + * Tell the BIOS the I/O ports are already enabled + * to avoid a double I/O handler mess. + */ + dev->pos = 0x08; + + io_sethandler(0x46e8, 1, + oti_pos_in,NULL,NULL, oti_pos_out,NULL,NULL, dev); break; - case 2+128: + case OTI_067_AMA932J: /* Onboard OTI067; ROM set up by machine. */ - dev->chip_id = 2; + dev->chip_id = OTI_067; + dev->vram_size = 512; + dev->dipswitch_val |= 0x20; + + /* + * Tell the BIOS the I/O ports are already enabled + * to avoid a double I/O handler mess. + */ + dev->pos = 0x08; + + io_sethandler(0x46e8, 1, + oti_pos_in,NULL,NULL, oti_pos_out,NULL,NULL, dev); break; - case 5: - fn = BIOS_77_PATH; + case OTI_077: + fn = BIOS_077_PATH; + dev->vram_size = device_get_config_int("memory"); + + /* + * Tell the BIOS the I/O ports are already enabled + * to avoid a double I/O handler mess. + */ + dev->pos = 0x08; + + io_sethandler(0x46e8, 1, + oti_pos_in,NULL,NULL, oti_pos_out,NULL,NULL, dev); break; } @@ -328,23 +456,21 @@ oti_init(const device_t *info) rom_init(&dev->bios_rom, fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - dev->vram_size = device_get_config_int("memory"); dev->vram_mask = (dev->vram_size << 10) - 1; + INFO("VIDEO: %s (chip=%02x(%i), mem=%i)\n", + info->name, dev->chip_id, info->local, dev->vram_size); + + video_inform(VID_TYPE_SPEC, &oti_timing); + svga_init(&dev->svga, dev, dev->vram_size << 10, recalc_timings, oti_in, oti_out, NULL, NULL); io_sethandler(0x03c0, 32, oti_in,NULL,NULL, oti_out,NULL,NULL, dev); - io_sethandler(0x46e8, 1, - oti_pos_in,NULL,NULL, oti_pos_out,NULL,NULL, dev); - dev->svga.miscout = 1; - /* FIXME: BIOS wants to read this there (undocumented.)*/ - dev->regs[0] = 0x08; - return(dev); } @@ -363,19 +489,25 @@ oti_close(void *priv) static int oti037c_available(void) { - return(rom_present(BIOS_37C_PATH)); + return(rom_present(BIOS_037C_PATH)); } static int oti067_available(void) { #ifdef BIOS_67_PATH - return(rom_present(BIOS_67_PATH)); + return(rom_present(BIOS_067_PATH)); #else - return(rom_present(BIOS_77_PATH)); + return(rom_present(BIOS_077_PATH)); #endif } +static int +oti077_available(void) +{ + return(rom_present(BIOS_077_PATH)); +} + static const device_config_t oti067_config[] = { { @@ -397,14 +529,6 @@ static const device_config_t oti067_config[] = { } }; - -static int -oti077_available(void) -{ - return(rom_present(BIOS_77_PATH)); -} - - static const device_config_t oti077_config[] = { { "memory", "Memory size", CONFIG_SELECTION, "", 1024, @@ -431,19 +555,19 @@ static const device_config_t oti077_config[] = { const device_t oti037c_device = { "Oak OTI-037C", DEVICE_ISA, - 0, + OTI_037C, oti_init, oti_close, NULL, oti037c_available, speed_changed, force_redraw, NULL, - oti067_config + NULL }; const device_t oti067_device = { "Oak OTI-067", DEVICE_ISA, - 2, + OTI_067, oti_init, oti_close, NULL, oti067_available, speed_changed, @@ -453,21 +577,21 @@ const device_t oti067_device = { }; const device_t oti067_onboard_device = { - "Oak OTI-067 (onboard)", + "Onboard Oak OTI-067", DEVICE_ISA, - 2+128, + OTI_067_AMA932J, oti_init, oti_close, NULL, NULL, speed_changed, force_redraw, NULL, - oti067_config + NULL }; const device_t oti077_device = { "Oak OTI-077", DEVICE_ISA, - 5, + OTI_077, oti_init, oti_close, NULL, oti077_available, speed_changed, diff --git a/src/devices/video/vid_svga.c b/src/devices/video/vid_svga.c index 5d57e5a..1c586cf 100644 --- a/src/devices/video/vid_svga.c +++ b/src/devices/video/vid_svga.c @@ -11,7 +11,7 @@ * This is intended to be used by another SVGA driver, * and not as a card in it's own right. * - * Version: @(#)vid_svga.c 1.0.12 2018/10/05 + * Version: @(#)vid_svga.c 1.0.13 2018/10/07 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -397,7 +397,6 @@ svga_in(uint16_t addr, void *priv) break; case 0x3da: svga->attrff = 0; - svga->attrff = 0; if (svga->cgastat & 0x01) svga->cgastat &= ~0x30; @@ -803,7 +802,7 @@ svga_poll(void *p) int -svga_init(svga_t *svga, void *p, int memsize, +svga_init(svga_t *svga, void *p, int vramsize, void (*recalctimings_ex)(struct svga_t *svga), uint8_t (*video_in) (uint16_t addr, void *p), void (*video_out)(uint16_t addr, uint8_t val, void *p), @@ -833,11 +832,11 @@ svga_init(svga_t *svga, void *p, int memsize, svga->crtc[6] = 255; svga->dispontime = svga->dispofftime = 1000 * (1 << TIMER_SHIFT); svga->bpp = 8; - svga->vram = (uint8_t *)mem_alloc(memsize); - svga->vram_max = memsize; - svga->vram_display_mask = svga->vram_mask = memsize - 1; + svga->vram = (uint8_t *)mem_alloc(vramsize); + svga->vram_max = vramsize; + svga->vram_display_mask = svga->vram_mask = vramsize - 1; svga->decode_mask = 0x7fffff; - svga->changedvram = (uint8_t *)mem_alloc(memsize >> 12); + svga->changedvram = (uint8_t *)mem_alloc(0x800000 >> 12); svga->recalctimings_ex = recalctimings_ex; svga->video_in = video_in; svga->video_out = video_out; diff --git a/src/machines/m_at_headland.c b/src/machines/m_at_headland.c index 8b2760c..12bbf56 100644 --- a/src/machines/m_at_headland.c +++ b/src/machines/m_at_headland.c @@ -10,7 +10,7 @@ * * FIXME: fix the mem_map_t stuff in mem_read_b() et al! * - * Version: @(#)m_at_headland.c 1.0.6 2018/09/22 + * Version: @(#)m_at_headland.c 1.0.7 2018/10/07 * * Authors: Fred N. van Kempen, * Original by GreatPsycho for PCem. @@ -57,7 +57,7 @@ #include "machine.h" -#define BIOS_67_AMA932J_PATH L"machines/unknown/ama932j/oti067.bin" +#define BIOS_AMA932J_VIDEO_PATH L"machines/unknown/ama932j/oti067.bin" typedef struct { @@ -469,8 +469,9 @@ hl_readw(uint16_t addr, void *priv) static uint8_t mem_read_b(uint32_t addr, void *priv) { - uint16_t *mr = (uint16_t *)priv; - headland_t *dev = NULL; //FIXME: + mem_map_t *map = (mem_map_t *)priv; + headland_t *dev = (headland_t *)map->dev; + uint16_t *mr = (uint16_t *)map->p2; uint8_t ret = 0xff; addr = get_addr(dev, addr, mr); @@ -484,8 +485,9 @@ mem_read_b(uint32_t addr, void *priv) static uint16_t mem_read_w(uint32_t addr, void *priv) { - uint16_t *mr = (uint16_t *)priv; - headland_t *dev = NULL; //FIXME: + mem_map_t *map = (mem_map_t *)priv; + headland_t *dev = (headland_t *)map->dev; + uint16_t *mr = (uint16_t *)map->p2; uint16_t ret = 0xffff; addr = get_addr(dev, addr, mr); @@ -499,8 +501,9 @@ mem_read_w(uint32_t addr, void *priv) static uint32_t mem_read_l(uint32_t addr, void *priv) { - uint16_t *mr = (uint16_t *)priv; - headland_t *dev = NULL; //FIXME: + mem_map_t *map = (mem_map_t *)priv; + headland_t *dev = (headland_t *)map->dev; + uint16_t *mr = (uint16_t *)map->p2; uint32_t ret = 0xffffffff; addr = get_addr(dev, addr, mr); @@ -514,8 +517,9 @@ mem_read_l(uint32_t addr, void *priv) static void mem_write_b(uint32_t addr, uint8_t val, void *priv) { - uint16_t *mr = (uint16_t *)priv; - headland_t *dev = NULL; //FIXME: + mem_map_t *map = (mem_map_t *)priv; + headland_t *dev = (headland_t *)map->dev; + uint16_t *mr = (uint16_t *)map->p2; addr = get_addr(dev, addr, mr); if (addr < ((uint32_t)mem_size << 10)) @@ -526,8 +530,9 @@ mem_write_b(uint32_t addr, uint8_t val, void *priv) static void mem_write_w(uint32_t addr, uint16_t val, void *priv) { - uint16_t *mr = (uint16_t *)priv; - headland_t *dev = NULL; //FIXME: + mem_map_t *map = (mem_map_t *)priv; + headland_t *dev = (headland_t *)map->dev; + uint16_t *mr = (uint16_t *)map->p2; addr = get_addr(dev, addr, mr); if (addr < ((uint32_t)mem_size << 10)) @@ -538,8 +543,9 @@ mem_write_w(uint32_t addr, uint16_t val, void *priv) static void mem_write_l(uint32_t addr, uint32_t val, void *priv) { - uint16_t *mr = (uint16_t *)priv; - headland_t *dev = NULL; //FIXME: + mem_map_t *map = (mem_map_t *)priv; + headland_t *dev = (headland_t *)map->dev; + uint16_t *mr = (uint16_t *)map->p2; addr = get_addr(dev, addr, mr); if (addr < ((uint32_t)mem_size << 10)) @@ -581,22 +587,25 @@ headland_init(headland_t *dev, int ht386) mem_map_add(&dev->low_mapping, 0, 0x40000, mem_read_b,mem_read_w,mem_read_l, mem_write_b,mem_write_w,mem_write_l, - ram, MEM_MAPPING_INTERNAL, dev); + ram, MEM_MAPPING_INTERNAL, &dev->low_mapping); + mem_map_set_dev(&dev->low_mapping, dev); if (mem_size > 640) { mem_map_add(&dev->mid_mapping, 0xA0000, 0x60000, mem_read_b,mem_read_w,mem_read_l, mem_write_b,mem_write_w,mem_write_l, - ram + 0xA0000, MEM_MAPPING_INTERNAL, dev); + ram + 0xA0000, MEM_MAPPING_INTERNAL, &dev->mid_mapping); mem_map_enable(&dev->mid_mapping); + mem_map_set_dev(&dev->mid_mapping, dev); } if (mem_size > 1024) { mem_map_add(&dev->high_mapping, 0x100000, ((mem_size-1024)*1024), mem_read_b,mem_read_w,mem_read_l, mem_write_b,mem_write_w,mem_write_l, - ram + 0x100000, MEM_MAPPING_INTERNAL, dev); + ram + 0x100000, MEM_MAPPING_INTERNAL, &dev->high_mapping); mem_map_enable(&dev->high_mapping); + mem_map_set_dev(&dev->high_mapping, dev); } for (i = 0; i < 24; i++) { @@ -605,8 +614,9 @@ headland_init(headland_t *dev, int ht386) mem_read_b,mem_read_w,mem_read_l, mem_write_b,mem_write_w,mem_write_l, mem_size > 256 + (i << 4) ? ram + 0x40000 + (i << 14) : NULL, - MEM_MAPPING_INTERNAL, dev); + MEM_MAPPING_INTERNAL, &dev->upper_mapping[i]); mem_map_enable(&dev->upper_mapping[i]); + mem_map_set_dev(&dev->upper_mapping[i], dev); } for (i = 0; i < 64; i++) { @@ -616,8 +626,12 @@ headland_init(headland_t *dev, int ht386) mem_read_b,mem_read_w,mem_read_l, mem_write_b,mem_write_w,mem_write_l, ram + (((i & 31) + ((i & 31) >= 24 ? 24 : 16)) << 14), - 0, &dev->ems_mr[i]); + 0, &dev->ems_mapping[i]); mem_map_disable(&dev->ems_mapping[i]); + mem_map_set_dev(&dev->ems_mapping[i], dev); + + /* HACK - we need 'mr' in the r/w routines!! */ + dev->ems_mapping[i].p2 = &dev->ems_mr[i]; } memmap_state_update(dev); @@ -652,9 +666,8 @@ machine_at_ama932j_init(const machine_t *model, void *arg) dev = headland_common_init(1); if (video_card == VID_INTERNAL) { - rom_init(&dev->vid_bios, BIOS_67_AMA932J_PATH, - 0xc0000, 0x8000, 0x7fff, - 0, MEM_MAPPING_INTERNAL); + rom_init(&dev->vid_bios, BIOS_AMA932J_VIDEO_PATH, + 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_INTERNAL); device_add(&oti067_onboard_device); } diff --git a/src/mem.h b/src/mem.h index 0f11437..4112cba 100644 --- a/src/mem.h +++ b/src/mem.h @@ -8,7 +8,7 @@ * * Definitions for the memory interface. * - * Version: @(#)mem.h 1.0.10 2018/09/18 + * Version: @(#)mem.h 1.0.11 2018/10/07 * * Authors: Fred N. van Kempen, * Sarah Walker, @@ -78,7 +78,7 @@ typedef struct _memmap_ { uint32_t flags; void *p; /* backpointer to mapping or device */ - + void *p2; /* FIXME: temporary hack for Headland --FvK */ void *dev; /* backpointer to memory device */ } mem_map_t; diff --git a/src/pc.c b/src/pc.c index 8317af3..766290a 100644 --- a/src/pc.c +++ b/src/pc.c @@ -8,7 +8,7 @@ * * Main emulator module where most things are controlled. * - * Version: @(#)pc.c 1.0.54 2018/10/05 + * Version: @(#)pc.c 1.0.55 2018/10/07 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -202,6 +202,7 @@ pclog_ex(const char *fmt, va_list ap) static int seen = 0; static int detect = 1; char temp[PCLOG_BUFF_SIZE]; + FILE *fp; if (fmt == NULL) { /* Initialize. */ @@ -210,22 +211,11 @@ pclog_ex(const char *fmt, va_list ap) return; } - if (stdlog == NULL) { - if (log_path[0] != L'\0') { - stdlog = plat_fopen(log_path, L"w"); - if (stdlog == NULL) -#ifdef _WIN32 - stdlog = stdout; -#else - stdlog = stderr; -#endif - } else { -#ifdef _WIN32 - stdlog = stdout; -#else - stdlog = stderr; -#endif - } + /* If a logpath was set, override the default. */ + if (log_path[0] != L'\0') { + fp = plat_fopen(log_path, L"w"); + if (fp != NULL) + stdlog = fp; } vsprintf(temp, fmt, ap); @@ -233,7 +223,7 @@ pclog_ex(const char *fmt, va_list ap) seen++; } else { if (seen) { - fprintf(stdlog, "*** %d repeats ***\n", seen); + fprintf(stdlog, "*** %i repeats ***\n", seen); } seen = 0; strcpy(buff, temp); @@ -383,18 +373,18 @@ pc_version(const char *platform) strcpy(emu_fullversion, emu_version); #if defined(_MSC_VER) - sprintf(temp, " [VC %d]", _MSC_VER); + sprintf(temp, " [VC %i]", _MSC_VER); #elif defined(__clang_major__) - sprintf(temp, " [Clang %d.%d.%d]", + sprintf(temp, " [Clang %i.%i.%i]", __clang_major__, __clang_minor__, __clang_patchlevel__); #elif defined(__GNUC__) - sprintf(temp, " [GCC %d.%d.%d]", + sprintf(temp, " [GCC %i.%i.%i]", __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__); #endif strcat(emu_fullversion, temp); #ifdef BUILD - sprintf(temp, " (Build %d", BUILD); + sprintf(temp, " (Build %i", BUILD); strcat(emu_fullversion, temp); #endif #ifdef COMMIT @@ -514,6 +504,16 @@ pc_setup(int argc, wchar_t *argv[]) */ plat_getcwd(usr_path, sizeof_w(usr_path)); + /* + * Initialize the 'stdlog' variable, this is + * somewhat platform-specific. On Windows, it + * will always be 'stdout', but on UNIX-based + * systems, it can be 'stderr' for the console + * mode (since 'stdout' is used by the UI), + * and 'stdout' for the GUI versins, etc... + */ + stdlog = (FILE *)argv; + return(0); } @@ -528,7 +528,9 @@ usage: plat_console(1); #endif printf("\n%s %s\n", emu_title, emu_fullversion); - printf("\nUsage: varcem [options] [cfg-file]\n\n"); + p = plat_get_basename(argv[0]); + if (*p == L'/' || *p == L'\\') p++; + printf("\nUsage: %ls [options] [cfg-file]\n\n", p); printf("Valid options are:\n\n"); printf(" -? or --help - show this information\n"); printf(" -C or --dumpcfg - dump config file after loading\n"); @@ -1245,7 +1247,7 @@ set_screen_size(int x, int y) double dx, dy, dtx, dty; int vid; - DEBUG("SetScreenSize(%d, %d) resize=%d\n", x, y, vid_resize); + DEBUG("SetScreenSize(%i, %i) resize=%i\n", x, y, vid_resize); /* Make sure we keep usable values. */ if (x < 320) x = 320; diff --git a/src/png.c b/src/png.c index 035e4a7..85e08d5 100644 --- a/src/png.c +++ b/src/png.c @@ -8,7 +8,7 @@ * * Provide centralized access to the PNG image handler. * - * Version: @(#)png.c 1.0.3 2018/10/05 + * Version: @(#)png.c 1.0.4 2018/10/07 * * Author: Fred N. van Kempen, * @@ -191,7 +191,8 @@ png_load(void) ui_msgbox(MBX_ERROR, temp); ERRLOG("PNG: unable to load '%s'; format disabled!\n", fn); return(0); - } + } else + INFO("PNG: module '%s' loaded.\n", fn); #else png_handle = (void *)1; /* just to indicate always therse */ #endif diff --git a/src/win/win.c b/src/win/win.c index 83f873e..0bc0d45 100644 --- a/src/win/win.c +++ b/src/win/win.c @@ -8,7 +8,7 @@ * * Platform main support module for Windows. * - * Version: @(#)win.c 1.0.20 2018/10/05 + * Version: @(#)win.c 1.0.21 2018/10/07 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -206,7 +206,7 @@ WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpszArg, int nCmdShow) pc_version("Windows"); /* Set up the basic pathname info for the application. */ - (void)pc_setup(0, NULL); + (void)pc_setup(0, (wchar_t **)stdout); /* Set this to the default value (windowed mode). */ vid_fullscreen = 0; diff --git a/src/win/win_lang.c b/src/win/win_lang.c index b61e394..13f0612 100644 --- a/src/win/win_lang.c +++ b/src/win/win_lang.c @@ -8,7 +8,7 @@ * * Handle language support for the platform. * - * Version: @(#)win_lang.c 1.0.6 2018/10/05 + * Version: @(#)win_lang.c 1.0.7 2018/10/07 * * Author: Fred N. van Kempen, * @@ -119,7 +119,7 @@ plat_lang_scan(void) lflen = wcslen(LANG_FILE); /* Open the "language modules" directory. */ - swprintf(path, sizeof_w(temp), L"%ls%ls", exe_path, LANGUAGE_PATH); + swprintf(path, sizeof_w(path), L"%ls%ls", exe_path, LANGUAGE_PATH); dir = opendir(path); if (dir != NULL) { /* Scan all files, and see if we find a usable one. */ diff --git a/src/win/win_serial.c b/src/win/win_serial.c index 4fec0ff..a3a42bc 100644 --- a/src/win/win_serial.c +++ b/src/win/win_serial.c @@ -12,7 +12,7 @@ * Windows and UNIX systems, with support for FTDI and Prolific * USB ports. Support for these has been removed. * - * Version: @(#)win_serial.c 1.0.3 2018/05/06 + * Version: @(#)win_serial.c 1.0.4 2018/10/07 * * Author: Fred N. van Kempen, * diff --git a/src/win/win_settings_disk.h b/src/win/win_settings_disk.h index 68305dd..1cca1e1 100644 --- a/src/win/win_settings_disk.h +++ b/src/win/win_settings_disk.h @@ -8,7 +8,7 @@ * * Implementation of the Settings dialog. * - * Version: @(#)win_settings_disk.h 1.0.14 2018/09/22 + * Version: @(#)win_settings_disk.h 1.0.15 2018/10/07 * * Authors: Fred N. van Kempen, * Miran Grca, diff --git a/src/win/win_ui.c b/src/win/win_ui.c index 3c8d2ce..5f5c271 100644 --- a/src/win/win_ui.c +++ b/src/win/win_ui.c @@ -8,7 +8,7 @@ * * Implement the user Interface module. * - * Version: @(#)win_ui.c 1.0.26 2018/10/05 + * Version: @(#)win_ui.c 1.0.27 2018/10/07 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -59,11 +59,6 @@ #include "resource.h" -#ifndef GWL_WNDPROC -# define GWL_WNDPROC GWLP_WNDPROC -#endif - - #define TIMER_1SEC 1 /* ID of the one-second timer */ #define ICONS_MAX 256 /* number of icons we can cache */ @@ -194,7 +189,7 @@ StatusBarCreate(uintptr_t id) /* Replace the original procedure with ours. */ stbar_orig_proc = GetWindowLongPtr(hwndSBAR, GWLP_WNDPROC); - SetWindowLongPtr(hwndSBAR, GWL_WNDPROC, (LONG_PTR)sb_dlg_proc); + SetWindowLongPtr(hwndSBAR, GWLP_WNDPROC, (LONG_PTR)sb_dlg_proc); SendMessage(hwndSBAR, SB_SETMINHEIGHT, (WPARAM)SB_HEIGHT, (LPARAM)0); @@ -563,14 +558,14 @@ plat_set_input(HWND h) { /* If needed, rest the old one first. */ if (input_orig_hwnd != NULL) { - SetWindowLongPtr(input_orig_hwnd, GWL_WNDPROC, + SetWindowLongPtr(input_orig_hwnd, GWLP_WNDPROC, (LONG_PTR)input_orig_proc); } /* Redirect the window procedure so we can catch WM_INPUT. */ input_orig_proc = GetWindowLongPtr(h, GWLP_WNDPROC); input_orig_hwnd = h; - SetWindowLongPtr(h, GWL_WNDPROC, (LONG_PTR)input_proc); + SetWindowLongPtr(h, GWLP_WNDPROC, (LONG_PTR)input_proc); }