diff --git a/src/86box.h b/src/86box.h index c59566e45..6e9034139 100644 --- a/src/86box.h +++ b/src/86box.h @@ -8,7 +8,7 @@ * * Main include file for the application. * - * Version: @(#)86box.h 1.0.32 2019/10/31 + * Version: @(#)86box.h 1.0.33 2019/11/01 * * Authors: Miran Grca, *f Fred N. van Kempen, @@ -30,8 +30,8 @@ #define EMU_NAME "86Box" #define EMU_NAME_W L"86Box" #ifdef RELEASE_BUILD -#define EMU_VERSION "2.04" -#define EMU_VERSION_W L"2.04" +#define EMU_VERSION "2.05" +#define EMU_VERSION_W L"2.05" #else #define EMU_VERSION "2.10" #define EMU_VERSION_W L"2.10" diff --git a/src/disk/hdc_esdi_at.c b/src/disk/hdc_esdi_at.c index e3bc9aa62..6e3946a80 100644 --- a/src/disk/hdc_esdi_at.c +++ b/src/disk/hdc_esdi_at.c @@ -8,15 +8,15 @@ * * Driver for the ESDI controller (WD1007-vse1) for PC/AT. * - * Version: @(#)hdc_esdi_at.c 1.0.14 2018/10/17 + * Version: @(#)hdc_esdi_at.c 1.0.15 2018/10/31 * * Authors: Sarah Walker, * Miran Grca, * Fred N. van Kempen, * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - * Copyright 2017,2018 Fred N. van Kempen. + * Copyright 2008-2019 Sarah Walker. + * Copyright 2016-2019 Miran Grca. + * Copyright 2017-2019 Fred N. van Kempen. */ #define _LARGEFILE_SOURCE #define _LARGEFILE64_SOURCE @@ -98,8 +98,7 @@ typedef struct { uint16_t buffer[256]; int irqstat; - uint64_t callback; - pc_timer_t timer; + pc_timer_t callback_timer; drive_t drives[2]; @@ -127,7 +126,7 @@ esdi_at_log(const char *fmt, ...) #endif -static inline void +static __inline void irq_raise(esdi_t *esdi) { if (!(esdi->fdisk & 2)) @@ -137,15 +136,18 @@ irq_raise(esdi_t *esdi) } -static inline void +static __inline void irq_lower(esdi_t *esdi) { - if (esdi->irqstat) { - if (!(esdi->fdisk & 2)) - picintc(1 << 14); + picintc(1 << 14); +} - esdi->irqstat = 0; - } + +static __inline void +irq_update(esdi_t *esdi) +{ + if (esdi->irqstat && !((pic2.pend | pic2.ins) & 0x40) && !(esdi->fdisk & 2)) + picint(1 << 14); } @@ -209,21 +211,6 @@ next_sector(esdi_t *esdi) } } -static void -esdi_set_callback(esdi_t *esdi, uint64_t callback) -{ - if (!esdi) { - return; - } - - if (callback) { - esdi->callback = callback; - timer_set_delay_u64(&esdi->timer, esdi->callback); - } else { - esdi->callback = 0; - timer_disable(&esdi->timer); - } -} static void esdi_writew(uint16_t port, uint16_t val, void *priv) @@ -237,7 +224,7 @@ esdi_writew(uint16_t port, uint16_t val, void *priv) esdi->pos = 0; esdi->status = STAT_BUSY; /* 390.625 us per sector at 10 Mbit/s = 1280 kB/s. */ - esdi_set_callback(esdi, (3125 * TIMER_USEC) / 8); + timer_set_delay_u64(&esdi->callback_timer, (3125 * TIMER_USEC) / 8); } } @@ -277,11 +264,10 @@ esdi_write(uint16_t port, uint8_t val, void *priv) case 0x1f6: /* drive/Head */ esdi->head = val & 0xF; esdi->drive_sel = (val & 0x10) ? 1 : 0; - if (esdi->drives[esdi->drive_sel].present) { - esdi->status = STAT_READY|STAT_DSC; - } else { + if (esdi->drives[esdi->drive_sel].present) + esdi->status = STAT_READY | STAT_DSC; + else esdi->status = 0; - } return; case 0x1f7: /* command register */ @@ -295,20 +281,20 @@ esdi_write(uint16_t port, uint8_t val, void *priv) case CMD_RESTORE: esdi->command &= ~0x0f; /*mask off step rate*/ esdi->status = STAT_BUSY; - esdi_set_callback(esdi, 200 * HDC_TIME); + timer_set_delay_u64(&esdi->callback_timer, 200 * HDC_TIME); break; case CMD_SEEK: esdi->command &= ~0x0f; /*mask off step rate*/ esdi->status = STAT_BUSY; - esdi_set_callback(esdi, 200 * HDC_TIME); + timer_set_delay_u64(&esdi->callback_timer, 200 * HDC_TIME); break; default: switch (val) { case CMD_NOP: esdi->status = STAT_BUSY; - esdi_set_callback(esdi, 200 * HDC_TIME); + timer_set_delay_u64(&esdi->callback_timer, 200 * HDC_TIME); break; case CMD_READ: @@ -321,7 +307,7 @@ esdi_write(uint16_t port, uint8_t val, void *priv) case 0xa0: esdi->status = STAT_BUSY; - esdi_set_callback(esdi, 200 * HDC_TIME); + timer_set_delay_u64(&esdi->callback_timer, 200 * HDC_TIME); break; case CMD_WRITE: @@ -339,7 +325,7 @@ esdi_write(uint16_t port, uint8_t val, void *priv) case CMD_VERIFY+1: esdi->command &= ~0x01; esdi->status = STAT_BUSY; - esdi_set_callback(esdi, 200 * HDC_TIME); + timer_set_delay_u64(&esdi->callback_timer, 200 * HDC_TIME); break; case CMD_FORMAT: @@ -349,25 +335,25 @@ esdi_write(uint16_t port, uint8_t val, void *priv) case CMD_SET_PARAMETERS: /* Initialize Drive Parameters */ esdi->status = STAT_BUSY; - esdi_set_callback(esdi, 30 * HDC_TIME); + timer_set_delay_u64(&esdi->callback_timer, 30 * HDC_TIME); break; case CMD_DIAGNOSE: /* Execute Drive Diagnostics */ esdi->status = STAT_BUSY; - esdi_set_callback(esdi, 200 * HDC_TIME); + timer_set_delay_u64(&esdi->callback_timer, 200 * HDC_TIME); break; case 0xe0: /*???*/ case CMD_READ_PARAMETERS: esdi->status = STAT_BUSY; - esdi_set_callback(esdi, 200 * HDC_TIME); + timer_set_delay_u64(&esdi->callback_timer, 200 * HDC_TIME); break; default: esdi_at_log("WD1007: bad command %02X\n", val); case 0xe8: /*???*/ esdi->status = STAT_BUSY; - esdi_set_callback(esdi, 200 * HDC_TIME); + timer_set_delay_u64(&esdi->callback_timer, 200 * HDC_TIME); break; } } @@ -375,20 +361,18 @@ esdi_write(uint16_t port, uint8_t val, void *priv) case 0x3f6: /* Device control */ if ((esdi->fdisk & 0x04) && !(val & 0x04)) { - esdi_set_callback(esdi, 500 * HDC_TIME); + timer_set_delay_u64(&esdi->callback_timer, 500 * HDC_TIME); esdi->reset = 1; esdi->status = STAT_BUSY; } if (val & 0x04) { - /*Drive held in reset*/ - esdi_set_callback(esdi, 0); + /* Drive held in reset. */ + timer_disable(&esdi->callback_timer); esdi->status = STAT_BUSY; } esdi->fdisk = val; - /* Lower IRQ on IRQ disable. */ - if ((val & 2) && !(esdi->fdisk & 0x02)) - picintc(1 << 14); + irq_update(esdi); break; } } @@ -412,7 +396,7 @@ esdi_readw(uint16_t port, void *priv) next_sector(esdi); esdi->status = STAT_BUSY; /* 390.625 us per sector at 10 Mbit/s = 1280 kB/s. */ - esdi_set_callback(esdi, (3125 * TIMER_USEC) / 8); + timer_set_delay_u64(&esdi->callback_timer, (3125 * TIMER_USEC) / 8); } else { ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 0); } @@ -447,15 +431,15 @@ esdi_read(uint16_t port, void *priv) break; case 0x1f4: /* cylinder low */ - temp = (uint8_t)(esdi->cylinder&0xff); + temp = (uint8_t) (esdi->cylinder&0xff); break; case 0x1f5: /* cylinder high */ - temp = (uint8_t)(esdi->cylinder>>8); + temp = (uint8_t) (esdi->cylinder>>8); break; case 0x1f6: /* drive/Head */ - temp = (uint8_t)(0xa0|esdi->head|(esdi->drive_sel?0x10:0)); + temp = (uint8_t) (esdi->head | (esdi->drive_sel ? 0x10 : 0) | 0xa0); break; case 0x1f7: /* status */ @@ -477,8 +461,6 @@ esdi_callback(void *priv) drive_t *drive = &esdi->drives[esdi->drive_sel]; off64_t addr; - esdi_set_callback(esdi, 0); - if (esdi->reset) { esdi->status = STAT_READY|STAT_DSC; esdi->error = 1; @@ -489,11 +471,10 @@ esdi_callback(void *priv) esdi->reset = 0; ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 0); - return; } - esdi_at_log("WD1007: command %02x\n", esdi->command); + esdi_at_log("WD1007: command %02x on drive %i\n", esdi->command, esdi->drive_sel); switch (esdi->command) { case CMD_RESTORE: @@ -511,9 +492,8 @@ esdi_callback(void *priv) if (! drive->present) { esdi->status = STAT_READY|STAT_ERR|STAT_DSC; esdi->error = ERR_ABRT; - } else { + } else esdi->status = STAT_READY|STAT_DSC; - } irq_raise(esdi); break; @@ -522,23 +502,26 @@ esdi_callback(void *priv) esdi->status = STAT_READY|STAT_ERR|STAT_DSC; esdi->error = ERR_ABRT; irq_raise(esdi); - break; - } + } else { + if (get_sector(esdi, &addr)) { + esdi->error = ERR_ID_NOT_FOUND; + esdi->status = STAT_READY|STAT_DSC|STAT_ERR; + irq_raise(esdi); + break; + } - if (get_sector(esdi, &addr)) { - esdi->error = ERR_ID_NOT_FOUND; - esdi->status = STAT_READY|STAT_DSC|STAT_ERR; + if (hdd_image_read_ex(drive->hdd_num, addr, 1, (uint8_t *)esdi->buffer)) { + esdi->error = ERR_ID_NOT_FOUND; + esdi->status = STAT_READY | STAT_DSC | STAT_ERR; + irq_raise(esdi); + break; + } + + esdi->pos = 0; + esdi->status = STAT_DRQ|STAT_READY|STAT_DSC; irq_raise(esdi); - break; + ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 1); } - - hdd_image_read(drive->hdd_num, addr, 1, - (uint8_t *)esdi->buffer); - - esdi->pos = 0; - esdi->status = STAT_DRQ|STAT_READY|STAT_DSC; - irq_raise(esdi); - ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 1); break; case CMD_WRITE: @@ -547,28 +530,31 @@ esdi_callback(void *priv) esdi->error = ERR_ABRT; irq_raise(esdi); break; - } - - if (get_sector(esdi, &addr)) { - esdi->error = ERR_ID_NOT_FOUND; - esdi->status = STAT_READY|STAT_DSC|STAT_ERR; - irq_raise(esdi); - break; - } - - hdd_image_write(drive->hdd_num, addr, 1, - (uint8_t *)esdi->buffer); - - irq_raise(esdi); - esdi->secount = (esdi->secount - 1) & 0xff; - if (esdi->secount) { - esdi->status = STAT_DRQ|STAT_READY|STAT_DSC; - esdi->pos = 0; - next_sector(esdi); } else { - esdi->status = STAT_READY|STAT_DSC; + if (get_sector(esdi, &addr)) { + esdi->error = ERR_ID_NOT_FOUND; + esdi->status = STAT_READY|STAT_DSC|STAT_ERR; + irq_raise(esdi); + break; + } + + if (hdd_image_write_ex(drive->hdd_num, addr, 1, (uint8_t *)esdi->buffer)) { + esdi->error = ERR_ID_NOT_FOUND; + esdi->status = STAT_READY | STAT_DSC | STAT_ERR; + irq_raise(esdi); + break; + } + + irq_raise(esdi); + esdi->secount = (esdi->secount - 1) & 0xff; + if (esdi->secount) { + esdi->status = STAT_DRQ|STAT_READY|STAT_DSC; + esdi->pos = 0; + next_sector(esdi); + } else + esdi->status = STAT_READY|STAT_DSC; + ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 1); } - ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 1); break; case CMD_VERIFY: @@ -577,27 +563,31 @@ esdi_callback(void *priv) esdi->error = ERR_ABRT; irq_raise(esdi); break; - } + } else { + if (get_sector(esdi, &addr)) { + esdi->error = ERR_ID_NOT_FOUND; + esdi->status = STAT_READY|STAT_DSC|STAT_ERR; + irq_raise(esdi); + break; + } - if (get_sector(esdi, &addr)) { - esdi->error = ERR_ID_NOT_FOUND; - esdi->status = STAT_READY|STAT_DSC|STAT_ERR; - irq_raise(esdi); - break; - } + if (hdd_image_read_ex(drive->hdd_num, addr, 1, (uint8_t *)esdi->buffer)) { + esdi->error = ERR_ID_NOT_FOUND; + esdi->status = STAT_READY | STAT_DSC | STAT_ERR; + irq_raise(esdi); + break; + } - hdd_image_read(drive->hdd_num, addr, 1, - (uint8_t *)esdi->buffer); - - ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 1); - next_sector(esdi); - esdi->secount = (esdi->secount - 1) & 0xff; - if (esdi->secount) - esdi_set_callback(esdi, 6 * HDC_TIME); - else { - esdi->pos = 0; - esdi->status = STAT_READY|STAT_DSC; - irq_raise(esdi); + ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 1); + next_sector(esdi); + esdi->secount = (esdi->secount - 1) & 0xff; + if (esdi->secount) + timer_set_delay_u64(&esdi->callback_timer, 6 * HDC_TIME); + else { + esdi->pos = 0; + esdi->status = STAT_READY|STAT_DSC; + irq_raise(esdi); + } } break; @@ -607,45 +597,54 @@ esdi_callback(void *priv) esdi->error = ERR_ABRT; irq_raise(esdi); break; - } + } else { + if (get_sector(esdi, &addr)) { + esdi->error = ERR_ID_NOT_FOUND; + esdi->status = STAT_READY|STAT_DSC|STAT_ERR; + irq_raise(esdi); + break; + } - if (get_sector(esdi, &addr)) { - esdi->error = ERR_ID_NOT_FOUND; - esdi->status = STAT_READY|STAT_DSC|STAT_ERR; + if (hdd_image_zero_ex(drive->hdd_num, addr, esdi->secount)) { + esdi->error = ERR_ID_NOT_FOUND; + esdi->status = STAT_READY | STAT_DSC | STAT_ERR; + irq_raise(esdi); + break; + } + + esdi->status = STAT_READY|STAT_DSC; irq_raise(esdi); - break; + ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 1); } - - hdd_image_zero(drive->hdd_num, addr, esdi->secount); - - esdi->status = STAT_READY|STAT_DSC; - irq_raise(esdi); - ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 1); break; case CMD_DIAGNOSE: + /* This is basically controller diagnostics - it resets drive select to 0, + and resets error and status to ready, DSC, and no error detected. */ + esdi->drive_sel = 0; + drive = &esdi->drives[esdi->drive_sel]; + esdi->error = 1; /*no error detected*/ esdi->status = STAT_READY|STAT_DSC; irq_raise(esdi); break; case CMD_SET_PARAMETERS: /* Initialize Drive Parameters */ - if (drive->present == 0) { + if (! drive->present) { esdi->status = STAT_READY|STAT_ERR|STAT_DSC; esdi->error = ERR_ABRT; irq_raise(esdi); - break; + } else { + drive->cfg_spt = esdi->secount; + drive->cfg_hpc = esdi->head+1; + + esdi_at_log("WD1007: parameters: spt=%i hpc=%i\n", drive->cfg_spt,drive->cfg_hpc); + + if (! esdi->secount) + fatal("WD1007: secount=0\n"); + esdi->status = STAT_READY|STAT_DSC; + irq_raise(esdi); } - - drive->cfg_spt = esdi->secount; - drive->cfg_hpc = esdi->head+1; - - esdi_at_log("WD1007: parameters: spt=%i hpc=%i\n", drive->cfg_spt,drive->cfg_hpc); - - if (! esdi->secount) - fatal("WD1007: secount=0\n"); - esdi->status = STAT_READY|STAT_DSC; - irq_raise(esdi); break; case CMD_NOP: @@ -660,31 +659,30 @@ esdi_callback(void *priv) esdi->error = ERR_ABRT; irq_raise(esdi); break; + } else { + switch (esdi->cylinder >> 8) { + case 0x31: + esdi->cylinder = drive->real_tracks; + break; + + case 0x33: + esdi->cylinder = drive->real_hpc; + break; + + case 0x35: + esdi->cylinder = 0x200; + break; + + case 0x36: + esdi->cylinder = drive->real_spt; + break; + + default: + esdi_at_log("WD1007: bad read config %02x\n", esdi->cylinder >> 8); + } + esdi->status = STAT_READY|STAT_DSC; + irq_raise(esdi); } - - switch (esdi->cylinder >> 8) { - case 0x31: - esdi->cylinder = drive->real_tracks; - break; - - case 0x33: - esdi->cylinder = drive->real_hpc; - break; - - case 0x35: - esdi->cylinder = 0x200; - break; - - case 0x36: - esdi->cylinder = drive->real_spt; - break; - - default: - esdi_at_log("WD1007: bad read config %02x\n", - esdi->cylinder >> 8); - } - esdi->status = STAT_READY|STAT_DSC; - irq_raise(esdi); break; case 0xa0: @@ -705,35 +703,34 @@ esdi_callback(void *priv) esdi->status = STAT_READY|STAT_ERR|STAT_DSC; esdi->error = ERR_ABRT; irq_raise(esdi); - break; + } else { + memset(esdi->buffer, 0x00, 512); + esdi->buffer[0] = 0x44; /* general configuration */ + esdi->buffer[1] = drive->real_tracks; /* number of non-removable cylinders */ + esdi->buffer[2] = 0; /* number of removable cylinders */ + esdi->buffer[3] = drive->real_hpc; /* number of heads */ + esdi->buffer[4] = 600; /* number of unformatted bytes/sector */ + esdi->buffer[5] = esdi->buffer[4] * drive->real_spt; /* number of unformatted bytes/track */ + esdi->buffer[6] = drive->real_spt; /* number of sectors */ + esdi->buffer[7] = 0; /*minimum bytes in inter-sector gap*/ + esdi->buffer[8] = 0; /* minimum bytes in postamble */ + esdi->buffer[9] = 0; /* number of words of vendor status */ + /* controller info */ + esdi->buffer[20] = 2; /* controller type */ + esdi->buffer[21] = 1; /* sector buffer size, in sectors */ + esdi->buffer[22] = 0; /* ecc bytes appended */ + esdi->buffer[27] = 'W' | ('D' << 8); + esdi->buffer[28] = '1' | ('0' << 8); + esdi->buffer[29] = '0' | ('7' << 8); + esdi->buffer[30] = 'V' | ('-' << 8); + esdi->buffer[31] = 'S' | ('E' << 8); + esdi->buffer[32] = '1'; + esdi->buffer[47] = 0; /* sectors per interrupt */ + esdi->buffer[48] = 0; /* can use double word read/write? */ + esdi->pos = 0; + esdi->status = STAT_DRQ|STAT_READY|STAT_DSC; + irq_raise(esdi); } - - memset(esdi->buffer, 0x00, 512); - esdi->buffer[0] = 0x44; /* general configuration */ - esdi->buffer[1] = drive->real_tracks; /* number of non-removable cylinders */ - esdi->buffer[2] = 0; /* number of removable cylinders */ - esdi->buffer[3] = drive->real_hpc; /* number of heads */ - esdi->buffer[4] = 600; /* number of unformatted bytes/track */ - esdi->buffer[5] = esdi->buffer[4] * drive->real_spt; /* number of unformatted bytes/sector */ - esdi->buffer[6] = drive->real_spt; /* number of sectors */ - esdi->buffer[7] = 0; /*minimum bytes in inter-sector gap*/ - esdi->buffer[8] = 0; /* minimum bytes in postamble */ - esdi->buffer[9] = 0; /* number of words of vendor status */ - /* controller info */ - esdi->buffer[20] = 2; /* controller type */ - esdi->buffer[21] = 1; /* sector buffer size, in sectors */ - esdi->buffer[22] = 0; /* ecc bytes appended */ - esdi->buffer[27] = 'W' | ('D' << 8); - esdi->buffer[28] = '1' | ('0' << 8); - esdi->buffer[29] = '0' | ('7' << 8); - esdi->buffer[30] = 'V' | ('-' << 8); - esdi->buffer[31] = 'S' | ('E' << 8); - esdi->buffer[32] = '1'; - esdi->buffer[47] = 0; /* sectors per interrupt */ - esdi->buffer[48] = 0; /* can use double word read/write? */ - esdi->pos = 0; - esdi->status = STAT_DRQ|STAT_READY|STAT_DSC; - irq_raise(esdi); break; default: @@ -770,6 +767,18 @@ loadhd(esdi_t *esdi, int hdd_num, int d, const wchar_t *fn) } +static void +esdi_rom_write(uint32_t addr, uint8_t val, void *p) +{ + rom_t *rom = (rom_t *)p; + + addr &= rom->mask; + + if (addr >= 0x1f00 && addr < 0x2000) + rom->rom[addr] = val; +} + + static void * wd1007vse1_init(const device_t *info) { @@ -793,6 +802,10 @@ wd1007vse1_init(const device_t *info) rom_init(&esdi->bios_rom, BIOS_FILE, 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + mem_mapping_set_handler(&esdi->bios_rom.mapping, + rom_read, rom_readw, rom_readl, + esdi_rom_write, NULL, NULL); + io_sethandler(0x01f0, 1, esdi_read, esdi_readw, NULL, esdi_write, esdi_writew, NULL, esdi); @@ -802,7 +815,7 @@ wd1007vse1_init(const device_t *info) io_sethandler(0x03f6, 1, NULL, NULL, NULL, esdi_write, NULL, NULL, esdi); - timer_add(&esdi->timer, esdi_callback, esdi, 0); + timer_add(&esdi->callback_timer, esdi_callback, esdi, 0); ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0); diff --git a/src/disk/hdc_ide.c b/src/disk/hdc_ide.c index 4464f0018..1e44453c2 100644 --- a/src/disk/hdc_ide.c +++ b/src/disk/hdc_ide.c @@ -9,7 +9,7 @@ * Implementation of the IDE emulation for hard disks and ATAPI * CD-ROM devices. * - * Version: @(#)hdc_ide.c 1.0.61 2019/10/20 + * Version: @(#)hdc_ide.c 1.0.62 2019/10/31 * * Authors: Sarah Walker, * Miran Grca, @@ -114,7 +114,8 @@ typedef struct { int bit32, cur_dev, - irq, inited; + irq, inited, + diag; uint16_t base_main, side_main; pc_timer_t timer; } ide_board_t; @@ -252,34 +253,6 @@ ide_get_period(ide_t *ide, int size) } -#if 0 -int64_t -ide_get_seek_time(ide_t *ide, uint32_t new_pos) -{ - double dusec, time; - uint32_t pos = hdd_image_get_pos(ide->hdd_num); - uint32_t t, nt; - t = pos / ide->spt; - nt = new_pos / ide->spt; - - dusec = (double) TIMER_USEC; - time = (1000000.0 / 2800.0) * dusec; /* Revolution (1/2800 s). */ - - if ((t % ide->hpc) != (pos % ide->hpc)) /* Head change. */ - time += (dusec / 250.0); /* 4ns */ - - t /= ide->hpc; - nt /= ide->hpc; - - if (t != nt) { - t = ABS(t - nt); - time += ((40000.0 * dusec) / ((double) ide->tracks)) * ((double) t); - } - return (int64_t) time; -} -#endif - - void ide_irq_raise(ide_t *ide) { @@ -836,7 +809,10 @@ ide_set_callback(uint8_t board, double callback) return; } - timer_on_auto(&dev->timer, callback); + if (callback == 0.0) + timer_stop(&dev->timer); + else + timer_on_auto(&dev->timer, callback); } @@ -1176,6 +1152,25 @@ ide_writel(uint16_t addr, uint32_t val, void *priv) } +static void +dev_reset(ide_t *ide) +{ + ide_set_signature(ide); + ide->error = 1; /*No error detected*/ + + if (ide->type == IDE_ATAPI) { + ide->sc->status = 0; + ide->sc->error = 1; + ide_irq_raise(ide); + if (ide->stop) + ide->stop(ide->sc); + } else { + ide->atastat = DRDY_STAT | DSC_STAT; + ide->error = 1; + } +} + + void ide_write_devctl(uint16_t addr, uint8_t val, void *priv) { @@ -1190,27 +1185,39 @@ ide_write_devctl(uint16_t addr, uint8_t val, void *priv) ide_log("ide_write_devctl %04X %02X from %04X(%08X):%08X\n", addr, val, CS, cs, cpu_state.pc); - if ((ide->fdisk & 4) && !(val&4) && (ide->type != IDE_NONE || ide_other->type != IDE_NONE)) { + if ((ide->type == IDE_NONE) && (ide_other->type == IDE_NONE)) + return; + + dev->diag = 0; + + if ((val & 4) && !(ide->fdisk & 4)) { + /* Reset toggled from 0 to 1, initiate reset procedure. */ if (ide->type == IDE_ATAPI) ide->sc->callback = 0.0; - ide_set_callback(ide->board, 500 * IDE_TIME); - - if (ide->type != IDE_NONE) - ide->reset = 1; - if (ide_other->type != IDE_NONE) - ide->reset = 1; + ide_set_callback(ide->board, 0.0); + ide->atastat = BSY_STAT; if (ide->type == IDE_ATAPI) ide->sc->status = BSY_STAT; - ide->atastat = ide_other->atastat = BSY_STAT; + dev_reset(ide); + } else if (!(val & 4) && (ide->fdisk & 4)) { + /* Reset toggled from 1 to 0. */ + if (!(ch & 1)) { + /* Currently active device is 0, fire the timer. */ + if (ide->type == IDE_ATAPI) + ide->sc->callback = 0.4; + ide_set_callback(ide->board, 0.4); + ide->reset = 1; + } else { + /* Currently active device is 1, simply reset the status and the active device. */ + ide->atastat = 0x50; + if (ide->type == IDE_ATAPI) + ide->sc->status = DRDY_STAT | DSC_STAT; + ide->atastat = DRDY_STAT | DSC_STAT; + dev->cur_dev &= ~1; + } } - if (val & 4) { - /*Drive held in reset*/ - ide_set_callback(ide->board, 0.0); - ide->atastat = ide_other->atastat = BSY_STAT; - } ide->fdisk = ide_other->fdisk = val; - return; } @@ -1487,18 +1494,18 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv) return; case WIN_DRIVE_DIAGNOSTICS: /* Execute Drive Diagnostics */ + ide->atastat = BSY_STAT; + dev_reset(ide); + if (!(ch & 1)) + dev_reset(ide_other); + dev->diag = 1; + if (ide->type == IDE_ATAPI) { ide->sc->status = BSY_STAT; - ide->sc->callback = 200.0 * IDE_TIME; - } else - ide->atastat = BSY_STAT; - - if (ide_other->type == IDE_ATAPI) - ide_other->sc->status = BSY_STAT; - else - ide_other->atastat = BSY_STAT; - - ide_set_callback(ide->board, 200.0 * IDE_TIME); + ide->sc->callback = 0.4; + } + ide_set_callback(ide->board, 0.4); + ide->reset = 1; return; case WIN_PIDENTIFY: /* Identify Packet Device */ @@ -1816,34 +1823,33 @@ ide_callback(void *priv) if (ide->reset) { ide_log("CALLBACK RESET %i %i\n", ide->reset,ch); - ide->atastat = ide_other->atastat = DRDY_STAT | DSC_STAT; - ide->error = ide_other->error = 1; - ide->secount = ide_other->secount = 1; - ide->sector = ide_other->sector = 1; - ide->head = ide_other->head = 0; - ide->cylinder = ide_other->cylinder = 0; + ide = ide_drives[ch & ~1]; + ide_other = ide_drives[ch | 1]; - // ide->cfg_spt = ide->cfg_hpc = 0; /* need new parameters (drive 0) */ - // ide_other->cfg_spt = ide_other->cfg_hpc = 0; /* need new parameters (drive 1) */ + if (!dev->diag) + dev_reset(ide_other); - ide->reset = ide_other->reset = 0; - - ide_set_signature(ide); - if (ide->type == IDE_ATAPI) { + ide->atastat = DRDY_STAT | DSC_STAT; + if (ide->type == IDE_ATAPI) ide->sc->status = DRDY_STAT | DSC_STAT; - ide->sc->error = 1; - if (ide->stop) - ide->stop(ide->sc); - } - ide_set_signature(ide_other); - if (ide_other->type == IDE_ATAPI) { + ide_other->atastat = DRDY_STAT | DSC_STAT; + if (ide_other->type == IDE_ATAPI) ide_other->sc->status = DRDY_STAT | DSC_STAT; - ide_other->sc->error = 1; - if (ide_other->stop) - ide_other->stop(ide_other->sc); + + dev->cur_dev &= ~1; + + if (dev->diag) { + dev->diag = 0; + ide_irq_raise(ide); } + if (ide->type == IDE_ATAPI) + ide->sc->callback = 0.0; + if (ide_other->type == IDE_ATAPI) + ide_other->sc->callback = 0.0; + ide_set_callback(ide->board, 0.0); + ide->reset = 0; return; } @@ -2136,35 +2142,6 @@ ide_callback(void *priv) ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 1); return; - case WIN_DRIVE_DIAGNOSTICS: - ide_set_signature(ide); - ide->error = 1; /*No error detected*/ - - if (ide->type == IDE_ATAPI) { - ide->sc->status = 0; - ide->sc->error = 1; - ide_irq_raise(ide); - } else { - ide->atastat = DRDY_STAT | DSC_STAT; - ide->error = 1; - ide_irq_raise(ide); - } - - ide_set_signature(ide_other); - ide_other->error = 1; /*No error detected*/ - - if (ide_other->type == IDE_ATAPI) { - ide_other->sc->status = 0; - ide_other->sc->error = 1; - } else { - ide_other->atastat = DRDY_STAT | DSC_STAT; - ide_other->error = 1; - } - - ide_boards[ide->board]->cur_dev &= ~1; - ch = ide_boards[ide->board]->cur_dev; - return; - case WIN_SPECIFY: /* Initialize Drive Parameters */ if (ide->type == IDE_ATAPI) goto abort_cmd; diff --git a/src/disk/hdc_st506_at.c b/src/disk/hdc_st506_at.c index cde098d2c..683ade1fc 100644 --- a/src/disk/hdc_st506_at.c +++ b/src/disk/hdc_st506_at.c @@ -12,7 +12,7 @@ * based design. Most cards were WD1003-WA2 or -WAH, where the * -WA2 cards had a floppy controller as well (to save space.) * - * Version: @(#)hdc_st506_at.c 1.0.20 2019/09/29 + * Version: @(#)hdc_st506_at.c 1.0.21 2019/11/01 * * Authors: Sarah Walker, * Fred N. van Kempen, @@ -112,8 +112,7 @@ typedef struct { pad; int pos; /* offset within data buffer */ - uint64_t callback; /* callback delay timer */ - pc_timer_t timer; + pc_timer_t callback_timer; /* callback delay timer */ uint16_t buffer[256]; /* data buffer (16b wide) */ @@ -154,12 +153,16 @@ irq_raise(mfm_t *mfm) static inline void irq_lower(mfm_t *mfm) { - if (mfm->irqstat) { - if (!(mfm->fdisk & 2)) - picintc(1 << 14); + picintc(1 << 14); +} - mfm->irqstat = 0; - } + + +static void +irq_update(mfm_t *mfm) +{ + if (mfm->irqstat && !((pic2.pend | pic2.ins) & 0x40) && !(mfm->fdisk & 2)) + picint(1 << 14); } @@ -182,12 +185,10 @@ get_sector(mfm_t *mfm, off64_t *addr) /* FIXME: See if this is even needed - if the code is present, IBM AT diagnostics v2.07 will error with: ERROR 152 - SYSTEM BOARD. */ -#ifdef FIXME if (drive->curcyl != mfm->cylinder) { st506_at_log("WD1003(%d) sector: wrong cylinder\n"); return(1); } -#endif if (mfm->head > drive->cfg_hpc) { st506_at_log("WD1003(%d) get_sector: past end of configured heads\n", @@ -201,7 +202,6 @@ get_sector(mfm_t *mfm, off64_t *addr) return(1); } -#if 1 /* We should check this in the SET_DRIVE_PARAMETERS command! --FvK */ if (mfm->head > drive->hpc) { st506_at_log("WD1003(%d) get_sector: past end of heads\n", mfm->drvsel); @@ -212,7 +212,6 @@ get_sector(mfm_t *mfm, off64_t *addr) st506_at_log("WD1003(%d) get_sector: past end of sectors\n", mfm->drvsel); return(1); } -#endif *addr = ((((off64_t) mfm->cylinder * drive->cfg_hpc) + mfm->head) * drive->cfg_spt) + (mfm->sector - 1); @@ -238,20 +237,6 @@ next_sector(mfm_t *mfm) } } -static void -mfm_set_callback(mfm_t *mfm, uint64_t callback) -{ - if (!mfm) - return; - - if (callback) { - mfm->callback = callback; - timer_set_delay_u64(&mfm->timer, mfm->callback); - } else { - mfm->callback = 0ULL; - timer_disable(&mfm->timer); - } -} static void mfm_cmd(mfm_t *mfm, uint8_t val) @@ -264,7 +249,7 @@ mfm_cmd(mfm_t *mfm, uint8_t val) mfm->drvsel, val); mfm->command = 0xff; mfm->status = STAT_BUSY; - mfm_set_callback(mfm, 200 * MFM_TIME); + timer_set_delay_u64(&mfm->callback_timer, 200 * MFM_TIME); return; } @@ -278,6 +263,7 @@ mfm_cmd(mfm_t *mfm, uint8_t val) st506_at_log("WD1003(%d) restore, step=%d\n", mfm->drvsel, drive->steprate); drive->curcyl = 0; + mfm->cylinder = 0; mfm->status = STAT_READY|STAT_DSC; mfm->command &= 0xf0; irq_raise(mfm); @@ -287,7 +273,7 @@ mfm_cmd(mfm_t *mfm, uint8_t val) drive->steprate = (val & 0x0f); mfm->command &= 0xf0; mfm->status = STAT_BUSY; - mfm_set_callback(mfm, 200 * MFM_TIME); + timer_set_delay_u64(&mfm->callback_timer, 200 * MFM_TIME); break; default: @@ -303,7 +289,7 @@ mfm_cmd(mfm_t *mfm, uint8_t val) if (val & 2) fatal("WD1003: READ with ECC\n"); mfm->status = STAT_BUSY; - mfm_set_callback(mfm, 200 * MFM_TIME); + timer_set_delay_u64(&mfm->callback_timer, 200 * MFM_TIME); break; case CMD_WRITE: @@ -323,7 +309,7 @@ mfm_cmd(mfm_t *mfm, uint8_t val) case CMD_VERIFY+1: mfm->command &= 0xfe; mfm->status = STAT_BUSY; - mfm_set_callback(mfm, 200 * MFM_TIME); + timer_set_delay_u64(&mfm->callback_timer, 200 * MFM_TIME); break; case CMD_FORMAT: @@ -333,7 +319,7 @@ mfm_cmd(mfm_t *mfm, uint8_t val) case CMD_DIAGNOSE: mfm->status = STAT_BUSY; - mfm_set_callback(mfm, 200 * MFM_TIME); + timer_set_delay_u64(&mfm->callback_timer, 200 * MFM_TIME); break; case CMD_SET_PARAMETERS: @@ -374,7 +360,7 @@ mfm_cmd(mfm_t *mfm, uint8_t val) default: st506_at_log("WD1003: bad command %02X\n", val); mfm->status = STAT_BUSY; - mfm_set_callback(mfm, 200 * MFM_TIME); + timer_set_delay_u64(&mfm->callback_timer, 200 * MFM_TIME); break; } } @@ -392,7 +378,7 @@ mfm_writew(uint16_t port, uint16_t val, void *priv) if (mfm->pos >= 512) { mfm->pos = 0; mfm->status = STAT_BUSY; - mfm_set_callback(mfm, SECTOR_TIME); + timer_set_delay_u64(&mfm->callback_timer, SECTOR_TIME); } } @@ -445,20 +431,18 @@ mfm_write(uint16_t port, uint8_t val, void *priv) case 0x03f6: /* device control */ val &= 0x0f; if ((mfm->fdisk & 0x04) && !(val & 0x04)) { - mfm_set_callback(mfm, 500 * MFM_TIME); + timer_set_delay_u64(&mfm->callback_timer, 500 * MFM_TIME); mfm->reset = 1; mfm->status = STAT_BUSY; } if (val & 0x04) { /* Drive held in reset. */ - mfm_set_callback(mfm, 0); + timer_disable(&mfm->callback_timer); mfm->status = STAT_BUSY; } mfm->fdisk = val; - /* Lower IRQ on IRQ disable. */ - if ((val & 2) && !(mfm->fdisk & 0x02)) - picintc(1 << 14); + irq_update(mfm); break; } } @@ -480,7 +464,7 @@ mfm_readw(uint16_t port, void *priv) if (mfm->secount) { next_sector(mfm); mfm->status = STAT_BUSY; - mfm_set_callback(mfm, SECTOR_TIME); + timer_set_delay_u64(&mfm->callback_timer, SECTOR_TIME); } else ui_sb_update_icon(SB_HDD|HDD_BUS_MFM, 0); } @@ -562,7 +546,6 @@ do_callback(void *priv) drive_t *drive = &mfm->drives[mfm->drvsel]; off64_t addr; - mfm_set_callback(mfm, 0); if (mfm->reset) { st506_at_log("WD1003(%d) reset\n", mfm->drvsel); @@ -667,6 +650,12 @@ do_callback(void *priv) case CMD_DIAGNOSE: st506_at_log("WD1003(%d) diag\n", mfm->drvsel); + + /* This is basically controller diagnostics - it resets drive select to 0, + and resets error and status to ready, DSC, and no error detected. */ + mfm->drvsel = 0; + drive = &mfm->drives[mfm->drvsel]; + drive->steprate = 0x0f; mfm->error = 1; mfm->status = STAT_READY|STAT_DSC; @@ -735,7 +724,7 @@ mfm_init(const device_t *info) io_sethandler(0x03f6, 1, NULL, NULL, NULL, mfm_write, NULL, NULL, mfm); - timer_add(&mfm->timer, do_callback, mfm, 0); + timer_add(&mfm->callback_timer, do_callback, mfm, 0); ui_sb_update_icon(SB_HDD|HDD_BUS_MFM, 0); diff --git a/src/machine/m_at_286_386sx.c b/src/machine/m_at_286_386sx.c index 06b542800..4ff2476ae 100644 --- a/src/machine/m_at_286_386sx.c +++ b/src/machine/m_at_286_386sx.c @@ -8,7 +8,7 @@ * * Implementation of 286 and 386SX machines. * - * Version: @(#)m_at_286_386sx.c 1.0.0 2019/05/16 + * Version: @(#)m_at_286_386sx.c 1.0.1 2019/11/01 * * Authors: Sarah Walker, * Miran Grca, @@ -203,6 +203,8 @@ machine_at_award286_init(const machine_t *model) machine_at_scat_init(model, 0); + device_add(&ide_isa_device); + return ret; } diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 00c1a6272..5f173e3f4 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -11,7 +11,7 @@ * NOTES: OpenAT wip for 286-class machine with open BIOS. * PS2_M80-486 wip, pending receipt of TRM's for machine. * - * Version: @(#)machine_table.c 1.0.48 2019/09/29 + * Version: @(#)machine_table.c 1.0.49 2019/11/01 * * Authors: Sarah Walker, * Miran Grca, @@ -86,7 +86,7 @@ const machine_t machines[] = { #endif { "[286 ISA] AMI 286 clone", "ami286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 512, 8192, 128, 127, machine_at_neat_ami_init, NULL }, - { "[286 ISA] Award 286 clone", "award286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 512,16384, 128, 127, machine_at_award286_init, NULL }, + { "[286 ISA] Award 286 clone", "award286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 512,16384, 128, 127, machine_at_award286_init, NULL }, { "[286 ISA] Commodore PC 30 III", "cmdpc30", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 640,16384, 128, 127, machine_at_cmdpc_init, NULL }, { "[286 ISA] Compaq Portable II", "portableii", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 640,16384, 128, 127, machine_at_portableii_init, NULL }, #if defined(DEV_BRANCH) && defined(USE_PORTABLE3) diff --git a/src/machine/machine_table_new.c b/src/machine/machine_table_new.c index 8d4274a97..016f2fb8b 100644 --- a/src/machine/machine_table_new.c +++ b/src/machine/machine_table_new.c @@ -11,7 +11,7 @@ * NOTES: OpenAT wip for 286-class machine with open BIOS. * PS2_M80-486 wip, pending receipt of TRM's for machine. * - * Version: @(#)machine_table.c 1.0.48 2019/09/29 + * Version: @(#)machine_table.c 1.0.49 2019/11/01 * * Authors: Sarah Walker, * Miran Grca, @@ -73,7 +73,7 @@ const machine_t machines[] = { #endif { "[286 ISA] AMI 286 clone", "ami286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 512, 8192, 128, 127, machine_at_neat_ami_init, NULL }, - { "[286 ISA] Award 286 clone", "award286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 512,16384, 128, 127, machine_at_award286_init, NULL }, + { "[286 ISA] Award 286 clone", "award286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 512,16384, 128, 127, machine_at_award286_init, NULL }, { "[286 ISA] Commodore PC 30 III", "cmdpc30", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 640,16384, 128, 127, machine_at_cmdpc_init, NULL }, { "[286 ISA] Compaq Portable II", "portableii", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 640,16384, 128, 127, machine_at_portableii_init, NULL }, #if defined(DEV_BRANCH) && defined(USE_PORTABLE3) diff --git a/src/sound/openal.c b/src/sound/openal.c index 319623816..185730a57 100644 --- a/src/sound/openal.c +++ b/src/sound/openal.c @@ -8,13 +8,13 @@ * * Interface to the OpenAL sound processing library. * - * Version: @(#)openal.c 1.0.6 2018/04/23 + * Version: @(#)openal.c 1.0.7 2019/10/31 * * Authors: Sarah Walker, * Miran Grca, * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. + * Copyright 2008-2019 Sarah Walker. + * Copyright 2016-2019 Miran Grca. */ #include #include @@ -47,7 +47,9 @@ static ALuint source[3]; /* audio source */ static int midi_freq = 44100; static int midi_buf_size = 4410; static int initialized = 0; - +static int sources = 2; +static ALCcontext *Context; +static ALCdevice *Device; void al_set_midi(int freq, int buf_size) @@ -60,9 +62,6 @@ al_set_midi(int freq, int buf_size) void closeal(void); ALvoid alutInit(ALint *argc,ALbyte **argv) { - ALCcontext *Context; - ALCdevice *Device; - /* Open device */ Device = alcOpenDevice((ALCchar *)""); if (Device != NULL) { @@ -79,24 +78,17 @@ ALvoid alutInit(ALint *argc,ALbyte **argv) ALvoid alutExit(ALvoid) { - ALCcontext *Context; - ALCdevice *Device; - - /* Get active context */ - Context = alcGetCurrentContext(); if (Context != NULL) { - /* Get device for active context */ - Device = alcGetContextsDevice(Context); - if (Device != NULL) { - /* Disable context */ - alcMakeContextCurrent(NULL); - - /* Close device */ - alcCloseDevice(Device); - } + /* Disable context */ + alcMakeContextCurrent(NULL); /* Release context(s) */ alcDestroyContext(Context); + + if (Device != NULL) { + /* Close device */ + alcCloseDevice(Device); + } } } @@ -104,7 +96,16 @@ alutExit(ALvoid) void closeal(void) { - if (!initialized) return; + if (!initialized) + return; + + alSourceStopv(sources, source); + alDeleteSources(sources, source); + + if (sources == 3) + alDeleteBuffers(4, buffers_midi); + alDeleteBuffers(4, buffers_cd); + alDeleteBuffers(4, buffers); alutExit(); @@ -122,7 +123,8 @@ inital(void) char *mdn; int init_midi = 0; - if (initialized) return; + if (initialized) + return; alutInit(0, 0); atexit(closeal); @@ -131,6 +133,7 @@ inital(void) if (strcmp(mdn, "none") && strcmp(mdn, SYSTEM_MIDI_INTERNAL_NAME)) init_midi = 1; /* If the device is neither none, nor system MIDI, initialize the MIDI buffer and source, otherwise, do not. */ + sources = 2 + !!init_midi; if (sound_is_float) { buf = (float *) malloc((BUFLEN << 1) * sizeof(float)); @@ -231,6 +234,9 @@ givealbuffer_common(void *buf, uint8_t src, int size, int freq) ALuint buffer; double gain; + if (!initialized) + return; + alGetSourcei(source[src], AL_SOURCE_STATE, &state); if (state == 0x1014) { @@ -244,11 +250,10 @@ givealbuffer_common(void *buf, uint8_t src, int size, int freq) alSourceUnqueueBuffers(source[src], 1, &buffer); - if (sound_is_float) { + if (sound_is_float) alBufferData(buffer, AL_FORMAT_STEREO_FLOAT32, buf, size * sizeof(float), freq); - } else { + else alBufferData(buffer, AL_FORMAT_STEREO16, buf, size * sizeof(int16_t), freq); - } alSourceQueueBuffers(source[src], 1, &buffer); } diff --git a/src/sound/snd_gus.c b/src/sound/snd_gus.c index 84c338a93..46bd3408d 100644 --- a/src/sound/snd_gus.c +++ b/src/sound/snd_gus.c @@ -48,7 +48,7 @@ typedef struct gus_t int pos; pc_timer_t samp_timer; - uint64_t samp_latch; + uint64_t samp_latch; uint8_t *ram; @@ -333,9 +333,9 @@ gus->curx[gus->voice]=(gus->curx[gus->voice]&0xFFF8000)|((val&0x7F)<<8); if (gus->voices<14) gus->voices=14; gus->global=val; if (gus->voices < 14) - gus->samp_latch = (int)(TIMER_USEC * (1000000.0 / 44100.0)); + gus->samp_latch = (uint64_t)(TIMER_USEC * (1000000.0 / 44100.0)); else - gus->samp_latch = (int)(TIMER_USEC * (1000000.0 / gusfreqs[gus->voices - 14])); + gus->samp_latch = (uint64_t)(TIMER_USEC * (1000000.0 / gusfreqs[gus->voices - 14])); break; case 0x41: /*DMA*/ @@ -746,7 +746,7 @@ void gus_poll_timer_1(void *p) { gus_t *gus = (gus_t *)p; - timer_advance_u64(&gus->timer_1, TIMER_USEC * 80); + timer_advance_u64(&gus->timer_1, (uint64_t)(TIMER_USEC * 80)); if (gus->t1on) { gus->t1++; @@ -777,7 +777,7 @@ void gus_poll_timer_2(void *p) { gus_t *gus = (gus_t *)p; - timer_advance_u64(&gus->timer_2, TIMER_USEC * 320); + timer_advance_u64(&gus->timer_2, (uint64_t)(TIMER_USEC * 320)); if (gus->t2on) { gus->t2++; @@ -833,7 +833,7 @@ void gus_poll_wave(void *p) gus_update(gus); - timer_advance_u64(&gus->samp_timer, gus->samp_latch); + timer_advance_u64(&gus->samp_timer, gus->samp_latch); gus->out_l = gus->out_r = 0; @@ -1022,8 +1022,8 @@ void *gus_init(const device_t *info) } gus->voices=14; - - gus->samp_latch = (uint64_t)(TIMER_USEC * (1000000.0 / 44100.0)); + + gus->samp_latch = (uint64_t)(TIMER_USEC * (1000000.0 / 44100.0)); gus->t1l = gus->t2l = 0xff; diff --git a/src/win/86Box.rc b/src/win/86Box.rc index 67e98acdb..543ed98b1 100644 --- a/src/win/86Box.rc +++ b/src/win/86Box.rc @@ -8,7 +8,7 @@ * * Application resource script for Windows. * - * Version: @(#)86Box.rc 1.0.51 2019/10/31 + * Version: @(#)86Box.rc 1.0.52 2019/11/01 * * Authors: Miran Grca, * Fred N. van Kempen, @@ -225,7 +225,7 @@ BEGIN DEFPUSHBUTTON "OK",IDOK,129,94,71,12 ICON 100,IDC_ABOUT_ICON,7,7,20,20 #ifdef RELEASE_BUILD - LTEXT "86Box v2.04 - An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, MoochMcGee, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2. See LICENSE for more information.", + LTEXT "86Box v2.05 - An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, MoochMcGee, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2. See LICENSE for more information.", IDC_ABOUT_ICON,54,7,146,73 #else LTEXT "86Box v2.10 - An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, MoochMcGee, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2. See LICENSE for more information.", @@ -980,8 +980,8 @@ END VS_VERSION_INFO VERSIONINFO #ifdef RELEASE_BUILD - FILEVERSION 2,4,0,0 - PRODUCTVERSION 2,4,0,0 + FILEVERSION 2,5,0,0 + PRODUCTVERSION 2,5,0,0 #else FILEVERSION 2,10,0,0 PRODUCTVERSION 2,10,0,0 @@ -1004,7 +1004,7 @@ BEGIN VALUE "CompanyName", "IRC #SoftHistory\0" VALUE "FileDescription", "86Box - an emulator for X86-based systems\0" #ifdef RELEASE_BUILD - VALUE "FileVersion", "2.04\0" + VALUE "FileVersion", "2.05\0" #else VALUE "FileVersion", "2.10\0" #endif @@ -1015,7 +1015,7 @@ BEGIN VALUE "PrivateBuild", "\0" VALUE "ProductName", "86Box Emulator\0" #ifdef RELEASE_BUILD - VALUE "ProductVersion", "2.04\0" + VALUE "ProductVersion", "2.05\0" #else VALUE "ProductVersion", "2.10\0" #endif diff --git a/src/win/win.h b/src/win/win.h index 959056ba9..747c8c616 100644 --- a/src/win/win.h +++ b/src/win/win.h @@ -8,15 +8,15 @@ * * Platform support defintions for Win32. * - * Version: @(#)win.h 1.0.25 2019/02/11 + * Version: @(#)win.h 1.0.26 2019/11/01 * * Authors: Sarah Walker, * Miran Grca, * Fred N. van Kempen, * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - * Copyright 2017,2018 Fred N. van Kempen. + * Copyright 2008-2019 Sarah Walker. + * Copyright 2016-2019 Miran Grca. + * Copyright 2017-2019 Fred N. van Kempen. */ #ifndef PLAT_WIN_H # define PLAT_WIN_H @@ -57,6 +57,8 @@ #define WM_SENDSTATUS 0x8895 /* Settings status: WPARAM = 1 for open, 0 for closed. */ #define WM_SENDSSTATUS 0x8896 +/* Emulator shut down. */ +#define WM_SHUTDOWN_DONE 0x8897 #ifdef USE_VNC #ifdef USE_D2D diff --git a/src/win/win_settings.c b/src/win/win_settings.c index 989931bd7..ab5a5baa8 100644 --- a/src/win/win_settings.c +++ b/src/win/win_settings.c @@ -8,7 +8,7 @@ * * Windows 86Box Settings dialog handler. * - * Version: @(#)win_settings.c 1.0.56 2019/09/26 + * Version: @(#)win_settings.c 1.0.57 2019/11/01 * * Authors: Miran Grca, * David Hrdlička, @@ -3058,7 +3058,7 @@ hdd_add_file_open_error: case HDD_BUS_ESDI: max_spt = 43; /* ESDI drives usually had 32 to 43 sectors per track. */ max_hpc = 16; - max_tracks = 1023; + max_tracks = 266305; break; case HDD_BUS_XTA: max_spt = 63; diff --git a/src/win/win_ui.c b/src/win/win_ui.c index 625769f49..a23d74361 100644 --- a/src/win/win_ui.c +++ b/src/win/win_ui.c @@ -8,7 +8,7 @@ * * user Interface module for WinAPI on Windows. * - * Version: @(#)win_ui.c 1.0.40 2019/10/31 + * Version: @(#)win_ui.c 1.0.41 2019/11/01 * * Authors: Sarah Walker, * Miran Grca, @@ -309,6 +309,8 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) case IDM_ACTION_EXIT: i = ui_msgbox(MBX_QUESTION_YN, (wchar_t *)IDS_2122); if (i == 0) { + if (source_hwnd) + PostMessage((HWND) (uintptr_t) source_hwnd, WM_SHUTDOWN_DONE, (WPARAM) 0, (LPARAM) hwndMain); UnhookWindowsHookEx(hKeyboardHook); KillTimer(hwnd, TIMER_1SEC); PostQuitMessage(0); @@ -671,6 +673,8 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) case WM_CLOSE: i = ui_msgbox(MBX_QUESTION_YN, (wchar_t *)IDS_2122); if (i == 0) { + if (source_hwnd) + PostMessage((HWND) (uintptr_t) source_hwnd, WM_SHUTDOWN_DONE, (WPARAM) 0, (LPARAM) hwndMain); UnhookWindowsHookEx(hKeyboardHook); KillTimer(hwnd, TIMER_1SEC); PostQuitMessage(0); @@ -678,6 +682,8 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) break; case WM_DESTROY: + if (source_hwnd) + PostMessage((HWND) (uintptr_t) source_hwnd, WM_SHUTDOWN_DONE, (WPARAM) 0, (LPARAM) hwndMain); UnhookWindowsHookEx(hKeyboardHook); KillTimer(hwnd, TIMER_1SEC); PostQuitMessage(0); @@ -693,12 +699,16 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) break; case WM_HARDRESET: - pc_reset(1); + i = ui_msgbox(MBX_QUESTION_YN, (wchar_t *)IDS_2121); + if (i == 0) + pc_reset(1); break; case WM_SHUTDOWN: i = ui_msgbox(MBX_QUESTION_YN, (wchar_t *)IDS_2122); if (i == 0) { + if (source_hwnd) + PostMessage((HWND) (uintptr_t) source_hwnd, WM_SHUTDOWN_DONE, (WPARAM) 0, (LPARAM) hwndMain); UnhookWindowsHookEx(hKeyboardHook); KillTimer(hwnd, TIMER_1SEC); PostQuitMessage(0);