diff --git a/src/cpu/codegen_timing_486.c b/src/cpu/codegen_timing_486.c index 7c57aa3..d2b0ec8 100644 --- a/src/cpu/codegen_timing_486.c +++ b/src/cpu/codegen_timing_486.c @@ -8,7 +8,7 @@ * * Instruction timing for i486-class. * - * Version: @(#)codegen_timing_486.c 1.0.1 2018/02/14 + * Version: @(#)codegen_timing_486.c 1.0.2 2018/12/24 * * Authors: Sarah Walker, * Miran Grca, @@ -319,24 +319,24 @@ static INLINE int COUNT(int *c, int op_32) return *c; } -void codegen_timing_486_block_start() +static void codegen_timing_486_block_start(void) { regmask_modified = 0; } -void codegen_timing_486_start() +static void codegen_timing_486_start(void) { timing_count = 0; last_prefix = 0; } -void codegen_timing_486_prefix(uint8_t prefix, uint32_t fetchdat) +static void codegen_timing_486_prefix(uint8_t prefix, uint32_t fetchdat) { timing_count += COUNT(opcode_timings[prefix], 0); last_prefix = prefix; } -void codegen_timing_486_opcode(uint8_t opcode, uint32_t fetchdat, int op_32) +static void codegen_timing_486_opcode(uint8_t opcode, uint32_t fetchdat, int op_32) { int **timings; uint64_t *deps; @@ -442,7 +442,7 @@ void codegen_timing_486_opcode(uint8_t opcode, uint32_t fetchdat, int op_32) regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8); } -void codegen_timing_486_block_end() +static void codegen_timing_486_block_end(void) { } diff --git a/src/cpu/codegen_timing_pentium.c b/src/cpu/codegen_timing_pentium.c index 96883d0..30da161 100644 --- a/src/cpu/codegen_timing_pentium.c +++ b/src/cpu/codegen_timing_pentium.c @@ -20,7 +20,7 @@ * - PMMX decode queue * - MMX latencies * - * Version: @(#)codegen_timing_pentium.c 1.0.3 2018/09/04 + * Version: @(#)codegen_timing_pentium.c 1.0.4 2018/12/24 * * Authors: Sarah Walker, * Miran Grca, @@ -975,20 +975,20 @@ static INLINE int codegen_timing_instr_length(uint64_t timing, uint32_t fetchdat } -void codegen_timing_pentium_block_start(void) +static void codegen_timing_pentium_block_start(void) { u_pipe_full = decode_delay = decode_delay_offset = 0; } -void codegen_timing_pentium_start(void) +static void codegen_timing_pentium_start(void) { last_prefix = 0; prefixes = 0; } -void codegen_timing_pentium_prefix(uint8_t prefix, uint32_t fetchdat) +static void codegen_timing_pentium_prefix(uint8_t prefix, uint32_t fetchdat) { prefixes++; if ((prefix & 0xf8) == 0xd8) @@ -1122,7 +1122,7 @@ static void codegen_instruction(const uint64_t *timings, uint64_t *deps, uint8_t } } -void codegen_timing_pentium_opcode(uint8_t opcode, uint32_t fetchdat, int op_32) +static void codegen_timing_pentium_opcode(uint8_t opcode, uint32_t fetchdat, int op_32) { const uint64_t *timings; uint64_t *deps; @@ -1346,7 +1346,7 @@ nopair: addr_regmask = 0; } -void codegen_timing_pentium_block_end() +static void codegen_timing_pentium_block_end(void) { if (u_pipe_full) { diff --git a/src/cpu/codegen_timing_winchip.c b/src/cpu/codegen_timing_winchip.c index 7d43320..4b8118e 100644 --- a/src/cpu/codegen_timing_winchip.c +++ b/src/cpu/codegen_timing_winchip.c @@ -8,7 +8,7 @@ * * Code generation timing for IDT WinChip processors. * - * Version: @(#)codegen_timing_winchip.c 1.0.1 2018/02/14 + * Version: @(#)codegen_timing_winchip.c 1.0.2 2018/12/24 * * Authors: Sarah Walker, * Miran Grca, @@ -51,7 +51,7 @@ #define CYCLES(c) (int *)c #define CYCLES2(c16, c32) (int *)((-1 & ~0xffff) | c16 | (c32 << 8)) -static int *opcode_timings[256] = +static const int *opcode_timings[256] = { /*00*/ &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(2), NULL, /*10*/ &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), @@ -74,7 +74,7 @@ static int *opcode_timings[256] = /*f0*/ CYCLES(4), CYCLES(0), CYCLES(0), CYCLES(0), CYCLES(4), CYCLES(2), NULL, NULL, CYCLES(2), CYCLES(2), CYCLES(3), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(3), NULL }; -static int *opcode_timings_mod3[256] = +static const int *opcode_timings_mod3[256] = { /*00*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(2), NULL, /*10*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), @@ -97,7 +97,7 @@ static int *opcode_timings_mod3[256] = /*f0*/ CYCLES(4), CYCLES(0), CYCLES(0), CYCLES(0), CYCLES(4), CYCLES(2), NULL, NULL, CYCLES(2), CYCLES(2), CYCLES(3), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(3), NULL }; -static int *opcode_timings_0f[256] = +static const int *opcode_timings_0f[256] = { /*00*/ CYCLES(20), CYCLES(11), CYCLES(11), CYCLES(10), NULL, CYCLES(195), CYCLES(7), NULL, CYCLES(1000), CYCLES(10000), NULL, NULL, NULL, NULL, NULL, NULL, /*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -119,7 +119,7 @@ static int *opcode_timings_0f[256] = /*e0*/ NULL, &timing_rm, &timing_rm, NULL, NULL, &timing_rm, NULL, NULL, &timing_rm, &timing_rm, NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm, /*f0*/ NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm, NULL, NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm, &timing_rm, &timing_rm, NULL, }; -static int *opcode_timings_0f_mod3[256] = +static const int *opcode_timings_0f_mod3[256] = { /*00*/ CYCLES(20), CYCLES(11), CYCLES(11), CYCLES(10), NULL, CYCLES(195), CYCLES(7), NULL, CYCLES(1000), CYCLES(10000), NULL, NULL, NULL, NULL, NULL, NULL, /*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -142,57 +142,57 @@ static int *opcode_timings_0f_mod3[256] = /*f0*/ NULL, &timing_rr, &timing_rr, &timing_rr, NULL, &timing_rr, NULL, NULL, &timing_rr, &timing_rr, &timing_rr, NULL, &timing_rr, &timing_rr, &timing_rr, NULL, }; -static int *opcode_timings_shift[8] = +static const int *opcode_timings_shift[8] = { CYCLES(7), CYCLES(7), CYCLES(10), CYCLES(10), CYCLES(7), CYCLES(7), CYCLES(7), CYCLES(7) }; -static int *opcode_timings_shift_mod3[8] = +static const int *opcode_timings_shift_mod3[8] = { CYCLES(3), CYCLES(3), CYCLES(9), CYCLES(9), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3) }; -static int *opcode_timings_f6[8] = +static const int *opcode_timings_f6[8] = { &timing_rm, NULL, &timing_mm, &timing_mm, CYCLES(13), CYCLES(14), CYCLES(16), CYCLES(19) }; -static int *opcode_timings_f6_mod3[8] = +static const int *opcode_timings_f6_mod3[8] = { &timing_rr, NULL, &timing_rr, &timing_rr, CYCLES(13), CYCLES(14), CYCLES(16), CYCLES(19) }; -static int *opcode_timings_f7[8] = +static const int *opcode_timings_f7[8] = { &timing_rm, NULL, &timing_mm, &timing_mm, CYCLES(21), CYCLES2(22,38), CYCLES2(24,40), CYCLES2(27,43) }; -static int *opcode_timings_f7_mod3[8] = +static const int *opcode_timings_f7_mod3[8] = { &timing_rr, NULL, &timing_rr, &timing_rr, CYCLES(21), CYCLES2(22,38), CYCLES2(24,40), CYCLES2(27,43) }; -static int *opcode_timings_ff[8] = +static const int *opcode_timings_ff[8] = { &timing_mm, &timing_mm, CYCLES(5), CYCLES(0), CYCLES(5), CYCLES(0), CYCLES(5), NULL }; -static int *opcode_timings_ff_mod3[8] = +static const int *opcode_timings_ff_mod3[8] = { &timing_rr, &timing_rr, CYCLES(5), CYCLES(0), CYCLES(5), CYCLES(0), CYCLES(5), NULL }; -static int *opcode_timings_d8[8] = +static const int *opcode_timings_d8[8] = { /* FADDil FMULil FCOMil FCOMPil FSUBil FSUBRil FDIVil FDIVRil*/ CYCLES(10), CYCLES(12), CYCLES(9), CYCLES(9), CYCLES(10), CYCLES(10), CYCLES(78), CYCLES(78) }; -static int *opcode_timings_d8_mod3[8] = +static const int *opcode_timings_d8_mod3[8] = { /* FADD FMUL FCOM FCOMP FSUB FSUBR FDIV FDIVR*/ CYCLES(4), CYCLES(6), CYCLES(3), CYCLES(3), CYCLES(4), CYCLES(4), CYCLES(72), CYCLES(72) }; -static int *opcode_timings_d9[8] = +static const int *opcode_timings_d9[8] = { /* FLDs FSTs FSTPs FLDENV FLDCW FSTENV FSTCW*/ CYCLES(2), NULL, CYCLES(7), CYCLES(7), CYCLES(34), CYCLES(4), CYCLES(67), CYCLES(3) }; -static int *opcode_timings_d9_mod3[64] = +static const int *opcode_timings_d9_mod3[64] = { /*FLD*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), @@ -212,23 +212,23 @@ static int *opcode_timings_d9_mod3[64] = CYCLES(70), NULL, CYCLES(72), CYCLES(292), CYCLES(21), CYCLES(30), CYCLES(474), CYCLES(474) }; -static int *opcode_timings_da[8] = +static const int *opcode_timings_da[8] = { /* FADDil FMULil FCOMil FCOMPil FSUBil FSUBRil FDIVil FDIVRil*/ CYCLES(10), CYCLES(12), CYCLES(9), CYCLES(9), CYCLES(10), CYCLES(10), CYCLES(78), CYCLES(78) }; -static int *opcode_timings_da_mod3[8] = +static const int *opcode_timings_da_mod3[8] = { NULL, NULL, NULL, NULL, NULL, CYCLES(5), NULL, NULL }; -static int *opcode_timings_db[8] = +static const int *opcode_timings_db[8] = { /* FLDil FSTil FSTPil FLDe FSTPe*/ CYCLES(6), NULL, CYCLES(7), CYCLES(7), NULL, CYCLES(8), NULL, CYCLES(8) }; -static int *opcode_timings_db_mod3[64] = +static const int *opcode_timings_db_mod3[64] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -241,63 +241,63 @@ static int *opcode_timings_db_mod3[64] = NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, }; -static int *opcode_timings_dc[8] = +static const int *opcode_timings_dc[8] = { /* opFADDd_a16 opFMULd_a16 opFCOMd_a16 opFCOMPd_a16 opFSUBd_a16 opFSUBRd_a16 opFDIVd_a16 opFDIVRd_a16*/ CYCLES(6), CYCLES(8), CYCLES(5), CYCLES(5), CYCLES(6), CYCLES(6), CYCLES(74), CYCLES(74) }; -static int *opcode_timings_dc_mod3[8] = +static const int *opcode_timings_dc_mod3[8] = { /* opFADDr opFMULr opFSUBRr opFSUBr opFDIVRr opFDIVr*/ CYCLES(4), CYCLES(6), NULL, NULL, CYCLES(4), CYCLES(4), CYCLES(72), CYCLES(72) }; -static int *opcode_timings_dd[8] = +static const int *opcode_timings_dd[8] = { /* FLDd FSTd FSTPd FRSTOR FSAVE FSTSW*/ CYCLES(2), NULL, CYCLES(8), CYCLES(8), CYCLES(131), NULL, CYCLES(154), CYCLES(5) }; -static int *opcode_timings_dd_mod3[8] = +static const int *opcode_timings_dd_mod3[8] = { /* FFFREE FST FSTP FUCOM FUCOMP*/ CYCLES(3), NULL, CYCLES(1), CYCLES(1), CYCLES(3), CYCLES(3), NULL, NULL }; -static int *opcode_timings_de[8] = +static const int *opcode_timings_de[8] = { /* FADDiw FMULiw FCOMiw FCOMPiw FSUBil FSUBRil FDIVil FDIVRil*/ CYCLES(10), CYCLES(12), CYCLES(9), CYCLES(9), CYCLES(10), CYCLES(10), CYCLES(78), CYCLES(78) }; -static int *opcode_timings_de_mod3[8] = +static const int *opcode_timings_de_mod3[8] = { /* FADD FMUL FCOMPP FSUB FSUBR FDIV FDIVR*/ CYCLES(4), CYCLES(6), NULL, CYCLES(3), CYCLES(4), CYCLES(4), CYCLES(72), CYCLES(72) }; -static int *opcode_timings_df[8] = +static const int *opcode_timings_df[8] = { /* FILDiw FISTiw FISTPiw FILDiq FBSTP FISTPiq*/ CYCLES(6), NULL, CYCLES(7), CYCLES(7), NULL, CYCLES(8), CYCLES(172), CYCLES(8) }; -static int *opcode_timings_df_mod3[8] = +static const int *opcode_timings_df_mod3[8] = { /* FFREE FST FSTP FUCOM FUCOMP*/ CYCLES(3), NULL, CYCLES(1), CYCLES(1), CYCLES(3), CYCLES(3), NULL, NULL }; -static int *opcode_timings_8x[8] = +static const int *opcode_timings_8x[8] = { &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm }; -static int *opcode_timings_8x_mod3[8] = +static const int *opcode_timings_8x_mod3[8] = { &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm }; -static int *opcode_timings_81[8] = +static const int *opcode_timings_81[8] = { &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm }; -static int *opcode_timings_81_mod3[8] = +static const int *opcode_timings_81_mod3[8] = { &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm }; @@ -306,7 +306,7 @@ static int timing_count; static uint8_t last_prefix; static uint32_t regmask_modified; -static INLINE int COUNT(int *c, int op_32) +static INLINE int COUNT(const int *c, int op_32) { if ((uintptr_t)c <= 10000) return (int)(uintptr_t)c; @@ -319,26 +319,26 @@ static INLINE int COUNT(int *c, int op_32) return *c; } -void codegen_timing_winchip_block_start() +static void codegen_timing_winchip_block_start(void) { regmask_modified = 0; } -void codegen_timing_winchip_start() +static void codegen_timing_winchip_start(void) { timing_count = 0; last_prefix = 0; } -void codegen_timing_winchip_prefix(uint8_t prefix, uint32_t fetchdat) +static void codegen_timing_winchip_prefix(uint8_t prefix, uint32_t fetchdat) { timing_count += COUNT(opcode_timings[prefix], 0); last_prefix = prefix; } -void codegen_timing_winchip_opcode(uint8_t opcode, uint32_t fetchdat, int op_32) +static void codegen_timing_winchip_opcode(uint8_t opcode, uint32_t fetchdat, int op_32) { - int **timings; + const int **timings; uint64_t *deps; int mod3 = ((fetchdat & 0xc0) == 0xc0); int bit8 = !(opcode & 1); @@ -442,7 +442,7 @@ void codegen_timing_winchip_opcode(uint8_t opcode, uint32_t fetchdat, int op_32) regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8); } -void codegen_timing_winchip_block_end() +static void codegen_timing_winchip_block_end(void) { } diff --git a/src/devices/sound/snd_cs423x.c b/src/devices/sound/snd_cs423x.c index 6adbbb3..fa305e1 100644 --- a/src/devices/sound/snd_cs423x.c +++ b/src/devices/sound/snd_cs423x.c @@ -1,334 +1,360 @@ -/* - * VARCem Virtual ARchaeological Computer EMulator. - * An emulator of (mostly) x86-based PC systems and devices, - * using the ISA,EISA,VLB,MCA and PCI system buses, roughly - * spanning the era between 1981 and 1995. - * - * This file is part of the VARCem Project. - * - * Implementation of Cirrus Logic Crystal 423x sound devices. - * - * Version: @(#)snd_cs423x.c 1.0.0 2018/11/27 - * - * Authors: Fred N. van Kempen, - * - * Copyright 2018 Fred N. van Kempen. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the: - * - * Free Software Foundation, Inc. - * 59 Temple Place - Suite 330 - * Boston, MA 02111-1307 - * USA. - */ -#include -#include -#include -#include -#include -#include -#define dbglog sound_card_log -#include "../../emu.h" -#include "../../io.h" -#include "../../device.h" -#include "../../timer.h" -#include "../system/dma.h" -#include "../system/pic.h" -#include "sound.h" -#include "snd_cs423x.h" - -#define CS4231 0x80 -#define CS4231A 0xa0 -#define CS4232 0xa2 -#define CS4232A 0xb2 -#define CS4236 0x83 -#define CS4236B 0x03 - - -static int cs423x_vols[64]; - -void cs423x_setirq(cs423x_t *cs423x, int irq_ch) -{ - cs423x->irq = irq_ch; -} - -void cs423x_setdma(cs423x_t *cs423x, int dma_ch) -{ - cs423x->dma = dma_ch; -} - -uint8_t cs423x_read(uint16_t addr, void *p) -{ - cs423x_t *cs423x = (cs423x_t *)p; - uint8_t temp = 0xff; - - if (cs423x->initb) - return 0x80; - - switch (addr & 3) - { - case 0: /*Index*/ - if (cs423x->mode2) - temp = cs423x->index | cs423x->trd | cs423x->mce | cs423x->ia4 | cs423x->initb; - else - temp = cs423x->index | cs423x->trd | cs423x->mce | cs423x->initb; - break; - case 1: - temp = cs423x->regs[cs423x->index]; - if (cs423x->index == 0x0b) { - temp ^= 0x20; - cs423x->regs[cs423x->index] = temp; - } - break; - case 2: - temp = cs423x->status; - break; - case 3: // Todo Capture I/O read - break; - } - return temp; -} - -void cs423x_write(uint16_t addr, uint8_t val, void *p) -{ - cs423x_t *cs423x = (cs423x_t *)p; - double freq; - - switch (addr & 3) - { - case 0: /*Index*/ - cs423x->index = val & (cs423x->mode2 ? 0x1F : 0x0F); - cs423x->trd = val & 0x20; - cs423x->mce = val & 0x40; - cs423x->ia4 = val & 0x10; - cs423x->initb = val & 0x80; - break; - case 1: - switch (cs423x->index) - { - case 8: - freq = (double)((val & 1) ? 16934400LL : 24576000LL); - switch ((val >> 1) & 7) - { - case 0: freq /= 3072; break; - case 1: freq /= 1536; break; - case 2: freq /= 896; break; - case 3: freq /= 768; break; - case 4: freq /= 448; break; - case 5: freq /= 384; break; - case 6: freq /= 512; break; - case 7: freq /= 2560; break; - } - cs423x->freq = (int64_t)freq; - cs423x->timer_latch = (int64_t)((double)TIMER_USEC * (1000000.0 / (double)cs423x->freq)); - break; - - case 9: - cs423x->enable = ((val & 0x41) == 0x01); - if (!cs423x->enable) - cs423x->out_l = cs423x->out_r = 0; - break; - - case 11: - break; - - case 12: - val |= 0x8a; - cs423x->mode2 = (val >> 6) & 1; - break; - - case 14: - cs423x->count = cs423x->regs[15] | (val << 8); - break; - - case 24: - if (!(val & 0x70)) - cs423x->status &= 0xfe; - break; - - case 25: - break; - } - cs423x->regs[cs423x->index] = val; - break; - case 2: - cs423x->status &= 0xfe; - break; - case 3: // Todo Playback I/O Write - break; - } -} - -void cs423x_speed_changed(cs423x_t *cs423x) -{ - cs423x->timer_latch = (int64_t)((double)TIMER_USEC * (1000000.0 / (double)cs423x->freq)); -} - -void cs423x_update(cs423x_t *cs423x) -{ - for (; cs423x->pos < sound_pos_global; cs423x->pos++) - { - cs423x->buffer[cs423x->pos * 2] = cs423x->out_l; - cs423x->buffer[cs423x->pos * 2 + 1] = cs423x->out_r; - } -} - -static void cs423x_poll(void *p) -{ - cs423x_t *cs423x = (cs423x_t *)p; - - if (cs423x->timer_latch) - cs423x->timer_count += cs423x->timer_latch; - else - cs423x->timer_count = TIMER_USEC; - - cs423x_update(cs423x); - - if (cs423x->enable) { - int32_t temp; - - if (!(cs423x->mode2)) { - switch (cs423x->regs[8] & 0x70) - { - case 0x00: /*Mono, 8-bit PCM*/ - cs423x->out_l = cs423x->out_r = (dma_channel_read(cs423x->dma) ^ 0x80) * 256; - break; - - case 0x10: /*Stereo, 8-bit PCM*/ - cs423x->out_l = (dma_channel_read(cs423x->dma) ^ 0x80) * 256; - cs423x->out_r = (dma_channel_read(cs423x->dma) ^ 0x80) * 256; - break; - - case 0x40: /*Mono, 16-bit PCM*/ - temp = dma_channel_read(cs423x->dma); - cs423x->out_l = cs423x->out_r = (dma_channel_read(cs423x->dma) << 8) | temp; - break; - - case 0x50: /*Stereo, 16-bit PCM*/ - temp = dma_channel_read(cs423x->dma); - cs423x->out_l = (dma_channel_read(cs423x->dma) << 8) | temp; - temp = dma_channel_read(cs423x->dma); - cs423x->out_r = (dma_channel_read(cs423x->dma) << 8) | temp; - break; - } - } - else { - switch (cs423x->regs[8] & 0xf0) - { - case 0x00: /*Mono, 8-bit PCM*/ - cs423x->out_l = cs423x->out_r = (dma_channel_read(cs423x->dma) ^ 0x80) * 256; - break; - - case 0x10: /*Stereo, 8-bit PCM*/ - cs423x->out_l = (dma_channel_read(cs423x->dma) ^ 0x80) * 256; - cs423x->out_r = (dma_channel_read(cs423x->dma) ^ 0x80) * 256; - break; - - case 0x40: /*Mono, 16-bit PCM*/ - case 0xc0: /*Mono, 16-bit PCM Big-Endian should not happen on x86*/ - temp = dma_channel_read(cs423x->dma); - cs423x->out_l = cs423x->out_r = (dma_channel_read(cs423x->dma) << 8) | temp; - break; - - case 0x50: /*Stereo, 16-bit PCM*/ - case 0xd0: /*Stereo, 16-bit PCM Big-Endian. Should not happen on x86*/ - temp = dma_channel_read(cs423x->dma); - cs423x->out_l = (dma_channel_read(cs423x->dma) << 8) | temp; - temp = dma_channel_read(cs423x->dma); - cs423x->out_r = (dma_channel_read(cs423x->dma) << 8) | temp; - break; - - case 0xa0: /*TODO Mono, ADPCM, 4-bit*/ - case 0xb0: /*TODO Stereo, ADPCM, 4-bit*/ - break; - } - } - - if (cs423x->regs[6] & 0x80) // Mute Left-Channel - cs423x->out_l = 0; - else - cs423x->out_l = (cs423x->out_l * cs423x_vols[cs423x->regs[6] & 0x3f]) >> 16; - - if (cs423x->regs[7] & 0x80) // Mute Right-Channel - cs423x->out_r = 0; - else - cs423x->out_r = (cs423x->out_r * cs423x_vols[cs423x->regs[7] & 0x3f]) >> 16; - - if (cs423x->regs[26] & 0x40) // Mono Output Mute - cs423x->out_l = cs423x->out_r = 0; - - if (cs423x->count < 0) { - cs423x->count = cs423x->regs[15] | (cs423x->regs[14] << 8); - if (!(cs423x->status & 0x01)) { - cs423x->status |= 0x01; - if (cs423x->regs[10] & 2) - picint(1 << cs423x->irq); - } - } - cs423x->count--; - } - else { - cs423x->out_l = cs423x->out_r = 0; - } -} - -void cs423x_init(cs423x_t *cs423x) -{ - int c; - double attenuation; - - cs423x->enable = 0; - - cs423x->status = 0xcc; - cs423x->index = cs423x->trd = 0; - cs423x->mce = 0x40; - cs423x->initb = 0; - cs423x->mode2 = 0; - - cs423x->regs[0] = cs423x->regs[1] = 0; - cs423x->regs[2] = cs423x->regs[3] = 0x88; - cs423x->regs[4] = cs423x->regs[5] = 0x88; - cs423x->regs[6] = cs423x->regs[7] = 0x80; - cs423x->regs[8] = 0; - cs423x->regs[9] = 0x08; - cs423x->regs[10] = cs423x->regs[11] = 0; - cs423x->regs[12] = 0x8a; - cs423x->regs[13] = 0; - cs423x->regs[14] = cs423x->regs[15] = 0; - cs423x->regs[16] = cs423x->regs[17] = 0; - cs423x->regs[18] = cs423x->regs[19] = 0x88; - cs423x->regs[22] = 0x80; - cs423x->regs[24] = 0; - cs423x->regs[25] = CS4231; //CS4231 for GUS MAX - cs423x->regs[26] = 0x80; - cs423x->regs[29] = 0x80; - - cs423x->out_l = 0; - cs423x->out_r = 0; - - for (c = 0; c < 64; c++) // DAC and Loopback attenuation - { - attenuation = 0.0; - if (c & 0x01) attenuation -= 1.5; - if (c & 0x02) attenuation -= 3.0; - if (c & 0x04) attenuation -= 6.0; - if (c & 0x08) attenuation -= 12.0; - if (c & 0x10) attenuation -= 24.0; - if (c & 0x20) attenuation -= 48.0; - - attenuation = pow(10, attenuation / 10); - cs423x_vols[c] = (int)(attenuation * 65536); - } - timer_add(cs423x_poll, &cs423x->timer_count, &cs423x->enable, cs423x); -} +/* + * VARCem Virtual ARchaeological Computer EMulator. + * An emulator of (mostly) x86-based PC systems and devices, + * using the ISA,EISA,VLB,MCA and PCI system buses, roughly + * spanning the era between 1981 and 1995. + * + * This file is part of the VARCem Project. + * + * Implementation of Cirrus Logic Crystal 423x sound devices. + * + * Version: @(#)snd_cs423x.c 1.0.1 2019/01/13 + * + * Authors: Altheos, + * Fred N. van Kempen, + * + * Copyright 2018,2019 Altheos. + * Copyright 2018,2019 Fred N. van Kempen. + * + * Redistribution and use in source and binary forms, with + * or without modification, are permitted provided that the + * following conditions are met: + * + * 1. Redistributions of source code must retain the entire + * above notice, this list of conditions and the following + * disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names + * of its contributors may be used to endorse or promote + * products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include +#include +#include +#define dbglog sound_card_log +#include "../../emu.h" +#include "../../io.h" +#include "../../device.h" +#include "../../timer.h" +#include "../system/dma.h" +#include "../system/pic.h" +#include "sound.h" +#include "snd_cs423x.h" + + +#define CS4231 0x80 +#define CS4231A 0xa0 +#define CS4232 0xa2 +#define CS4232A 0xb2 +#define CS4236 0x83 +#define CS4236B 0x03 + + +static int cs423x_vols[64]; + + +void +cs423x_setirq(cs423x_t *dev, int irq_ch) +{ + dev->irq = irq_ch; +} + + +void +cs423x_setdma(cs423x_t *dev, int dma_ch) +{ + dev->dma = dma_ch; +} + + +uint8_t +cs423x_read(uint16_t addr, void *priv) +{ + cs423x_t *dev = (cs423x_t *)priv; + uint8_t ret = 0xff; + + if (dev->initb) + return 0x80; + + switch (addr & 3) { + case 0: /*Index*/ + if (dev->mode2) + ret = dev->indx | dev->trd | dev->mce | dev->ia4 | dev->initb; + else + ret = dev->indx | dev->trd | dev->mce | dev->initb; + break; + + case 1: + ret = dev->regs[dev->indx]; + if (dev->indx == 0x0b) { + ret ^= 0x20; + dev->regs[dev->indx] = ret; + } + break; + + case 2: + ret = dev->status; + break; + + case 3: // Todo Capture I/O read + break; + } + + return ret; +} + + +void +cs423x_write(uint16_t addr, uint8_t val, void *priv) +{ + cs423x_t *dev = (cs423x_t *)priv; + double freq; + + switch (addr & 3) { + case 0: /*Index*/ + dev->indx = val & (dev->mode2 ? 0x1f : 0x0f); + dev->trd = val & 0x20; + dev->mce = val & 0x40; + dev->ia4 = val & 0x10; + dev->initb = val & 0x80; + break; + + case 1: + switch (dev->indx) { + case 8: + freq = (double)((val & 1) ? 16934400LL : 24576000LL); + switch ((val >> 1) & 7) { + case 0: freq /= 3072; break; + case 1: freq /= 1536; break; + case 2: freq /= 896; break; + case 3: freq /= 768; break; + case 4: freq /= 448; break; + case 5: freq /= 384; break; + case 6: freq /= 512; break; + case 7: freq /= 2560; break; + } + dev->freq = (int64_t)freq; + dev->timer_latch = (int64_t)((double)TIMER_USEC * (1000000.0 / (double)dev->freq)); + break; + + case 9: + dev->enable = ((val & 0x41) == 0x01); + if (! dev->enable) + dev->out_l = dev->out_r = 0; + break; + + case 11: + break; + + case 12: + val |= 0x8a; + dev->mode2 = (val >> 6) & 1; + break; + + case 14: + dev->count = dev->regs[15] | (val << 8); + break; + + case 24: + if (! (val & 0x70)) + dev->status &= 0xfe; + break; + + case 25: + break; + } + dev->regs[dev->indx] = val; + break; + + case 2: + dev->status &= 0xfe; + break; + + case 3: // Todo Playback I/O Write + break; + } +} + + +void +cs423x_update(cs423x_t *dev) +{ + for (; dev->pos < sound_pos_global; dev->pos++) { + dev->buffer[dev->pos * 2] = dev->out_l; + dev->buffer[dev->pos * 2 + 1] = dev->out_r; + } +} + + +static void +cs423x_poll(void *priv) +{ + cs423x_t *dev = (cs423x_t *)priv; + int32_t temp; + + if (dev->timer_latch) + dev->timer_count += dev->timer_latch; + else + dev->timer_count = TIMER_USEC; + + cs423x_update(dev); + + if (! dev->enable) { + dev->out_l = dev->out_r = 0; + return; + } + + if (! (dev->mode2)) switch (dev->regs[8] & 0x70) { + case 0x00: /*Mono, 8-bit PCM*/ + dev->out_l = dev->out_r = (dma_channel_read(dev->dma) ^ 0x80) * 256; + break; + + case 0x10: /*Stereo, 8-bit PCM*/ + dev->out_l = (dma_channel_read(dev->dma) ^ 0x80) * 256; + dev->out_r = (dma_channel_read(dev->dma) ^ 0x80) * 256; + break; + + case 0x40: /*Mono, 16-bit PCM*/ + temp = dma_channel_read(dev->dma); + dev->out_l = dev->out_r = (dma_channel_read(dev->dma) << 8) | temp; + break; + + case 0x50: /*Stereo, 16-bit PCM*/ + temp = dma_channel_read(dev->dma); + dev->out_l = (dma_channel_read(dev->dma) << 8) | temp; + temp = dma_channel_read(dev->dma); + dev->out_r = (dma_channel_read(dev->dma) << 8) | temp; + break; + } else switch (dev->regs[8] & 0xf0) { + case 0x00: /*Mono, 8-bit PCM*/ + dev->out_l = dev->out_r = (dma_channel_read(dev->dma) ^ 0x80) * 256; + break; + + case 0x10: /*Stereo, 8-bit PCM*/ + dev->out_l = (dma_channel_read(dev->dma) ^ 0x80) * 256; + dev->out_r = (dma_channel_read(dev->dma) ^ 0x80) * 256; + break; + + case 0x40: /*Mono, 16-bit PCM*/ + case 0xc0: /*Mono, 16-bit PCM Big-Endian should not happen on x86*/ + temp = dma_channel_read(dev->dma); + dev->out_l = dev->out_r = (dma_channel_read(dev->dma) << 8) | temp; + break; + + case 0x50: /*Stereo, 16-bit PCM*/ + case 0xd0: /*Stereo, 16-bit PCM Big-Endian. Should not happen on x86*/ + temp = dma_channel_read(dev->dma); + dev->out_l = (dma_channel_read(dev->dma) << 8) | temp; + temp = dma_channel_read(dev->dma); + dev->out_r = (dma_channel_read(dev->dma) << 8) | temp; + break; + + case 0xa0: /*TODO Mono, ADPCM, 4-bit*/ + case 0xb0: /*TODO Stereo, ADPCM, 4-bit*/ + break; + } + + if (dev->regs[6] & 0x80) // Mute Left-Channel + dev->out_l = 0; + else + dev->out_l = (dev->out_l * cs423x_vols[dev->regs[6] & 0x3f]) >> 16; + + if (dev->regs[7] & 0x80) // Mute Right-Channel + dev->out_r = 0; + else + dev->out_r = (dev->out_r * cs423x_vols[dev->regs[7] & 0x3f]) >> 16; + + if (dev->regs[26] & 0x40) // Mono Output Mute + dev->out_l = dev->out_r = 0; + + if (dev->count < 0) { + dev->count = dev->regs[15] | (dev->regs[14] << 8); + if (! (dev->status & 0x01)) { + dev->status |= 0x01; + if (dev->regs[10] & 2) + picint(1 << dev->irq); + } + } + + dev->count--; +} + + +void +cs423x_init(cs423x_t *dev) +{ + double attenuation; + int c; + + dev->enable = 0; + + dev->status = 0xcc; + dev->indx = dev->trd = 0; + dev->mce = 0x40; + dev->initb = 0; + dev->mode2 = 0; + + dev->regs[0] = dev->regs[1] = 0; + dev->regs[2] = dev->regs[3] = 0x88; + dev->regs[4] = dev->regs[5] = 0x88; + dev->regs[6] = dev->regs[7] = 0x80; + dev->regs[8] = 0; + dev->regs[9] = 0x08; + dev->regs[10] = dev->regs[11] = 0; + dev->regs[12] = 0x8a; + dev->regs[13] = 0; + dev->regs[14] = dev->regs[15] = 0; + dev->regs[16] = dev->regs[17] = 0; + dev->regs[18] = dev->regs[19] = 0x88; + dev->regs[22] = 0x80; + dev->regs[24] = 0; + dev->regs[25] = CS4231; //CS4231 for GUS MAX + dev->regs[26] = 0x80; + dev->regs[29] = 0x80; + + dev->out_l = 0; + dev->out_r = 0; + + for (c = 0; c < 64; c++) { // DAC and Loopback attenuation + attenuation = 0.0; + if (c & 0x01) attenuation -= 1.5; + if (c & 0x02) attenuation -= 3.0; + if (c & 0x04) attenuation -= 6.0; + if (c & 0x08) attenuation -= 12.0; + if (c & 0x10) attenuation -= 24.0; + if (c & 0x20) attenuation -= 48.0; + + attenuation = pow(10, attenuation / 10); + cs423x_vols[c] = (int)(attenuation * 65536); + } + + timer_add(cs423x_poll, &dev->timer_count, &dev->enable, dev); +} + + +void +cs423x_speed_changed(cs423x_t *dev) +{ + dev->timer_latch = (int64_t)((double)TIMER_USEC * (1000000.0 / (double)dev->freq)); +} diff --git a/src/devices/sound/snd_cs423x.h b/src/devices/sound/snd_cs423x.h index 33cb266..68ee787 100644 --- a/src/devices/sound/snd_cs423x.h +++ b/src/devices/sound/snd_cs423x.h @@ -1,73 +1,94 @@ -/* - * VARCem Virtual ARchaeological Computer EMulator. - * An emulator of (mostly) x86-based PC systems and devices, - * using the ISA,EISA,VLB,MCA and PCI system buses, roughly - * spanning the era between 1981 and 1995. - * - * This file is part of the VARCem Project. - * - * Definitions for the Crystal CS423x driver. - * - * Version: @(#)snd_cs423x.h 1.0.0 2018/11/27 - * - * Authors: Fred N. van Kempen, - * - * Copyright 2018 Fred N. van Kempen. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the: - * - * Free Software Foundation, Inc. - * 59 Temple Place - Suite 330 - * Boston, MA 02111-1307 - * USA. - */ - -typedef struct cs423x_t -{ - int index; - uint8_t regs[32]; - uint8_t status; - - int trd; - int mce; - int ia4; - int mode2; - int initb; - - int count; - - int16_t out_l, out_r; - - int64_t enable; - - int irq, dma; - - int64_t freq; - - int64_t timer_count, timer_latch; - - int16_t buffer[SOUNDBUFLEN * 2]; - int pos; -} cs423x_t; - -void cs423x_setirq(cs423x_t *cs423x, int irq); -void cs423x_setdma(cs423x_t *cs423x, int dma); - -uint8_t cs423x_read(uint16_t addr, void *p); -void cs423x_write(uint16_t addr, uint8_t val, void *p); - -void cs423x_update(cs423x_t *cs423x); -void cs423x_speed_changed(cs423x_t *cs423x); - -void cs423x_init(cs423x_t *cs423x); +/* + * VARCem Virtual ARchaeological Computer EMulator. + * An emulator of (mostly) x86-based PC systems and devices, + * using the ISA,EISA,VLB,MCA and PCI system buses, roughly + * spanning the era between 1981 and 1995. + * + * This file is part of the VARCem Project. + * + * Definitions for the Crystal CS423x driver. + * + * Version: @(#)snd_cs423x.h 1.0.1 2019/01/13 + * + * Authors: Altheos, + * Fred N. van Kempen, + * + * Copyright 2018,2019 Altheos. + * Copyright 2018,2019 Fred N. van Kempen. + * + * Redistribution and use in source and binary forms, with + * or without modification, are permitted provided that the + * following conditions are met: + * + * 1. Redistributions of source code must retain the entire + * above notice, this list of conditions and the following + * disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names + * of its contributors may be used to endorse or promote + * products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef SND_CS423X_H +# define SND_CS423X_H + + +typedef struct { + int indx; + uint8_t regs[32]; + uint8_t status; + + int trd; + int mce; + int ia4; + int mode2; + int initb; + + int count; + + int16_t out_l, out_r; + + int64_t enable; + + int irq, dma; + + int64_t freq; + + int64_t timer_count, + timer_latch; + + int16_t buffer[SOUNDBUFLEN * 2]; + int pos; +} cs423x_t; + + +extern void cs423x_setirq(cs423x_t *, int irq); +extern void cs423x_setdma(cs423x_t *, int dma); + +extern uint8_t cs423x_read(uint16_t addr, void *priv); +extern void cs423x_write(uint16_t addr, uint8_t val, void *priv); + +extern void cs423x_update(cs423x_t *); +extern void cs423x_speed_changed(cs423x_t *); + +extern void cs423x_init(cs423x_t *); + + +#endif /*SND_CS423X_H*/ diff --git a/src/devices/sound/snd_gus.c b/src/devices/sound/snd_gus.c index aad4b18..4813e02 100644 --- a/src/devices/sound/snd_gus.c +++ b/src/devices/sound/snd_gus.c @@ -8,13 +8,13 @@ * * Implementation of the Gravis UltraSound sound device. * - * Version: @(#)snd_gus.c 1.0.8 2018/11/27 + * Version: @(#)snd_gus.c 1.0.9 2019/01/13 * * Authors: Fred N. van Kempen, * Miran Grca, * Sarah Walker, * - * Copyright 2017,2018 Fred N. van Kempen. + * Copyright 2017-2019 Fred N. van Kempen. * Copyright 2016-2018 Miran Grca. * Copyright 2008-2018 Sarah Walker. * @@ -56,94 +56,116 @@ #endif -typedef struct { - int reset; +enum { + MIDI_INT_RECEIVE = 0x01, + MIDI_INT_TRANSMIT = 0x02, + MIDI_INT_MASTER = 0x80 +}; - int global; - uint32_t addr, +enum { + MIDI_CTRL_TRANSMIT_MASK = 0x60, + MIDI_CTRL_TRANSMIT = 0x20, + MIDI_CTRL_RECEIVE = 0x80 +}; + +enum { + GUS_INT_MIDI_TRANSMIT = 0x01, + GUS_INT_MIDI_RECEIVE = 0x02 +}; + +enum { + GUS_TIMER_CTRL_AUTO = 0x01 +}; + + +typedef struct { + int reset; + + int global; + uint32_t addr, dmaaddr; - int voice; - uint32_t start[32], + int voice; + uint32_t start[32], end[32], cur[32]; - uint32_t startx[32], + uint32_t startx[32], endx[32], curx[32]; - int rstart[32], + int rstart[32], rend[32]; - int rcur[32]; - uint16_t freq[32]; - uint16_t rfreq[32]; - uint8_t ctrl[32]; - uint8_t rctrl[32]; - int curvol[32]; - int pan_l[32], + int rcur[32]; + uint16_t freq[32]; + uint16_t rfreq[32]; + uint8_t ctrl[32]; + uint8_t rctrl[32]; + int curvol[32]; + int pan_l[32], pan_r[32]; - int t1on, + int t1on, t2on; - uint8_t tctrl; - uint16_t t1, + uint8_t tctrl; + uint16_t t1, t2, t1l, t2l; - uint8_t irqstatus, + uint8_t irqstatus, irqstatus2; - uint8_t adcommand; - int waveirqs[32], + uint8_t adcommand; + int waveirqs[32], rampirqs[32]; - int voices; - uint8_t dmactrl; + int voices; + uint8_t dmactrl; - int32_t out_l, + int32_t out_l, out_r; - int64_t samp_timer, + int64_t samp_timer, samp_latch; - uint8_t *ram; + uint8_t *ram; - int pos; - int16_t buffer[2][SOUNDBUFLEN]; + int pos; + int16_t buffer[2][SOUNDBUFLEN]; - int irqnext; + int irqnext; - int64_t timer_1, + int64_t timer_1, timer_2; - int irq, + int irq, dma, irq_midi; - int latch_enable; + int latch_enable; - uint8_t sb_2xa, + uint8_t sb_2xa, sb_2xc, sb_2xe; - uint8_t sb_ctrl; - int sb_nmi; + uint8_t sb_ctrl; + int sb_nmi; - uint8_t reg_ctrl; + uint8_t reg_ctrl; - uint8_t ad_status, + uint8_t ad_status, ad_data; - uint8_t ad_timer_ctrl; + uint8_t ad_timer_ctrl; - uint8_t midi_ctrl, + uint8_t midi_ctrl, midi_status; - uint8_t midi_data; - int midi_loopback; + uint8_t midi_data; + int midi_loopback; - uint8_t gp1, + uint8_t gp1, gp2; - uint16_t gp1_addr, + uint16_t gp1_addr, gp2_addr; - uint8_t usrr; + uint8_t usrr; + + uint8_t max_ctrl; - uint8_t max_ctrl; #if defined(DEV_BRANCH) && defined(USE_GUSMAX) - cs423x_t cs423x; + cs423x_t cs423x; #endif - } gus_t; @@ -151,107 +173,80 @@ static const int gus_irqs[8] = { -1, 2, 5, 3, 7, 11, 12, 15 }; static const int gus_irqs_midi[8] = { -1, 2, 5, 3, 7, 11, 12, 15 }; static const int gus_dmas[8] = { -1, 1, 3, 5, 6, 7, -1, -1 }; static const int gusfreqs[] = { - 44100, 41160, 38587, 36317, 34300, 32494, 30870, 29400, - 28063, 26843, 25725, 24696, 23746, 22866, 22050, 21289, - 20580, 19916, 19293 + 44100, 41160, 38587, 36317, 34300, 32494, 30870, 29400, + 28063, 26843, 25725, 24696, 23746, 22866, 22050, 21289, + 20580, 19916, 19293 }; - - -static double vol16bit[4096]; +static double vol16bit[4096]; static void poll_irqs(gus_t *dev) { - int c; + int c; - dev->irqstatus &= ~0x60; - for (c = 0; c < 32; c++) { - if (dev->waveirqs[c]) { - dev->irqstatus2 = 0x60 | c; - if (dev->rampirqs[c]) - dev->irqstatus2 |= 0x80; - dev->irqstatus |= 0x20; - if (dev->irq != -1) - picint(1 << dev->irq); - return; - } + dev->irqstatus &= ~0x60; - if (dev->rampirqs[c]) { - dev->irqstatus2 = 0xA0 | c; - dev->irqstatus |= 0x40; - if (dev->irq != -1) - picint(1 << dev->irq); - return; - } + for (c = 0; c < 32; c++) { + if (dev->waveirqs[c]) { + dev->irqstatus2 = 0x60 | c; + if (dev->rampirqs[c]) + dev->irqstatus2 |= 0x80; + dev->irqstatus |= 0x20; + if (dev->irq != -1) + picint(1 << dev->irq); + return; } - dev->irqstatus2 = 0xE0; + if (dev->rampirqs[c]) { + dev->irqstatus2 = 0xa0 | c; + dev->irqstatus |= 0x40; + if (dev->irq != -1) + picint(1 << dev->irq); + return; + } + } - if (!dev->irqstatus && dev->irq != -1) - picintc(1 << dev->irq); + dev->irqstatus2 = 0xe0; + + if (!dev->irqstatus && dev->irq != -1) + picintc(1 << dev->irq); } -enum { - MIDI_INT_RECEIVE = 0x01, - MIDI_INT_TRANSMIT = 0x02, - MIDI_INT_MASTER = 0x80 -}; - -enum { - MIDI_CTRL_TRANSMIT_MASK = 0x60, - MIDI_CTRL_TRANSMIT = 0x20, - MIDI_CTRL_RECEIVE = 0x80 -}; - -enum { - GUS_INT_MIDI_TRANSMIT = 0x01, - GUS_INT_MIDI_RECEIVE = 0x02 -}; - -enum { - GUS_TIMER_CTRL_AUTO = 0x01 -}; - - static void midi_update_int_status(gus_t *dev) { - dev->midi_status &= ~MIDI_INT_MASTER; + dev->midi_status &= ~MIDI_INT_MASTER; - if ((dev->midi_ctrl & MIDI_CTRL_TRANSMIT_MASK) == MIDI_CTRL_TRANSMIT && (dev->midi_status & MIDI_INT_TRANSMIT)) { - dev->midi_status |= MIDI_INT_MASTER; - dev->irqstatus |= GUS_INT_MIDI_TRANSMIT; - } - else - dev->irqstatus &= ~GUS_INT_MIDI_TRANSMIT; + if ((dev->midi_ctrl & MIDI_CTRL_TRANSMIT_MASK) == MIDI_CTRL_TRANSMIT && (dev->midi_status & MIDI_INT_TRANSMIT)) { + dev->midi_status |= MIDI_INT_MASTER; + dev->irqstatus |= GUS_INT_MIDI_TRANSMIT; + } else + dev->irqstatus &= ~GUS_INT_MIDI_TRANSMIT; - if ((dev->midi_ctrl & MIDI_CTRL_RECEIVE) && (dev->midi_status & MIDI_INT_RECEIVE)) { - dev->midi_status |= MIDI_INT_MASTER; - dev->irqstatus |= GUS_INT_MIDI_RECEIVE; - } - else - dev->irqstatus &= ~GUS_INT_MIDI_RECEIVE; + if ((dev->midi_ctrl & MIDI_CTRL_RECEIVE) && (dev->midi_status & MIDI_INT_RECEIVE)) { + dev->midi_status |= MIDI_INT_MASTER; + dev->irqstatus |= GUS_INT_MIDI_RECEIVE; + } else + dev->irqstatus &= ~GUS_INT_MIDI_RECEIVE; - if ((dev->midi_status & MIDI_INT_MASTER) && (dev->irq_midi != -1)) { - picint(1 << dev->irq_midi); - } + if ((dev->midi_status & MIDI_INT_MASTER) && (dev->irq_midi != -1)) + picint(1 << dev->irq_midi); } static void gus_write(uint16_t addr, uint8_t val, void *priv) { - gus_t *dev = (gus_t *)priv; - int c, d; - int old; - uint16_t ioport; + gus_t *dev = (gus_t *)priv; + uint16_t ioport; + int c, d, old; - if (dev->latch_enable && addr != 0x24b) - dev->latch_enable = 0; + if (dev->latch_enable && addr != 0x24b) + dev->latch_enable = 0; - switch (addr) { + switch (addr) { case 0x340: /*MIDI control*/ old = dev->midi_ctrl; dev->midi_ctrl = val; @@ -282,262 +277,260 @@ gus_write(uint16_t addr, uint8_t val, void *priv) case 0x344: /*Global low*/ switch (dev->global) { - case 0: /*Voice control*/ - dev->ctrl[dev->voice] = val; - break; + case 0: /*Voice control*/ + dev->ctrl[dev->voice] = val; + break; - case 1: /*Frequency control*/ - dev->freq[dev->voice] = (dev->freq[dev->voice] & 0xFF00) | val; - break; + case 1: /*Frequency control*/ + dev->freq[dev->voice] = (dev->freq[dev->voice] & 0xFF00) | val; + break; - case 2: /*Start addr high*/ - dev->startx[dev->voice] = (dev->startx[dev->voice] & 0xF807F) | (val << 7); - dev->start[dev->voice] = (dev->start[dev->voice] & 0x1F00FFFF) | (val << 16); - break; + case 2: /*Start addr high*/ + dev->startx[dev->voice] = (dev->startx[dev->voice] & 0xF807F) | (val << 7); + dev->start[dev->voice] = (dev->start[dev->voice] & 0x1F00FFFF) | (val << 16); + break; - case 3: /*Start addr low*/ - dev->start[dev->voice] = (dev->start[dev->voice] & 0x1FFFFF00) | val; - break; + case 3: /*Start addr low*/ + dev->start[dev->voice] = (dev->start[dev->voice] & 0x1FFFFF00) | val; + break; - case 4: /*End addr high*/ - dev->endx[dev->voice] = (dev->endx[dev->voice] & 0xF807F) | (val << 7); - dev->end[dev->voice] = (dev->end[dev->voice] & 0x1F00FFFF) | (val << 16); - break; + case 4: /*End addr high*/ + dev->endx[dev->voice] = (dev->endx[dev->voice] & 0xF807F) | (val << 7); + dev->end[dev->voice] = (dev->end[dev->voice] & 0x1F00FFFF) | (val << 16); + break; - case 5: /*End addr low*/ - dev->end[dev->voice] = (dev->end[dev->voice] & 0x1FFFFF00) | val; - break; + case 5: /*End addr low*/ + dev->end[dev->voice] = (dev->end[dev->voice] & 0x1FFFFF00) | val; + break; - case 0x6: /*Ramp frequency*/ - dev->rfreq[dev->voice] = (int)((double)((val & 63) * 512) / (double)(1 << (3 * (val >> 6)))); - break; + case 0x6: /*Ramp frequency*/ + dev->rfreq[dev->voice] = (int)((double)((val & 63) * 512) / (double)(1 << (3 * (val >> 6)))); + break; - case 0x9: /*Current volume*/ - dev->curvol[dev->voice] = dev->rcur[dev->voice] = (dev->rcur[dev->voice] & ~(0xff << 6)) | (val << 6); - break; + case 0x9: /*Current volume*/ + dev->curvol[dev->voice] = dev->rcur[dev->voice] = (dev->rcur[dev->voice] & ~(0xff << 6)) | (val << 6); + break; - case 0xA: /*Current addr high*/ - dev->cur[dev->voice] = (dev->cur[dev->voice] & 0x1F00FFFF) | (val << 16); - dev->curx[dev->voice] = (dev->curx[dev->voice] & 0xF807F00) | ((val << 7) << 8); - break; + case 0xA: /*Current addr high*/ + dev->cur[dev->voice] = (dev->cur[dev->voice] & 0x1F00FFFF) | (val << 16); + dev->curx[dev->voice] = (dev->curx[dev->voice] & 0xF807F00) | ((val << 7) << 8); + break; + + case 0xB: /*Current addr low*/ + dev->cur[dev->voice] = (dev->cur[dev->voice] & 0x1FFFFF00) | val; + break; - case 0xB: /*Current addr low*/ - dev->cur[dev->voice] = (dev->cur[dev->voice] & 0x1FFFFF00) | val; - break; + case 0x42: /*DMA address low*/ + dev->dmaaddr = (dev->dmaaddr & 0xFF000) | (val << 4); + break; - case 0x42: /*DMA address low*/ - dev->dmaaddr = (dev->dmaaddr & 0xFF000) | (val << 4); - break; + case 0x43: /*Address low*/ + dev->addr = (dev->addr & 0xFFF00) | val; + break; - case 0x43: /*Address low*/ - dev->addr = (dev->addr & 0xFFF00) | val; - break; - - case 0x45: /*Timer control*/ - dev->tctrl = val; - break; + case 0x45: /*Timer control*/ + dev->tctrl = val; + break; } break; case 0x345: /*Global high*/ - switch (dev->global) { - case 0: /*Voice control*/ - if (!(val & 1) && dev->ctrl[dev->voice] & 1) { - } + switch (dev->global) { + case 0: /*Voice control*/ + if (!(val & 1) && dev->ctrl[dev->voice] & 1) { + //FIXME: what? + } - dev->ctrl[dev->voice] = val & 0x7f; + dev->ctrl[dev->voice] = val & 0x7f; - old = dev->waveirqs[dev->voice]; - dev->waveirqs[dev->voice] = ((val & 0xa0) == 0xa0) ? 1 : 0; - if (dev->waveirqs[dev->voice] != old) - poll_irqs(dev); - break; + old = dev->waveirqs[dev->voice]; + dev->waveirqs[dev->voice] = ((val & 0xa0) == 0xa0) ? 1 : 0; + if (dev->waveirqs[dev->voice] != old) + poll_irqs(dev); + break; - case 1: /*Frequency control*/ - dev->freq[dev->voice] = (dev->freq[dev->voice] & 0xFF) | (val << 8); - break; + case 1: /*Frequency control*/ + dev->freq[dev->voice] = (dev->freq[dev->voice] & 0xFF) | (val << 8); + break; - case 2: /*Start addr high*/ - dev->startx[dev->voice] = (dev->startx[dev->voice] & 0x07FFF) | (val << 15); - dev->start[dev->voice] = (dev->start[dev->voice] & 0x00FFFFFF) | ((val & 0x1F) << 24); - break; + case 2: /*Start addr high*/ + dev->startx[dev->voice] = (dev->startx[dev->voice] & 0x07FFF) | (val << 15); + dev->start[dev->voice] = (dev->start[dev->voice] & 0x00FFFFFF) | ((val & 0x1F) << 24); + break; - case 3: /*Start addr low*/ - dev->startx[dev->voice] = (dev->startx[dev->voice] & 0xFFF80) | (val & 0x7F); - dev->start[dev->voice] = (dev->start[dev->voice] & 0x1FFF00FF) | (val << 8); - break; + case 3: /*Start addr low*/ + dev->startx[dev->voice] = (dev->startx[dev->voice] & 0xFFF80) | (val & 0x7F); + dev->start[dev->voice] = (dev->start[dev->voice] & 0x1FFF00FF) | (val << 8); + break; - case 4: /*End addr high*/ - dev->endx[dev->voice] = (dev->endx[dev->voice] & 0x07FFF) | (val << 15); - dev->end[dev->voice] = (dev->end[dev->voice] & 0x00FFFFFF) | ((val & 0x1F) << 24); - break; + case 4: /*End addr high*/ + dev->endx[dev->voice] = (dev->endx[dev->voice] & 0x07FFF) | (val << 15); + dev->end[dev->voice] = (dev->end[dev->voice] & 0x00FFFFFF) | ((val & 0x1F) << 24); + break; - case 5: /*End addr low*/ - dev->endx[dev->voice] = (dev->endx[dev->voice] & 0xFFF80) | (val & 0x7F); - dev->end[dev->voice] = (dev->end[dev->voice] & 0x1FFF00FF) | (val << 8); - break; + case 5: /*End addr low*/ + dev->endx[dev->voice] = (dev->endx[dev->voice] & 0xFFF80) | (val & 0x7F); + dev->end[dev->voice] = (dev->end[dev->voice] & 0x1FFF00FF) | (val << 8); + break; - case 0x6: /*Ramp frequency*/ - dev->rfreq[dev->voice] = (int)((double)((val & 63) * (1 << 10)) / (double)(1 << (3 * (val >> 6)))); - break; + case 0x6: /*Ramp frequency*/ + dev->rfreq[dev->voice] = (int)((double)((val & 63) * (1 << 10)) / (double)(1 << (3 * (val >> 6)))); + break; - case 0x7: /*Ramp start*/ - dev->rstart[dev->voice] = val << 14; - break; + case 0x7: /*Ramp start*/ + dev->rstart[dev->voice] = val << 14; + break; - case 0x8: /*Ramp end*/ - dev->rend[dev->voice] = val << 14; - break; + case 0x8: /*Ramp end*/ + dev->rend[dev->voice] = val << 14; + break; - case 0x9: /*Current volume*/ - dev->curvol[dev->voice] = dev->rcur[dev->voice] = (dev->rcur[dev->voice] & ~(0xff << 14)) | (val << 14); - break; + case 0x9: /*Current volume*/ + dev->curvol[dev->voice] = dev->rcur[dev->voice] = (dev->rcur[dev->voice] & ~(0xff << 14)) | (val << 14); + break; - case 0xA: /*Current addr high*/ - dev->cur[dev->voice] = (dev->cur[dev->voice] & 0x00FFFFFF) | ((val & 0x1F) << 24); - dev->curx[dev->voice] = (dev->curx[dev->voice] & 0x07FFF00) | ((val << 15) << 8); - break; + case 0xA: /*Current addr high*/ + dev->cur[dev->voice] = (dev->cur[dev->voice] & 0x00FFFFFF) | ((val & 0x1F) << 24); + dev->curx[dev->voice] = (dev->curx[dev->voice] & 0x07FFF00) | ((val << 15) << 8); + break; - case 0xB: /*Current addr low*/ - dev->cur[dev->voice] = (dev->cur[dev->voice] & 0x1FFF00FF) | (val << 8); - dev->curx[dev->voice] = (dev->curx[dev->voice] & 0xFFF8000) | ((val & 0x7F) << 8); - break; + case 0xB: /*Current addr low*/ + dev->cur[dev->voice] = (dev->cur[dev->voice] & 0x1FFF00FF) | (val << 8); + dev->curx[dev->voice] = (dev->curx[dev->voice] & 0xFFF8000) | ((val & 0x7F) << 8); + break; - case 0xC: /*Pan*/ - dev->pan_l[dev->voice] = 15 - (val & 0xf); - dev->pan_r[dev->voice] = (val & 0xf); - break; + case 0xC: /*Pan*/ + dev->pan_l[dev->voice] = 15 - (val & 0xf); + dev->pan_r[dev->voice] = (val & 0xf); + break; - case 0xD: /*Ramp control*/ - old = dev->rampirqs[dev->voice]; - dev->rctrl[dev->voice] = val & 0x7F; - dev->rampirqs[dev->voice] = ((val & 0xa0) == 0xa0) ? 1 : 0; - if (dev->rampirqs[dev->voice] != old) - poll_irqs(dev); - break; + case 0xD: /*Ramp control*/ + old = dev->rampirqs[dev->voice]; + dev->rctrl[dev->voice] = val & 0x7F; + dev->rampirqs[dev->voice] = ((val & 0xa0) == 0xa0) ? 1 : 0; + if (dev->rampirqs[dev->voice] != old) + poll_irqs(dev); + break; - case 0xE: - dev->voices = (val & 63) + 1; - if (dev->voices > 32) dev->voices = 32; - if (dev->voices < 14) dev->voices = 14; - dev->global = val; - if (dev->voices < 14) - dev->samp_latch = (int)(TIMER_USEC * (1000000.0 / 44100.0)); - else - dev->samp_latch = (int)(TIMER_USEC * (1000000.0 / gusfreqs[dev->voices - 14])); - break; + case 0xE: + dev->voices = (val & 63) + 1; + if (dev->voices > 32) dev->voices = 32; + if (dev->voices < 14) dev->voices = 14; + dev->global = val; + if (dev->voices < 14) + dev->samp_latch = (int)(TIMER_USEC * (1000000.0 / 44100.0)); + else + dev->samp_latch = (int)(TIMER_USEC * (1000000.0 / gusfreqs[dev->voices - 14])); + break; - case 0x41: /*DMA*/ - if (val & 1 && dev->dma != -1) { - if (val & 2) { - c = 0; - while (c < 65536) { - int dma_result; - - if (val & 0x04) { - uint32_t gus_addr = (dev->dmaaddr & 0xc0000) | ((dev->dmaaddr & 0x1ffff) << 1); - d = dev->ram[gus_addr] | (dev->ram[gus_addr + 1] << 8); - if (val & 0x80) - d ^= 0x8080; - dma_result = dma_channel_write(dev->dma, d); - if (dma_result == DMA_NODATA) + case 0x41: /*DMA*/ + if (val & 1 && dev->dma != -1) { + if (val & 2) { + c = 0; + while (c < 65536) { + int dma_result; + + if (val & 0x04) { + uint32_t gus_addr = (dev->dmaaddr & 0xc0000) | ((dev->dmaaddr & 0x1ffff) << 1); + d = dev->ram[gus_addr] | (dev->ram[gus_addr + 1] << 8); + if (val & 0x80) + d ^= 0x8080; + dma_result = dma_channel_write(dev->dma, d); + if (dma_result == DMA_NODATA) + break; + } else { + d = dev->ram[dev->dmaaddr]; + if (val & 0x80) + d ^= 0x80; + dma_result = dma_channel_write(dev->dma, d); + if (dma_result == DMA_NODATA) + break; + } + dev->dmaaddr++; + dev->dmaaddr &= 0xFFFFF; + c++; + if (dma_result & DMA_OVER) break; } - else { - d = dev->ram[dev->dmaaddr]; - if (val & 0x80) - d ^= 0x80; - dma_result = dma_channel_write(dev->dma, d); - if (dma_result == DMA_NODATA) + dev->dmactrl = val & ~0x40; + if (val & 0x20) + dev->irqnext = 1; + } else { + c = 0; + while (c < 65536) { + d = dma_channel_read(dev->dma); + if (d == DMA_NODATA) + break; + if (val & 0x04) { + uint32_t gus_addr = (dev->dmaaddr & 0xc0000) | ((dev->dmaaddr & 0x1ffff) << 1); + if (val & 0x80) + d ^= 0x8080; + dev->ram[gus_addr] = d & 0xff; + dev->ram[gus_addr + 1] = (d >> 8) & 0xff; + } else { + if (val & 0x80) + d ^= 0x80; + dev->ram[dev->dmaaddr] = d; + } + dev->dmaaddr++; + dev->dmaaddr &= 0xFFFFF; + c++; + if (d & DMA_OVER) break; } - dev->dmaaddr++; - dev->dmaaddr &= 0xFFFFF; - c++; - if (dma_result & DMA_OVER) - break; + dev->dmactrl = val & ~0x40; + if (val & 0x20) + dev->irqnext = 1; } - dev->dmactrl = val & ~0x40; - if (val & 0x20) - dev->irqnext = 1; } - else { - c = 0; - while (c < 65536) { - d = dma_channel_read(dev->dma); - if (d == DMA_NODATA) - break; - if (val & 0x04) { - uint32_t gus_addr = (dev->dmaaddr & 0xc0000) | ((dev->dmaaddr & 0x1ffff) << 1); - if (val & 0x80) - d ^= 0x8080; - dev->ram[gus_addr] = d & 0xff; - dev->ram[gus_addr + 1] = (d >> 8) & 0xff; - } - else { - if (val & 0x80) - d ^= 0x80; - dev->ram[dev->dmaaddr] = d; - } - dev->dmaaddr++; - dev->dmaaddr &= 0xFFFFF; - c++; - if (d & DMA_OVER) - break; - } - dev->dmactrl = val & ~0x40; - if (val & 0x20) - dev->irqnext = 1; + break; + + case 0x42: /*DMA address low*/ + dev->dmaaddr = (dev->dmaaddr & 0xFF0) | (val << 12); + break; + + case 0x43: /*Address low*/ + dev->addr = (dev->addr & 0xF00FF) | (val << 8); + break; + + case 0x44: /*Address high*/ + dev->addr = (dev->addr & 0xFFFF) | ((val << 16) & 0xF0000); + break; + + case 0x45: /*Timer control*/ + if (!(val & 4)) dev->irqstatus &= ~4; + if (!(val & 8)) dev->irqstatus &= ~8; + if (!(val & 0x20)) { + dev->ad_status &= ~0x18; + nmi = 0; } - } - break; + if (!(val & 0x02)) { + dev->ad_status &= ~0x01; + nmi = 0; + } + dev->tctrl = val; + dev->sb_ctrl = val; + break; - case 0x42: /*DMA address low*/ - dev->dmaaddr = (dev->dmaaddr & 0xFF0) | (val << 12); - break; + case 0x46: /*Timer 1*/ + dev->t1 = dev->t1l = val; + dev->t1on = 1; + break; - case 0x43: /*Address low*/ - dev->addr = (dev->addr & 0xF00FF) | (val << 8); - break; + case 0x47: /*Timer 2*/ + dev->t2 = dev->t2l = val; + dev->t2on = 1; + break; - case 0x44: /*Address high*/ - dev->addr = (dev->addr & 0xFFFF) | ((val << 16) & 0xF0000); - break; - - case 0x45: /*Timer control*/ - if (!(val & 4)) dev->irqstatus &= ~4; - if (!(val & 8)) dev->irqstatus &= ~8; - if (!(val & 0x20)) { - dev->ad_status &= ~0x18; - nmi = 0; - } - if (!(val & 0x02)) { - dev->ad_status &= ~0x01; - nmi = 0; - } - dev->tctrl = val; - dev->sb_ctrl = val; - break; - - case 0x46: /*Timer 1*/ - dev->t1 = dev->t1l = val; - dev->t1on = 1; - break; - - case 0x47: /*Timer 2*/ - dev->t2 = dev->t2l = val; - dev->t2on = 1; - break; - - case 0x4c: /*Reset*/ - dev->reset = val; - break; + case 0x4c: /*Reset*/ + dev->reset = val; + break; } break; case 0x347: /*DRAM access*/ dev->ram[dev->addr] = val; - dev->addr &= 0xFFFFF; + dev->addr &= 0xfffff; break; case 0x248: @@ -583,53 +576,52 @@ gus_write(uint16_t addr, uint8_t val, void *priv) case 0x24b: switch (dev->reg_ctrl & 0x07) { - case 0: - if (dev->latch_enable == 1) - dev->dma = gus_dmas[val & 7]; + case 0: + if (dev->latch_enable == 1) + dev->dma = gus_dmas[val & 7]; #if defined(DEV_BRANCH) && defined(USE_GUSMAX) - cs423x_setdma(&dev->cs423x, dev->dma); + cs423x_setdma(&dev->cs423x, dev->dma); #endif - if (dev->latch_enable == 2) { - dev->irq = gus_irqs[val & 7]; + if (dev->latch_enable == 2) { + dev->irq = gus_irqs[val & 7]; - if (val & 0x40) { - if (dev->irq == -1) - dev->irq = dev->irq_midi = gus_irqs[(val >> 3) & 7]; - else - dev->irq_midi = dev->irq; - } - else - dev->irq_midi = gus_irqs_midi[(val >> 3) & 7]; + if (val & 0x40) { + if (dev->irq == -1) + dev->irq = dev->irq_midi = gus_irqs[(val >> 3) & 7]; + else + dev->irq_midi = dev->irq; + } else + dev->irq_midi = gus_irqs_midi[(val >> 3) & 7]; #if defined(DEV_BRANCH) && defined(USE_GUSMAX) - cs423x_setirq(&dev->cs423x, dev->irq); + cs423x_setirq(&dev->cs423x, dev->irq); #endif - dev->sb_nmi = val & 0x80; - } - dev->latch_enable = 0; - break; + dev->sb_nmi = val & 0x80; + } + dev->latch_enable = 0; + break; - case 1: - dev->gp1 = val; - break; + case 1: + dev->gp1 = val; + break; - case 2: - dev->gp2 = val; - break; + case 2: + dev->gp2 = val; + break; - case 3: - dev->gp1_addr = val; - break; + case 3: + dev->gp1_addr = val; + break; - case 4: - dev->gp2_addr = val; - break; + case 4: + dev->gp2_addr = val; + break; - case 5: - dev->usrr = 0; - break; + case 5: + dev->usrr = 0; + break; - case 6: - break; + case 6: + break; } break; @@ -673,16 +665,20 @@ gus_write(uint16_t addr, uint8_t val, void *priv) if (dev->dma >= 4) val |= 0x30; dev->max_ctrl = (val >> 6) & 1; +#if defined(DEV_BRANCH) && defined(USE_GUSMAX) if (val & 0x40) { if ((val & 0xF) != ((addr >> 4) & 0xF)) { /* Fix me : why is DOS application attempting to relocate the CODEC ? */ ioport = 0x30c | ((addr >> 4) & 0xf); io_removehandler(ioport, 4, - cs423x_read, NULL, NULL, cs423x_write, NULL, NULL, &dev->cs423x); + cs423x_read,NULL,NULL, + cs423x_write,NULL,NULL,&dev->cs423x); ioport = 0x30c | ((val & 0xf) << 4); io_sethandler(ioport, 4, - cs423x_read, NULL, NULL, cs423x_write, NULL, NULL, &dev->cs423x); + cs423x_read,NULL,NULL, + cs423x_write,NULL,NULL, &dev->cs423x); } } +#endif break; } } @@ -691,10 +687,10 @@ gus_write(uint16_t addr, uint8_t val, void *priv) static uint8_t gus_read(uint16_t addr, void *priv) { - gus_t *dev = (gus_t *)priv; - uint8_t val = 0xff; + gus_t *dev = (gus_t *)priv; + uint8_t val = 0xff; - switch (addr) { + switch (addr) { case 0x340: /*MIDI status*/ val = dev->midi_status; break; @@ -901,415 +897,384 @@ gus_read(uint16_t addr, void *priv) val = dev->adcommand; break; - } + } - return(val); + return(val); } static void poll_timer_1(void *priv) { - gus_t *dev = (gus_t *)priv; + gus_t *dev = (gus_t *)priv; - dev->timer_1 += (TIMER_USEC * 80LL); - if (dev->t1on) { - dev->t1++; - if (dev->t1 > 0xFF) { - dev->t1 = dev->t1l; - dev->ad_status |= 0x40; - if (dev->tctrl & 4) { - if (dev->irq != -1) - picint(1 << dev->irq); - dev->ad_status |= 0x04; - dev->irqstatus |= 0x04; - } + dev->timer_1 += (TIMER_USEC * 80LL); + + if (dev->t1on) { + dev->t1++; + if (dev->t1 > 0xFF) { + dev->t1 = dev->t1l; + dev->ad_status |= 0x40; + if (dev->tctrl & 4) { + if (dev->irq != -1) + picint(1 << dev->irq); + dev->ad_status |= 0x04; + dev->irqstatus |= 0x04; } } + } - if (dev->irqnext) { - dev->irqnext = 0; - dev->irqstatus |= 0x80; - if (dev->irq != -1) - picint(1 << dev->irq); - } + if (dev->irqnext) { + dev->irqnext = 0; + dev->irqstatus |= 0x80; + if (dev->irq != -1) + picint(1 << dev->irq); + } - midi_update_int_status(dev); + midi_update_int_status(dev); } static void poll_timer_2(void *priv) { - gus_t *dev = (gus_t *)priv; + gus_t *dev = (gus_t *)priv; - dev->timer_2 += (TIMER_USEC * 320LL); - if (dev->t2on) { - dev->t2++; - if (dev->t2 > 0xFF) { - dev->t2 = dev->t2l; - dev->ad_status |= 0x20; - if (dev->tctrl & 8) { - if (dev->irq != -1) - picint(1 << dev->irq); - dev->ad_status |= 0x02; - dev->irqstatus |= 0x08; - } + dev->timer_2 += (TIMER_USEC * 320LL); + + if (dev->t2on) { + dev->t2++; + if (dev->t2 > 0xFF) { + dev->t2 = dev->t2l; + dev->ad_status |= 0x20; + if (dev->tctrl & 8) { + if (dev->irq != -1) + picint(1 << dev->irq); + dev->ad_status |= 0x02; + dev->irqstatus |= 0x08; } } + } - if (dev->irqnext) { - dev->irqnext = 0; - dev->irqstatus |= 0x80; - if (dev->irq != -1) - picint(1 << dev->irq); - } + if (dev->irqnext) { + dev->irqnext = 0; + dev->irqstatus |= 0x80; + if (dev->irq != -1) + picint(1 << dev->irq); + } } static void gus_update(gus_t *dev) { - for (; dev->pos < sound_pos_global; dev->pos++) { - if (dev->out_l < -32768) - dev->buffer[0][dev->pos] = -32768; - else if (dev->out_l > 32767) - dev->buffer[0][dev->pos] = 32767; - else - dev->buffer[0][dev->pos] = dev->out_l; - if (dev->out_r < -32768) - dev->buffer[1][dev->pos] = -32768; - else if (dev->out_r > 32767) - dev->buffer[1][dev->pos] = 32767; - else - dev->buffer[1][dev->pos] = dev->out_r; - } + for (; dev->pos < sound_pos_global; dev->pos++) { + if (dev->out_l < -32768) + dev->buffer[0][dev->pos] = -32768; + else if (dev->out_l > 32767) + dev->buffer[0][dev->pos] = 32767; + else + dev->buffer[0][dev->pos] = dev->out_l; + if (dev->out_r < -32768) + dev->buffer[1][dev->pos] = -32768; + else if (dev->out_r > 32767) + dev->buffer[1][dev->pos] = 32767; + else + dev->buffer[1][dev->pos] = dev->out_r; + } } static void poll_wave(void *priv) { - gus_t *dev = (gus_t *)priv; - uint32_t addr; - int d; - int16_t v; - int32_t vl; - int update_irqs = 0; + gus_t *dev = (gus_t *)priv; + uint32_t addr; + int d; + int16_t v; + int32_t vl; + int update_irqs = 0; - gus_update(dev); + gus_update(dev); - dev->samp_timer += dev->samp_latch; + dev->samp_timer += dev->samp_latch; - dev->out_l = dev->out_r = 0; + dev->out_l = dev->out_r = 0; - if ((dev->reset & 3) != 3) - return; + if ((dev->reset & 3) != 3) + return; - for (d = 0; d < 32; d++) { - if (!(dev->ctrl[d] & 3)) { - if (dev->ctrl[d] & 4) { - addr = dev->cur[d] >> 9; - addr = (addr & 0xC0000) | ((addr << 1) & 0x3FFFE); + for (d = 0; d < 32; d++) { + if (!(dev->ctrl[d] & 3)) { + if (dev->ctrl[d] & 4) { + addr = dev->cur[d] >> 9; + addr = (addr & 0xC0000) | ((addr << 1) & 0x3FFFE); - if (!(dev->freq[d] >> 10)) { /*Interpolate*/ - vl = (int16_t)(int8_t)((dev->ram[(addr + 1) & 0xFFFFF] ^ 0x80) - 0x80) * (511 - (dev->cur[d] & 511)); - vl += (int16_t)(int8_t)((dev->ram[(addr + 3) & 0xFFFFF] ^ 0x80) - 0x80) * (dev->cur[d] & 511); - v = vl >> 9; - } - else - v = (int16_t)(int8_t)((dev->ram[(addr + 1) & 0xFFFFF] ^ 0x80) - 0x80); - } - else { - if (!(dev->freq[d] >> 10)) { /*Interpolate*/ - vl = ((int8_t)((dev->ram[(dev->cur[d] >> 9) & 0xFFFFF] ^ 0x80) - 0x80)) * (511 - (dev->cur[d] & 511)); - vl += ((int8_t)((dev->ram[((dev->cur[d] >> 9) + 1) & 0xFFFFF] ^ 0x80) - 0x80)) * (dev->cur[d] & 511); - v = vl >> 9; - } - else - v = (int16_t)(int8_t)((dev->ram[(dev->cur[d] >> 9) & 0xFFFFF] ^ 0x80) - 0x80); - } - - if ((dev->rcur[d] >> 14) > 4095) - v = (int16_t)((float)v * 24.0 * vol16bit[4095]); - else - v = (int16_t)((float)v * 24.0 * vol16bit[(dev->rcur[d] >> 10) & 4095]); - - dev->out_l += (v * dev->pan_l[d]) / 7; - dev->out_r += (v * dev->pan_r[d]) / 7; - - if (dev->ctrl[d] & 0x40) { - dev->cur[d] -= (dev->freq[d] >> 1); - if (dev->cur[d] <= dev->start[d]) { - int diff = dev->start[d] - dev->cur[d]; - - if (dev->ctrl[d] & 8) { - if (dev->ctrl[d] & 0x10) - dev->ctrl[d] ^= 0x40; - dev->cur[d] = (dev->ctrl[d] & 0x40) ? (dev->end[d] - diff) : (dev->start[d] + diff); - } - else if (!(dev->rctrl[d] & 4)) { - dev->ctrl[d] |= 1; - dev->cur[d] = (dev->ctrl[d] & 0x40) ? dev->end[d] : dev->start[d]; - } - - if ((dev->ctrl[d] & 0x20) && !dev->waveirqs[d]) { - dev->waveirqs[d] = 1; - update_irqs = 1; - } - } - } - else { - dev->cur[d] += (dev->freq[d] >> 1); - - if (dev->cur[d] >= dev->end[d]) { - int diff = dev->cur[d] - dev->end[d]; - - if (dev->ctrl[d] & 8) { - if (dev->ctrl[d] & 0x10) - dev->ctrl[d] ^= 0x40; - dev->cur[d] = (dev->ctrl[d] & 0x40) ? (dev->end[d] - diff) : (dev->start[d] + diff); - } - else if (!(dev->rctrl[d] & 4)) { - dev->ctrl[d] |= 1; - dev->cur[d] = (dev->ctrl[d] & 0x40) ? dev->end[d] : dev->start[d]; - } - - if ((dev->ctrl[d] & 0x20) && !dev->waveirqs[d]) { - dev->waveirqs[d] = 1; - update_irqs = 1; - } - } - } + if (!(dev->freq[d] >> 10)) { /*Interpolate*/ + vl = (int16_t)(int8_t)((dev->ram[(addr + 1) & 0xFFFFF] ^ 0x80) - 0x80) * (511 - (dev->cur[d] & 511)); + vl += (int16_t)(int8_t)((dev->ram[(addr + 3) & 0xFFFFF] ^ 0x80) - 0x80) * (dev->cur[d] & 511); + v = vl >> 9; + } else + v = (int16_t)(int8_t)((dev->ram[(addr + 1) & 0xFFFFF] ^ 0x80) - 0x80); + } else { + if (!(dev->freq[d] >> 10)) { /*Interpolate*/ + vl = ((int8_t)((dev->ram[(dev->cur[d] >> 9) & 0xFFFFF] ^ 0x80) - 0x80)) * (511 - (dev->cur[d] & 511)); + vl += ((int8_t)((dev->ram[((dev->cur[d] >> 9) + 1) & 0xFFFFF] ^ 0x80) - 0x80)) * (dev->cur[d] & 511); + v = vl >> 9; + } else + v = (int16_t)(int8_t)((dev->ram[(dev->cur[d] >> 9) & 0xFFFFF] ^ 0x80) - 0x80); } - if (!(dev->rctrl[d] & 3)) { - if (dev->rctrl[d] & 0x40) { - dev->rcur[d] -= dev->rfreq[d]; - if (dev->rcur[d] <= dev->rstart[d]) { - int diff = dev->rstart[d] - dev->rcur[d]; + if ((dev->rcur[d] >> 14) > 4095) + v = (int16_t)((float)v * 24.0 * vol16bit[4095]); + else + v = (int16_t)((float)v * 24.0 * vol16bit[(dev->rcur[d] >> 10) & 4095]); - if (!(dev->rctrl[d] & 8)) { - dev->rctrl[d] |= 1; - dev->rcur[d] = (dev->rctrl[d] & 0x40) ? dev->rstart[d] : dev->rend[d]; - } - else { - if (dev->rctrl[d] & 0x10) - dev->rctrl[d] ^= 0x40; - dev->rcur[d] = (dev->rctrl[d] & 0x40) ? (dev->rend[d] - diff) : (dev->rstart[d] + diff); - } + dev->out_l += (v * dev->pan_l[d]) / 7; + dev->out_r += (v * dev->pan_r[d]) / 7; - if ((dev->rctrl[d] & 0x20) && !dev->rampirqs[d]) { - dev->rampirqs[d] = 1; - update_irqs = 1; - } + if (dev->ctrl[d] & 0x40) { + dev->cur[d] -= (dev->freq[d] >> 1); + if (dev->cur[d] <= dev->start[d]) { + int diff = dev->start[d] - dev->cur[d]; + + if (dev->ctrl[d] & 8) { + if (dev->ctrl[d] & 0x10) + dev->ctrl[d] ^= 0x40; + dev->cur[d] = (dev->ctrl[d] & 0x40) ? (dev->end[d] - diff) : (dev->start[d] + diff); + } else if (!(dev->rctrl[d] & 4)) { + dev->ctrl[d] |= 1; + dev->cur[d] = (dev->ctrl[d] & 0x40) ? dev->end[d] : dev->start[d]; + } + + if ((dev->ctrl[d] & 0x20) && !dev->waveirqs[d]) { + dev->waveirqs[d] = 1; + update_irqs = 1; } } - else { - dev->rcur[d] += dev->rfreq[d]; - if (dev->rcur[d] >= dev->rend[d]) { - int diff = dev->rcur[d] - dev->rend[d]; + } else { + dev->cur[d] += (dev->freq[d] >> 1); - if (!(dev->rctrl[d] & 8)) { - dev->rctrl[d] |= 1; - dev->rcur[d] = (dev->rctrl[d] & 0x40) ? dev->rstart[d] : dev->rend[d]; - } - else { - if (dev->rctrl[d] & 0x10) - dev->rctrl[d] ^= 0x40; - dev->rcur[d] = (dev->rctrl[d] & 0x40) ? (dev->rend[d] - diff) : (dev->rstart[d] + diff); - } + if (dev->cur[d] >= dev->end[d]) { + int diff = dev->cur[d] - dev->end[d]; - if ((dev->rctrl[d] & 0x20) && !dev->rampirqs[d]) { - dev->rampirqs[d] = 1; - update_irqs = 1; - } + if (dev->ctrl[d] & 8) { + if (dev->ctrl[d] & 0x10) + dev->ctrl[d] ^= 0x40; + dev->cur[d] = (dev->ctrl[d] & 0x40) ? (dev->end[d] - diff) : (dev->start[d] + diff); + } else if (!(dev->rctrl[d] & 4)) { + dev->ctrl[d] |= 1; + dev->cur[d] = (dev->ctrl[d] & 0x40) ? dev->end[d] : dev->start[d]; + } + + if ((dev->ctrl[d] & 0x20) && !dev->waveirqs[d]) { + dev->waveirqs[d] = 1; + update_irqs = 1; } } } } - if (update_irqs) - poll_irqs(dev); + if (!(dev->rctrl[d] & 3)) { + if (dev->rctrl[d] & 0x40) { + dev->rcur[d] -= dev->rfreq[d]; + if (dev->rcur[d] <= dev->rstart[d]) { + int diff = dev->rstart[d] - dev->rcur[d]; + + if (!(dev->rctrl[d] & 8)) { + dev->rctrl[d] |= 1; + dev->rcur[d] = (dev->rctrl[d] & 0x40) ? dev->rstart[d] : dev->rend[d]; + } else { + if (dev->rctrl[d] & 0x10) + dev->rctrl[d] ^= 0x40; + dev->rcur[d] = (dev->rctrl[d] & 0x40) ? (dev->rend[d] - diff) : (dev->rstart[d] + diff); + } + + if ((dev->rctrl[d] & 0x20) && !dev->rampirqs[d]) { + dev->rampirqs[d] = 1; + update_irqs = 1; + } + } + } else { + dev->rcur[d] += dev->rfreq[d]; + if (dev->rcur[d] >= dev->rend[d]) { + int diff = dev->rcur[d] - dev->rend[d]; + + if (!(dev->rctrl[d] & 8)) { + dev->rctrl[d] |= 1; + dev->rcur[d] = (dev->rctrl[d] & 0x40) ? dev->rstart[d] : dev->rend[d]; + } else { + if (dev->rctrl[d] & 0x10) + dev->rctrl[d] ^= 0x40; + dev->rcur[d] = (dev->rctrl[d] & 0x40) ? (dev->rend[d] - diff) : (dev->rstart[d] + diff); + } + + if ((dev->rctrl[d] & 0x20) && !dev->rampirqs[d]) { + dev->rampirqs[d] = 1; + update_irqs = 1; + } + } + } + } + } + + if (update_irqs) + poll_irqs(dev); } static void get_buffer(int32_t *buffer, int len, void *priv) { - gus_t *dev = (gus_t *)priv; - int c; + gus_t *dev = (gus_t *)priv; + int c; #if defined(DEV_BRANCH) && defined(USE_GUSMAX) - if (dev->max_ctrl) - cs423x_update(&dev->cs423x); + if (dev->max_ctrl) + cs423x_update(&dev->cs423x); #endif - gus_update(dev); + gus_update(dev); - for (c = 0; c < len * 2; c++) { + for (c = 0; c < len * 2; c++) { #if defined(DEV_BRANCH) && defined(USE_GUSMAX) - if (dev->max_ctrl) - buffer[c] += (int32_t)(dev->cs423x.buffer[c] / 2); + if (dev->max_ctrl) + buffer[c] += (int32_t)(dev->cs423x.buffer[c] / 2); #endif - buffer[c] += (int32_t)dev->buffer[c & 1][c >> 1]; - } + buffer[c] += (int32_t)dev->buffer[c & 1][c >> 1]; + } #if defined(DEV_BRANCH) && defined(USE_GUSMAX) - if (dev->max_ctrl) - dev->cs423x.pos = 0; + if (dev->max_ctrl) + dev->cs423x.pos = 0; #endif - dev->pos = 0; + dev->pos = 0; } static void * gus_init(const device_t *info) { - int c; - double out = 1.0; - gus_t *dev = (gus_t *)mem_alloc(sizeof(gus_t)); + gus_t *dev; + double out = 1.0; + int c; - memset(dev, 0x00, sizeof(gus_t)); + dev = (gus_t *)mem_alloc(sizeof(gus_t)); + memset(dev, 0x00, sizeof(gus_t)); - dev->ram = (uint8_t *)mem_alloc(1 << 20); - memset(dev->ram, 0x00, 1 << 20); + dev->ram = (uint8_t *)mem_alloc(1 << 20); + memset(dev->ram, 0x00, 1 << 20); - for (c = 0; c < 32; c++) { - dev->ctrl[c] = 1; - dev->rctrl[c] = 1; - dev->rfreq[c] = 63 * 512; - } + for (c = 0; c < 32; c++) { + dev->ctrl[c] = 1; + dev->rctrl[c] = 1; + dev->rfreq[c] = 63 * 512; + } - for (c = 4095; c >= 0; c--) { - vol16bit[c] = out; - out /= 1.002709201; /* 0.0235 dB Steps */ - } + for (c = 4095; c >= 0; c--) { + vol16bit[c] = out; + out /= 1.002709201; /* 0.0235 dB Steps */ + } - // DEBUG("GUS: top volume %f %f %f %f\n",vol16bit[4095],vol16bit[3800],vol16bit[3000],vol16bit[2048]); - dev->voices = 14; + // DEBUG("GUS: top volume %f %f %f %f\n",vol16bit[4095],vol16bit[3800],vol16bit[3000],vol16bit[2048]); - dev->samp_timer = dev->samp_latch = (int64_t)(TIMER_USEC * (1000000.0 / 44100.0)); + dev->voices = 14; - dev->t1l = dev->t2l = 0xff; + dev->samp_timer = dev->samp_latch = (int64_t)(TIMER_USEC * (1000000.0 / 44100.0)); - io_sethandler(0x0240, 16, - gus_read, NULL, NULL, gus_write, NULL, NULL, dev); - io_sethandler(0x0340, 16, - gus_read, NULL, NULL, gus_write, NULL, NULL, dev); - io_sethandler(0x0746, 1, - gus_read, NULL, NULL, gus_write, NULL, NULL, dev); - io_sethandler(0x0388, 2, - gus_read, NULL, NULL, gus_write, NULL, NULL, dev); + dev->t1l = dev->t2l = 0xff; - timer_add(poll_wave, &dev->samp_timer, TIMER_ALWAYS_ENABLED, dev); - timer_add(poll_timer_1, &dev->timer_1, TIMER_ALWAYS_ENABLED, dev); - timer_add(poll_timer_2, &dev->timer_2, TIMER_ALWAYS_ENABLED, dev); + switch(info->local) { + case 0: /* Standard GUS */ + io_sethandler(0x0240, 16, + gus_read,NULL,NULL, gus_write,NULL,NULL, dev); + io_sethandler(0x0340, 16, + gus_read,NULL,NULL, gus_write,NULL,NULL, dev); + io_sethandler(0x0746, 1, + gus_read,NULL,NULL, gus_write,NULL,NULL, dev); + io_sethandler(0x0388, 2, + gus_read,NULL,NULL, gus_write,NULL,NULL, dev); - sound_add_handler(get_buffer, dev); - - return(dev); -} + break; #if defined(DEV_BRANCH) && defined(USE_GUSMAX) -static void * -gus_max_init(const device_t *info) -{ - int c; - double out = 1.0; - gus_t *dev = (gus_t *)mem_alloc(sizeof(gus_t)); + case 1: /* GUS MAX */ + cs423x_init(&dev->cs423x); + cs423x_setirq(&dev->cs423x, 5); /*Default irq and dma from GUS SDK*/ + cs423x_setdma(&dev->cs423x, 3); - memset(dev, 0x00, sizeof(gus_t)); + io_sethandler(0x0240, 16, + gus_read,NULL,NULL, gus_write,NULL, NULL, dev); + io_sethandler(0x0340, 9, + gus_read,NULL,NULL, gus_write,NULL, NULL, dev); + io_sethandler(0x0746, 1, + gus_read,NULL,NULL, gus_write,NULL, NULL, dev); + io_sethandler(0x0388, 2, + gus_read,NULL,NULL, gus_write,NULL, NULL, dev); + io_sethandler(0x034c, 4, + cs423x_read,NULL,NULL, cs423x_write,NULL,NULL, &dev->cs423x); - dev->ram = (uint8_t *)mem_alloc(1 << 20); // Maximum 1 Mb RAM - memset(dev->ram, 0x00, 1 << 20); - - for (c = 0;c < 32;c++) { - dev->ctrl[c] = 1; - dev->rctrl[c] = 1; - dev->rfreq[c] = 63 * 512; - } - - for (c = 4095;c >= 0;c--) { - vol16bit[c] = out; - out /= 1.002709201; - } - - dev->voices = 14; - - dev->samp_timer = dev->samp_latch = (int)(TIMER_USEC * (1000000.0 / 44100.0)); - - dev->t1l = dev->t2l = 0xff; - - cs423x_init(&dev->cs423x); - cs423x_setirq(&dev->cs423x, 5); /*Default irq and dma from GUS SDK*/ - cs423x_setdma(&dev->cs423x, 3); - - io_sethandler(0x0240, 16, - gus_read, NULL, NULL, gus_write, NULL, NULL, dev); - io_sethandler(0x0340, 9, - gus_read, NULL, NULL, gus_write, NULL, NULL, dev); - io_sethandler(0x0746, 1, - gus_read, NULL, NULL, gus_write, NULL, NULL, dev); - io_sethandler(0x0388, 2, - gus_read, NULL, NULL, gus_write, NULL, NULL, dev); - io_sethandler(0x034c, 4, - cs423x_read, NULL, NULL, cs423x_write, NULL, NULL, &dev->cs423x); - - timer_add(poll_wave, &dev->samp_timer, TIMER_ALWAYS_ENABLED, dev); - timer_add(poll_timer_1, &dev->timer_1, TIMER_ALWAYS_ENABLED, dev); - timer_add(poll_timer_2, &dev->timer_2, TIMER_ALWAYS_ENABLED, dev); - - sound_add_handler(get_buffer, dev); - - return(dev); -} + break; #endif + } + + timer_add(poll_wave, &dev->samp_timer, TIMER_ALWAYS_ENABLED, dev); + timer_add(poll_timer_1, &dev->timer_1, TIMER_ALWAYS_ENABLED, dev); + timer_add(poll_timer_2, &dev->timer_2, TIMER_ALWAYS_ENABLED, dev); + + sound_add_handler(get_buffer, dev); + + return(dev); +} + static void gus_close(void *priv) { - gus_t *dev = (gus_t *)priv; + gus_t *dev = (gus_t *)priv; + if (dev->ram != NULL) free(dev->ram); - free(dev); + free(dev); } static void speed_changed(void *priv) { - gus_t *dev = (gus_t *)priv; + gus_t *dev = (gus_t *)priv; - if (dev->voices < 14) - dev->samp_latch = (int)(TIMER_USEC * (1000000.0 / 44100.0)); - else - dev->samp_latch = (int)(TIMER_USEC * (1000000.0 / gusfreqs[dev->voices - 14])); + if (dev->voices < 14) + dev->samp_latch = (int)(TIMER_USEC * (1000000.0 / 44100.0)); + else + dev->samp_latch = (int)(TIMER_USEC * (1000000.0 / gusfreqs[dev->voices - 14])); #if defined(DEV_BRANCH) && defined(USE_GUSMAX) - if (dev->max_ctrl) - cs423x_speed_changed(&dev->cs423x); + if (dev->max_ctrl) + cs423x_speed_changed(&dev->cs423x); #endif } const device_t gus_device = { - "Gravis UltraSound", - DEVICE_ISA, - 0, - gus_init, gus_close, NULL, NULL, - speed_changed, NULL, NULL, - NULL + "Gravis UltraSound", + DEVICE_ISA, + 0, + gus_init, gus_close, NULL, + NULL, + speed_changed, NULL, NULL, + NULL }; #if defined(DEV_BRANCH) && defined(USE_GUSMAX) const device_t gusmax_device = { - "Gravis UltraSound MAX", - DEVICE_ISA, - 0, - gus_max_init, gus_close, NULL, NULL, - speed_changed, NULL, NULL, - NULL + "Gravis UltraSound MAX", + DEVICE_ISA, + 1, + gus_init, gus_close, NULL, + NULL, + speed_changed, NULL, NULL, + NULL }; #endif diff --git a/src/devices/sound/sound_dev.c b/src/devices/sound/sound_dev.c index b5357a7..7ae3e0e 100644 --- a/src/devices/sound/sound_dev.c +++ b/src/devices/sound/sound_dev.c @@ -8,13 +8,13 @@ * * Sound devices support module. * - * Version: @(#)sound_dev.c 1.0.11 2018/11/27 + * Version: @(#)sound_dev.c 1.0.12 2019/01/13 * * Authors: Fred N. van Kempen, * Miran Grca, * Sarah Walker, * - * Copyright 2017,2018 Fred N. van Kempen. + * Copyright 2017-2019 Fred N. van Kempen. * Copyright 2016-2018 Miran Grca. * Copyright 2008-2018 Sarah Walker. * diff --git a/src/nvr.c b/src/nvr.c index 2091773..32ffd52 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -8,11 +8,11 @@ * * Implement a generic NVRAM/CMOS/RTC device. * - * Version: @(#)nvr.c 1.0.13 2018/11/01 + * Version: @(#)nvr.c 1.0.14 2019/01/03 * * Author: Fred N. van Kempen, * - * Copyright 2017,2018 Fred N. van Kempen. + * Copyright 2017-2019 Fred N. van Kempen. * * Redistribution and use in source and binary forms, with * or without modification, are permitted provided that the @@ -60,7 +60,9 @@ int nvr_dosave; /* NVR is dirty, needs saved */ -static int8_t days_in_month[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 }; +static const int8_t days_in_month[12] = { + 31,28,31,30,31,30,31,31,30,31,30,31 +}; static struct tm intclk; static nvr_t *saved_nvr = NULL; diff --git a/src/pc.c b/src/pc.c index 7d17ace..e750eb4 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.61 2018/11/13 + * Version: @(#)pc.c 1.0.62 2018/11/22 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -873,9 +873,6 @@ pc_init(void) codegen_init(); #endif -#ifdef WALTJE_SERIAL - serial_init(); -#endif keyboard_init(); joystick_init(); video_init(); diff --git a/src/plat.h b/src/plat.h index 8157a42..318eca5 100644 --- a/src/plat.h +++ b/src/plat.h @@ -8,7 +8,7 @@ * * Define the various platform support functions. * - * Version: @(#)plat.h 1.0.21 2018/11/20 + * Version: @(#)plat.h 1.0.22 2018/11/24 * * Author: Fred N. van Kempen, * @@ -191,7 +191,6 @@ extern int plat_midi_write(uint8_t val); extern int plat_midi_get_num_devs(); extern void plat_midi_get_dev_name(int num, char *s); - /* Thread support. */ typedef void thread_t; typedef void event_t; diff --git a/src/ui/lang/VARCem.lang b/src/ui/lang/VARCem.lang index dccc234..77881de 100644 --- a/src/ui/lang/VARCem.lang +++ b/src/ui/lang/VARCem.lang @@ -8,7 +8,7 @@ # # Supported Languages database. # -# Version: @(#)VARCem.lang 1.0.5 2018/10/27 +# Version: @(#)VARCem.lang 1.0.6 2018/12/08 # # Author: Fred N. van Kempen, # @@ -51,6 +51,7 @@ DU,0413,LANG_DUTCH,SUBLANG_DUTCH,Dutch ES,040a,LANG_SPANISH,SUBLANG_SPANISH,Spanish FI,040b,LANG_FINNISH,SUBLANG_FINNISH_FINLAND,Finnish FR,040c,LANG_FRENCH,SUBLANG_FRENCH,French +HE,040d,LANG_HEBREW,SUBLANG_HEBREW,Hebrew IT,0410,LANG_ITALIAN,SUBLANG_ITALIAN,Italian JP,0411,LANG_JAPANESE,SUBLANG_JAPANESE_JAPAN,Japanese KR,0412,LANG_KOREAN,SUBLANG_KOREAN,Korean diff --git a/src/win/VARCem.rc b/src/win/VARCem.rc index 237be2a..0fa7fdd 100644 --- a/src/win/VARCem.rc +++ b/src/win/VARCem.rc @@ -8,11 +8,11 @@ * * Application resource script for Windows. * - * Version: @(#)VARCem.rc 1.0.35 2018/11/05 + * Version: @(#)VARCem.rc 1.0.36 2019/01/13 * * Author: Fred N. van Kempen, * - * Copyright 2017,2018 Fred N. van Kempen. + * Copyright 2017-2019 Fred N. van Kempen. * * Redistribution and use in source and binary forms, with * or without modification, are permitted provided that the @@ -226,7 +226,7 @@ VS_VERSION_INFO VERSIONINFO VALUE "FileDescription", "Virtual ARchaeological Computer EMulator" VALUE "FileVersion", EMU_VERSION VALUE "InternalName", EMU_NAME - VALUE "LegalCopyright", "Copyright Fred N. van Kempen and others, 2007-2018, Released under a mixed BSD 3-Clause and GPL License" + VALUE "LegalCopyright", "Copyright Fred N. van Kempen and others, 2007-2019, Released under a mixed BSD 3-Clause and GPL License" VALUE "OriginalFilename", "VARCem.exe" VALUE "ProductName", "VARCem Emulator" VALUE "ProductVersion", EMU_VERSION diff --git a/src/win/VARCem.rpp b/src/win/VARCem.rpp index 05312e3..f9565df 100644 --- a/src/win/VARCem.rpp +++ b/src/win/VARCem.rpp @@ -10,11 +10,11 @@ * which require some weird processing. This file allows us * to use a single master for all those languages. * - * Version: @(#)VARCem.rpp 1.0.3 2018/11/05 + * Version: @(#)VARCem.rpp 1.0.4 2019/01/13 * * Author: Fred N. van Kempen, * - * Copyright 2018 Fred N. van Kempen. + * Copyright 2018,2019 Fred N. van Kempen. * * Redistribution and use in source and binary forms, with * or without modification, are permitted provided that the @@ -98,7 +98,7 @@ VS_VERSION_INFO VERSIONINFO VALUE "FileDescription", "VARCem Language Module" VALUE "FileVersion", STR(STR_VERSION) VALUE "InternalName", EMU_NAME - VALUE "LegalCopyright", "Copyright 2018 The VARCem Team" + VALUE "LegalCopyright", "Copyright 2018,2019 The VARCem Team" VALUE "OriginalFilename", DLLNAME(LANG) VALUE "ProductName", "VARCem Emulator" VALUE "ProductVersion", EMU_VERSION diff --git a/src/win/mingw/Makefile.MinGW b/src/win/mingw/Makefile.MinGW index 41b31ee..eb76072 100644 --- a/src/win/mingw/Makefile.MinGW +++ b/src/win/mingw/Makefile.MinGW @@ -8,11 +8,11 @@ # # Makefile for Windows systems using the MinGW32 environment. # -# Version: @(#)Makefile.mingw 1.0.70 2018/11/30 +# Version: @(#)Makefile.mingw 1.0.71 2019/01/13 # # Author: Fred N. van Kempen, # -# Copyright 2017,2018 Fred N. van Kempen. +# Copyright 2017-2018 Fred N. van Kempen. # # Redistribution and use in source and binary forms, with # or without modification, are permitted provided that the @@ -140,6 +140,9 @@ endif ifndef PAS16 PAS16 := n endif +ifndef GUSMAX + GUSMAX := n +endif ifndef XL24 XL24 := n endif @@ -152,9 +155,6 @@ endif ifndef HOSTCD HOSTCD := n endif -ifndef GUSMAX - GUSMAX := n -endif # Name of the executable. @@ -186,10 +186,10 @@ ifeq ($(DEV_BUILD), y) PORTABLE3 := y I686 := y PAS16 := y + GUSMAX := y XL24 := y WONDER := y HOSTCD := y - GUSMAX := y endif @@ -558,6 +558,11 @@ ifeq ($(DEV_BRANCH), y) DEVBROBJ += snd_pas16.o endif + ifeq ($(GUSMAX), y) + OPTS += -DUSE_GUSMAX + DEVBROBJ += snd_cs423x.o + endif + ifeq ($(WONDER), y) OPTS += -DUSE_WONDER endif @@ -575,10 +580,6 @@ ifeq ($(DEV_BRANCH), y) OPTS += -DUSE_HOST_CDROM endif - ifeq ($(GUSMAX), y) - OPTS += -DUSE_GUSMAX - DEVBROBJ += snd_cs423x.o - endif endif @@ -740,7 +741,7 @@ VIDOBJ := video.o \ PLATOBJ := win.o \ win_lang.o win_dynld.o win_opendir.o win_thread.o \ win_cdrom.o win_keyboard.o win_mouse.o win_joystick.o \ - win_midi.o + win_serial.o win_midi.o ifeq ($(CRASHDUMP), y) PLATOBJ += win_crashdump.o endif diff --git a/src/win/msvc/Makefile.VC b/src/win/msvc/Makefile.VC index 8f105d9..2b28dea 100644 --- a/src/win/msvc/Makefile.VC +++ b/src/win/msvc/Makefile.VC @@ -1,862 +1,862 @@ -# -# VARCem Virtual ARchaeological Computer EMulator. -# An emulator of (mostly) x86-based PC systems and devices, -# using the ISA,EISA,VLB,MCA and PCI system buses, roughly -# spanning the era between 1981 and 1995. -# -# This file is part of the VARCem Project. -# -# Makefile for Windows using Visual Studio 2015. -# -# Version: @(#)Makefile.VC 1.0.56 2018/11/30 -# -# Author: Fred N. van Kempen, -# -# Copyright 2017,2018 Fred N. van Kempen. -# -# Redistribution and use in source and binary forms, with -# or without modification, are permitted provided that the -# following conditions are met: -# -# 1. Redistributions of source code must retain the entire -# above notice, this list of conditions and the following -# disclaimer. -# -# 2. Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the -# following disclaimer in the documentation and/or other -# materials provided with the distribution. -# -# 3. Neither the name of the copyright holder nor the names -# of its contributors may be used to endorse or promote -# products derived from this software without specific -# prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A -# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -# Various compile-time options. -ifndef STUFF - STUFF := -endif - -# Add feature selections here. -ifndef EXTRAS - EXTRAS := -endif - - -# Defaults for several build options (possibly defined in a chained file.) -ifndef AUTODEP - AUTODEP := n -endif -ifndef CRASHDUMP - CRASHDUMP := n -endif -ifndef CROSS - CROSS := n -endif -ifndef DEBUG - DEBUG := n -endif -ifndef LOGGING - LOGGING := n -endif -ifndef PROFILER - PROFILER := n -endif -ifndef OPTIM - OPTIM := n -endif -ifndef RELEASE - RELEASE := n -endif -ifndef X64 - X64 := n -endif -ifndef DYNAREC - DYNAREC := y -endif -ifndef WX - WX := n -endif -ifndef USB - USB := n -endif -ifndef VNS - VNS := n -endif -ifndef SDL - SDL := n -endif -ifndef D2D - D2D := n -endif -ifndef VNC - VNC := n -endif -ifndef RDP - RDP := n -endif -ifndef PNG - PNG := n -endif -ifndef DEV_BUILD - DEV_BUILD := n -endif -ifndef DEV_BRANCH - DEV_BRANCH := n -endif -ifndef AMD_K - AMD_K := n -endif -ifndef LASERXT - LASERXT := n -endif -ifndef PORTABLE3 - PORTABLE3 := n -endif -ifndef I686 - I686 := n -endif -ifndef OPENAL - OPENAL := y -endif -ifndef FLUIDSYNTH - FLUIDSYNTH := y -endif -ifndef MUNT - MUNT := y -endif -ifndef PAS16 - PAS16 := n -endif -ifndef XL24 - XL24 := n -endif -ifndef WONDER - WONDER := n -endif -ifndef HOSTCD - HOSTCD := n -endif -ifndef PRINTER - PRINTER := n -endif -ifndef GUSMAX - GUSMAX := n -endif - -# Name of the executable. -NETIF := pcap_if -ifndef PROG - ifneq ($(WX), n) - PROG := WxVARCem - else - PROG := VARCem - endif -endif -ifeq ($(DEBUG), y) - PROG := $(PROG)-d - NETIF := $(NETIF)-d - LOGGING := y -else - ifeq ($(LOGGING), y) - PROG := $(PROG)-l - endif -endif - - -# Which modules to include a development build. -ifeq ($(DEV_BUILD), y) - CRASHDUMP := y - DEV_BRANCH := y - AMD_K := y - LASERXT := y - PORTABLE3 := y - I686 := y - PAS16 := y - XL24 := y - WONDER := y - HOSTCD := y - PRINTER := y - GUSMAX := y -endif - - -# WxWidgets basic info. Extract using the config program. -ifneq ($(WX), n) - EXPATH += wx - WX_CONFIG := wx-config.exe - ifeq ($(WX), y) - WX_PATH := C:/MinGW32/WxWidgets - WX_FLAGS := -I$(WX_PATH)/lib/wx/include/msw-unicode-3.0 \ - -I$(WX_PATH)/include/wx-3.0 \ - -D__WXMSW__ -DWX_PRECOMP -D_FILE_OFFSET_BITS=64 -pthread -# -lwx_mswu_gl-3.0 -lwxtiff-3.0 -llzma - WX_LIBS := -mthreads -L$(WX_PATH)/lib \ - -lwx_mswu-3.0.dll \ - -lrpcrt4 -loleaut32 -lole32 -luuid \ - -lwinspool -lwinmm -lshell32 -lcomctl32 \ - -lcomdlg32 -ladvapi32 -lwsock32 -lgdi32 - endif - ifeq ($(WX), static) - WX_PATH := C:/MinGW32/WxWidgets - WX_FLAGS := -I$(WX_PATH)/lib/wx/include/msw-unicode-3.0 \ - -I$(WX_PATH)/include/wx-3.0 \ - -D__WXMSW__ -DWX_PRECOMP -D_FILE_OFFSET_BITS=64 -pthread -# -lwx_mswu_gl-3.0 -lwxtiff-3.0 -llzma - WX_LIBS := -mthreads -L$(WX_PATH)/lib \ - -lwx_mswu-3.0 -lwxscintilla-3.0 \ - -lwxjpeg-3.0 -lwxpng-3.0 -lwxzlib-3.0 \ - -lwxregexu-3.0 -lwxexpat-3.0 \ - -lrpcrt4 -loleaut32 -lole32 -luuid \ - -lwinspool -lwinmm -lshell32 -lcomctl32 \ - -lcomdlg32 -ladvapi32 -lwsock32 -lgdi32 - endif -endif - - -######################################################################### -# Nothing should need changing from here on.. # -######################################################################### - -VPATH := $(EXPATH) . cpu \ - devices \ - devices/cdrom devices/disk devices/floppy \ - devices/floppy/lzf devices/input devices/input/game \ - devices/network devices/network/slirp devices/ports \ - devices/printer devices/sio devices/system devices/scsi \ - devices/misc \ - devices/sound \ - devices/sound/munt devices/sound/munt/c_interface \ - devices/sound/munt/sha1 devices/sound/munt/srchelper \ - devices/sound/resid-fp \ - devices/video \ - machines ui win - - -# -# Select the required build environment. -# -VCOPTS := -D_CRT_SECURE_NO_WARNINGS -D__MSC__ -ifeq ($(X64), y) - ARCH := x64 - CPP := cl -nologo - CC := cl -nologo -else - ARCH := x86 - CPP := cl -nologo - CC := cl -nologo #-TP -endif -PREPROC := cl -nologo -EP -MCPP := mcpp.exe -LINK := link -nologo -WINDRES := rc -nologo -r -d_MSC_VER - -SYSINC := -Iwin/msvc/Include -Iwin/mingw/include -SYSLIB := - -DEPS = -MMD -MF $*.d -DEPFILE := win\msvc\.depends - -# Set up the correct toolchain flags. -OPTS := $(EXTRAS) $(STUFF) $(VCOPTS) \ - -D_USE_MATH_DEFINES \ - -D_CRT_NONSTDC_NO_DEPRECATE \ - -D_WINSOCK_DEPRECATED_NO_WARNINGS \ - -D_CRT_SECURE_NO_WARNINGS \ - -D_CRT_STDIO_ISO_WIDE_SPECIFIERS \ - $(WPCAPINC) $(SYSINC) -AFLAGS := #/arch:SSE2 -RFLAGS := /n -COPTS := -W3 -CXXOPTS := -EHsc -DOPTS := -ifeq ($(X64), y) -LOPTS := -MACHINE:$(ARCH) -LIBPATH:win\msvc\Lib\$(ARCH) -LOPTS_C := -SUBSYSTEM:CONSOLE -LOPTS_W := -SUBSYSTEM:WINDOWS -else -LOPTS := -MACHINE:$(ARCH) -LIBPATH:win\msvc\Lib\$(ARCH) -LOPTS_C := -SUBSYSTEM:CONSOLE,5.01 -LOPTS_W := -SUBSYSTEM:WINDOWS,5.01 -endif -ifdef BUILD - OPTS += -DBUILD=$(BUILD) -endif -ifdef COMMIT - OPTS += -DCOMMIT=0x$(COMMIT) -endif -ifdef UPSTREAM - OPTS += -DUPSTREAM=0x$(UPSTREAM) -endif -ifdef EXFLAGS - OPTS += $(EXFLAGS) -endif -ifdef EXINC - OPTS += -I$(EXINC) -endif -OPTS += $(SYSINC) -ifeq ($(OPTIM), y) - AFLAGS := /arch:AVX2 -endif -ifeq ($(DEBUG), y) - OPTS += -D_DEBUG - DOPTS += -MTd -Gs -Zi - RFLAGS += -D_DEBUG - LOPTS += -debug - ifndef COPTIM - COPTIM := -Od - endif -else - LOPTS += -LTCG - DOPTS := -MT -GL - ifndef COPTIM - COPTIM := -O2 - endif -endif -ifeq ($(LOGGING), y) - OPTS += -D_LOGGING - RFLAGS += -D_LOGGING -endif -ifeq ($(CRASHDUMP), y) - OPTS += -DUSE_CRASHDUMP -endif -ifeq ($(RELEASE), y) - OPTS += -DRELEASE_BUILD - RFLAGS += -DRELEASE_BUILD -endif -ifeq ($(PROFILER), y) - LOPTS += /MAP -endif -ifeq ($(VRAMDUMP), y) - OPTS += -DENABLE_VRAM_DUMP - RFLAGS += -DENABLE_VRAM_DUMP -endif -ifeq ($(X64), y) - PLATCG := codegen_x86-64.obj - CGOPS := codegen_ops_x86-64.h - VCG := vid_voodoo_codegen_x86-64.h -else - PLATCG := codegen_x86.obj - CGOPS := codegen_ops_x86.h - VCG := vid_voodoo_codegen_x86.h -endif -LIBS := ddraw.lib dinput8.lib dxguid.lib d3d9.lib d3dx9.lib \ - version.lib comctl32.lib winmm.lib comdlg32.lib \ - advapi32.lib gdi32.lib shell32.lib user32.lib \ - ws2_32.lib wsock32.lib iphlpapi.lib psapi.lib -ifeq ($(DEBUG), y) -LIBS += libcmtd.lib libvcruntimed.lib libucrtd.lib -endif - - -# Optional modules. -MISCOBJ := -ifeq ($(DYNAREC), y) - OPTS += -DUSE_DYNAREC - RFLAGS += -DUSE_DYNAREC - DYNARECOBJ := 386_dynarec_ops.obj \ - codegen.obj \ - codegen_ops.obj \ - codegen_timing_common.obj codegen_timing_486.obj \ - codegen_timing_686.obj codegen_timing_pentium.obj \ - codegen_timing_winchip.obj $(PLATCG) -endif - -ifeq ($(VNS), y) - OPTS += -DUSE_VNS - MISCOBJ += net_vns.obj -endif - -ifeq ($(OPENAL), y) - OPTS += -DUSE_OPENAL -endif - -ifeq ($(FLUIDSYNTH), y) - OPTS += -DUSE_FLUIDSYNTH - MISCOBJ += midi_fluidsynth.obj -endif - -ifeq ($(MUNT), y) - OPTS += -DUSE_MUNT - MISCOBJ += midi_mt32.obj \ - Analog.obj BReverbModel.obj File.obj FileStream.obj \ - LA32Ramp.obj LA32FloatWaveGenerator.obj \ - LA32WaveGenerator.obj MidiStreamParser.obj Part.obj \ - Partial.obj PartialManager.obj Poly.obj ROMInfo.obj \ - SampleRateConverter_dummy.obj Synth.obj Tables.obj \ - TVA.obj TVF.obj TVP.obj sha1.obj c_interface.obj -endif - -# N=no, Y=yes,linked, D=yes,dynamic, S=yes,static -ifneq ($(SDL), n) - OPTS += -DUSE_SDL - RFLAGS += -DUSE_SDL - ifneq ($(SDL_PATH), ) - OPTS += -I$(SDL_PATH)/include/msvc -I$(SDL_PATH)/include - ifeq ($(X64), y) - LOPTS += -LIBPATH:$(SDL_PATH)\lib\msvc\x64 - else - LOPTS += -LIBPATH:$(SDL_PATH)\lib\msvc\x86 - endif - endif - ifeq ($(SDL), y) - LIBS += sdl2.lib - endif - SDLOBJ := win_sdl.obj -endif - -# N=no, Y=yes,linked, D=yes,dynamic, S=yes,static -ifneq ($(D2D), n) - ifeq ($(D2D), d) - OPTS += -DUSE_D2D=2 - else - OPTS += -DUSE_D2D=1 - endif - RFLAGS += -DUSE_D2D - ifneq ($(D2D_PATH), ) - OPTS += -I$(D2D_PATH)/include/msvc -I$(D2D_PATH)/include - ifeq ($(X64), y) - LOPTS += -LIBPATH:$(D2D_PATH)\lib\msvc\x64 - else - LOPTS += -LIBPATH:$(D2D_PATH)\lib\msvc\x86 - endif - endif - ifeq ($(D2D), y) - LIBS += d2d1.lib - endif - D2DOBJ := win_d2d.obj -endif - -# N=no, Y=yes,linked, D=yes,dynamic, S=yes,static -ifneq ($(VNC), n) - OPTS += -DUSE_VNC - RFLAGS += -DUSE_VNC - ifneq ($(VNC_PATH), ) - OPTS += -I$(VNC_PATH)/include/msvc -I$(VNC_PATH)/include - ifeq ($(X64), y) - LOPTS += -LIBPATH:$(VNC_PATH)\lib\x64 - else - LOPTS += -LIBPATH:$(VNC_PATH)\lib\x86 - endif - endif - ifeq ($(VNC), y) - LIBS += libvncserver.lib - endif - MISCOBJ += vnc.obj vnc_keymap.obj -endif - -# N=no, Y=yes,linked, D=yes,dynamic, S=yes,static -ifneq ($(RDP), n) - OPTS += -DUSE_RDP - RFLAGS += -DUSE_RDP - ifneq ($(RDP_PATH), ) - OPTS += -I$(RDP_PATH)/include/msvc -I$(RDP_PATH)/include - ifeq ($(X64), y) - LOPTS += -LIBPATH:$(RDP_PATH)\lib\x64 - else - LOPTS += -LIBPATH:$(RDP_PATH)\lib\x86 - endif - endif - ifeq ($(RDP), y) - LIBS += rdpsrvr.lib - endif - MISCOBJ += rdp.obj -endif - -# N=no, Y=yes,linked, D=yes,dynamic, S=yes,static -ifneq ($(PNG), n) - ifeq ($(PNG), d) - OPTS += -DUSE_LIBPNG=2 - else - OPTS += -DUSE_LIBPNG=1 - endif - RFLAGS += -DUSE_LIBPNG - ifneq ($(PNG_PATH), ) - OPTS += -I$(PNG_PATH)/include/msvc -I$(PNG_PATH)/include - ifeq ($(X64), y) - LOPTS += -LIBPATH:$(PNG_PATH)\lib\x64 - else - LOPTS += -LIBPATH:$(PNG_PATH)\lib\x86 - endif - endif - ifeq ($(PNG), y) - LIBS += libpng16_dll.lib #zlib.lib - endif - MISCOBJ += png.obj -endif - -# N=no, Y=yes,linked, D=yes,dynamic, S=yes,static -ifneq ($(WX), n) - OPTS += -DUSE_WX $(WX_FLAGS) - LIBS += $(WX_LIBS) -lm - UIOBJ := wx_main.obj wx_ui.obj wx_stbar.obj wx_render.obj -else - UIOBJ := win_ui.obj \ - win_ddraw.obj win_d3d.obj $(SDLOBJ) $(D2DOBJ) \ - win_dialog.obj win_about.obj win_settings.obj \ - win_devconf.obj win_snd_gain.obj win_new_image.obj -endif - - -# Options for the DEV branch. -ifeq ($(DEV_BRANCH), y) - OPTS += -DDEV_BRANCH - DEVBROBJ := - - ifeq ($(AMD_K), y) - OPTS += -DUSE_AMD_K - endif - - ifeq ($(LASERXT), y) - OPTS += -DUSE_LASERXT - DEVBROBJ += m_xt_laserxt.obj - endif - - ifeq ($(PORTABLE3), y) - OPTS += -DUSE_PORTABLE3 - endif - - ifeq ($(I686), y) - OPTS += -DUSE_I686 - endif - - ifeq ($(PAS16), y) - OPTS += -DUSE_PAS16 - DEVBROBJ += snd_pas16.obj - endif - - ifeq ($(XL24), y) - OPTS += -DUSE_XL24 - endif - - ifeq ($(WONDER), y) - OPTS += -DUSE_WONDER - endif - - ifeq ($(HOSTCD), y) - OPTS += -DUSE_HOST_CDROM - endif - - ifeq ($(PRINTER), y) - OPTS += -DUSE_PRINTER - DEVBROBJ += prt_parallel.obj - endif - - ifeq ($(GUSMAX), y) - OPTS += -DUSE_GUSMAX - DEVBROBJ += snd_cs423x.obj - endif -endif - - -# Final versions of the toolchain flags. -LDFLAGS := $(LOPTS) -CFLAGS := $(WX_FLAGS) $(OPTS) $(COPTS) $(COPTIM) $(DOPTS) $(AFLAGS) -CXXFLAGS := $(WX_FLAGS) $(OPTS) $(CXXOPTS) $(COPTS) $(COPTIM) $(DOPTS) $(AFLAGS) - - -######################################################################### -# Create the (final) list of objects to build. # -######################################################################### - -RESDLL := VARCem-$(LANG) - -MAINOBJ := pc.obj config.obj misc.obj random.obj timer.obj io.obj \ - mem.obj rom.obj rom_load.obj device.obj nvr.obj - -UIOBJ += ui_main.obj ui_lang.obj ui_stbar.obj ui_vidapi.obj \ - ui_cdrom.obj ui_new_image.obj ui_misc.obj - -SYSOBJ := dma.obj nmi.obj pic.obj pit.obj ppi.obj pci.obj mca.obj \ - mcr.obj memregs.obj nvr_at.obj nvr_ps2.obj - -CPUOBJ := cpu.obj cpu_table.obj \ - 808x.obj 386.obj x86seg.obj x87.obj \ - 386_dynarec.obj $(DYNARECOBJ) - -MCHOBJ := machine.obj machine_table.obj \ - m_xt.obj m_xt_compaq.obj \ - m_xt_t1000.obj m_xt_t1000_vid.obj \ - m_xt_xi8088.obj \ - m_pcjr.obj \ - m_amstrad.obj m_europc.obj \ - m_olivetti_m24.obj m_tandy.obj \ - m_at.obj \ - m_at_ali1429.obj m_at_commodore.obj \ - m_at_neat.obj m_at_headland.obj \ - m_at_t3100e.obj m_at_t3100e_vid.obj \ - m_ps1.obj m_ps1_hdc.obj \ - m_ps2_isa.obj m_ps2_mca.obj \ - m_at_opti495.obj m_at_scat.obj \ - m_at_compaq.obj m_at_wd76c10.obj \ - m_at_sis471.obj m_at_sis496.obj \ - m_at_4x0.obj - -INTELOBJ := intel.obj \ - intel_flash.obj \ - intel_sio.obj \ - intel_piix.obj - -DEVOBJ := bugger.obj \ - isamem.obj isartc.obj \ - game.obj game_dev.obj \ - parallel.obj parallel_dev.obj \ - prt_text.obj prt_cpmap.obj prt_escp.obj \ - serial.obj \ - sio_fdc37c66x.obj sio_fdc37c669.obj sio_fdc37c93x.obj \ - sio_pc87306.obj sio_w83877f.obj sio_um8669f.obj \ - keyboard.obj \ - keyboard_xt.obj keyboard_at.obj \ - mouse.obj \ - mouse_serial.obj mouse_ps2.obj mouse_bus.obj \ - joystick.obj \ - js_standard.obj js_ch_fs_pro.obj \ - js_sw_pad.obj js_tm_fcs.obj - -FDDOBJ := fdc.obj \ - fdd.obj \ - fdd_common.obj fdd_86f.obj \ - fdd_fdi.obj fdi2raw.obj lzf_c.obj lzf_d.obj \ - fdd_imd.obj fdd_img.obj fdd_json.obj fdd_td0.obj - -HDDOBJ := hdd.obj \ - hdd_image.obj hdd_table.obj \ - hdc.obj \ - hdc_st506_xt.obj hdc_st506_at.obj \ - hdc_esdi_at.obj hdc_esdi_mca.obj \ - hdc_ide_ata.obj hdc_ide_xta.obj hdc_xtide.obj - -CDROMOBJ := cdrom.obj \ - cdrom_speed.obj \ - cdrom_dosbox.obj cdrom_image.obj - -ZIPOBJ := zip.obj - -ifeq ($(USB), y) -USBOBJ := usb.obj -endif - -SCSIOBJ := scsi.obj \ - scsi_device.obj scsi_disk.obj scsi_cdrom.obj \ - scsi_x54x.obj scsi_aha154x.obj scsi_buslogic.obj \ - scsi_ncr5380.obj scsi_ncr53c810.obj - -NETOBJ := network.obj \ - network_dev.obj \ - net_pcap.obj \ - net_slirp.obj \ - net_dp8390.obj \ - net_ne2000.obj net_wd80x3.obj net_3c503.obj - -SNDOBJ := sound.obj \ - sound_dev.obj \ - openal.obj \ - snd_opl.obj snd_dbopl.obj \ - dbopl.obj nukedopl.obj \ - snd_resid.obj \ - convolve.obj convolve-sse.obj envelope.obj extfilt.obj \ - filter.obj pot.obj sid.obj voice.obj wave6581__ST.obj \ - wave6581_P_T.obj wave6581_PS_.obj wave6581_PST.obj \ - wave8580__ST.obj wave8580_P_T.obj wave8580_PS_.obj \ - wave8580_PST.obj wave.obj \ - midi.obj midi_system.obj \ - snd_speaker.obj \ - snd_lpt_dac.obj snd_lpt_dss.obj \ - snd_adlib.obj snd_adlibgold.obj snd_ad1848.obj snd_audiopci.obj \ - snd_cms.obj \ - snd_gus.obj \ - snd_sb.obj snd_sb_dsp.obj \ - snd_emu8k.obj snd_mpu401.obj \ - snd_sn76489.obj snd_ssi2001.obj \ - snd_wss.obj \ - snd_ym7128.obj - -VIDOBJ := video.obj \ - video_dev.obj \ - vid_cga.obj vid_cga_comp.obj \ - vid_cga_compaq.obj \ - vid_mda.obj \ - vid_hercules.obj vid_herculesplus.obj vid_incolor.obj \ - vid_colorplus.obj \ - vid_genius.obj \ - vid_sigma.obj \ - vid_wy700.obj \ - vid_ega.obj vid_ega_render.obj \ - vid_svga.obj vid_svga_render.obj \ - vid_vga.obj \ - vid_ati_eeprom.obj \ - vid_ati18800.obj vid_ati28800.obj \ - vid_ati_mach64.obj vid_ati68860_ramdac.obj \ - vid_bt48x_ramdac.obj vid_icd2061.obj vid_ics2595.obj \ - vid_cl54xx.obj \ - vid_et4000.obj vid_sc1502x_ramdac.obj \ - vid_et4000w32.obj vid_stg_ramdac.obj \ - vid_oak_oti.obj \ - vid_paradise.obj \ - vid_ti_cf62011.obj \ - vid_tvga.obj \ - vid_tgui9440.obj vid_tkd8001_ramdac.obj \ - vid_s3.obj vid_s3_virge.obj \ - vid_sdac_ramdac.obj \ - vid_voodoo.obj - -PLATOBJ := win.obj \ - win_lang.obj win_opendir.obj win_dynld.obj win_thread.obj \ - win_cdrom.obj win_keyboard.obj win_mouse.obj \ - win_joystick.obj win_midi.obj -ifeq ($(CRASHDUMP), y) -PLATOBJ += win_crashdump.obj -endif - - -OBJ := $(MAINOBJ) $(CPUOBJ) $(MCHOBJ) $(SYSOBJ) $(DEVOBJ) \ - $(INTELOBJ) $(FDDOBJ) $(CDROMOBJ) $(ZIPOBJ) $(HDDOBJ) \ - $(USBOBJ) $(NETOBJ) $(SCSIOBJ) $(SNDOBJ) $(VIDOBJ) \ - $(UIOBJ) $(PLATOBJ) $(MISCOBJ) $(DEVBROBJ) -ifdef EXOBJ -OBJ += $(EXOBJ) -endif - - -# Build module rules. -ifeq ($(AUTODEP), y) -%.obj: %.c - @$(CC) $(CFLAGS) -Fo$@ -c $< - @$(MCPP) $(OPTS) $(DEPS) $< - -%.obj: %.cpp - @$(CPP) $(CXXFLAGS) -Fo$@ -c $< - @$(MCPP) $(OPTS) $(DEPS) $< -else -%.obj: %.c - @$(CC) $(CFLAGS) -Fo$@ -c $< - -%.obj: %.cpp - @$(CPP) $(CXXFLAGS) -Fo$@ -c $< - -%.d: %.c $(wildcard $*.d) - $(MCPP) $(OPTS) $(DEPS) $< >NUL - -%.d: %.cpp $(wildcard $*.d) - $(MCPP) $(OPTS) $(DEPS) $< >NUL -endif - - -all: $(PREBUILD) $(PROG).exe $(NETIF).exe $(POSTBUILD) - -# -# This rule creates a script (command file) that figures out which -# language we want to make (its argument is the 2-letter language -# name, or none) by looking it up in the database of supported ones, -# and then it calls the (this) Makefile back with the proper args -# for that target. -# -# We do it this way so it can also be used by the VC project files. -# -win/Mklang.cmd: win/msvc/Makefile.VC - @echo @SET PATH=$(PATH) >>win\Mklang.cmd - @echo @SETLOCAL >>win\Mklang.cmd - @echo @SET LANG=none >>win\Mklang.cmd - @echo @FOR /F "eol=# tokens=1,2,3,4* delims=, " %%%%i in (ui\lang\VARCem.lang) do @if "%%1"=="%%%%i" set LANG=%%%%i LANGID=%%%%j PRILANG=%%%%k SUBLANG=%%%%l >>win\Mklang.cmd - @echo @IF NOT "%%LANG%%"=="none" @$(MAKE) -fwin/msvc/Makefile.VC "RFLAGS=$(RFLAGS) $(EXTRAS)" LANG=%%LANG%% VARCem-%%1.dll >>win\Mklang.cmd - - -langs: win/Mklang.cmd -ifdef LANG - @echo Generating localization $(LANG) .. -else - @echo Generating localizations.. - @FOR /F "eol=# tokens=1 delims=, " %%i in (ui\lang\VARCem.lang) do @win\Mklang %%i -endif - @-del win\Mklang.cmd - -$(RESDLL).rc: VARCem.rpp - @win\msvc\preproc $< $@ "-DPREAMBLE=" "-DLANG=$(LANG)" "-DLANGID=$(LANGID)" "-DPRILANG=$(PRILANG)" "-DSUBLANG=$(SUBLANG)" - -$(RESDLL).res: $(RESDLL).rc VARCem-common.rc - @echo Processing $(RESDLL).rc .. - @$(WINDRES) $(RFLAGS) -fo$@ $< - -$(RESDLL).dll: $(RESDLL).res - @echo Linking $(RESDLL).dll .. - @$(LINK) /DLL /NOENTRY $(LDFLAGS) -OUT:$@ $(RESDLL).res - @-del $(RESDLL).rc - -VARCem.res: VARCem.rc win/VARCem.mpp - @win\msvc\preproc win/VARCem.mpp VARCem.manifest - @echo Processing $< - @$(WINDRES) $(RFLAGS) $(EXTRAS) -fo$@ $< - -$(PROG).exe: $(OBJ) VARCem.res - @echo Linking $(PROG).exe .. - @$(LINK) $(LDFLAGS) $(LOPTS_W) -OUT:$(PROG).exe \ - $(OBJ) VARCem.res $(LIBS) - -pcap_if.res: pcap_if.rc - @echo Processing $< - @$(WINDRES) $(RFLAGS) -fo$@ $< - -$(NETIF).exe: pcap_if.obj win_dynld.obj pcap_if.res - @echo Linking $(NETIF).exe .. - @$(LINK) $(LDFLAGS) $(LOPTS_C) -OUT:$@ \ - pcap_if.obj win_dynld.obj pcap_if.res - -clean: - @echo Cleaning objects.. - @-del *.obj 2>NUL - @-del *.res 2>NUL - -clobber: Mklang.cmd clean - @echo Cleaning executables.. - @-del *.d 2>NUL - @-del *.exe 2>NUL -ifeq ($(DEBUG), y) - @-del *.ilk 2>NUL - @-del *.pdb 2>NUL -endif -ifeq ($(PROFILER), y) - @-del *.map 2>NUL -endif - @-del *.manifest 2>NUL - @-del *.dll 2>NUL - @-del win\Mklang.cmd -# @del $(DEPFILE) 2>NUL - -ifneq ($(AUTODEP), y) -depclean: - @del $(DEPFILE) 2>NUL - @echo Creating dependencies.. - @echo # Run "make depends" to re-create this file. >$(DEPFILE) - -depends: DEPOBJ=$(OBJ:%.obj=%.d) -depends: depclean $(OBJ:%.obj=%.d) - @-cat $(DEPOBJ) >>$(DEPFILE) - @del $(DEPOBJ) - -$(DEPFILE): -endif - - -# Module dependencies. -ifeq ($(AUTODEP), y) -#-include $(OBJ:%.obj=%.d) (better, but sloooowwwww) --include *.d -else -include $(wildcard $(DEPFILE)) -endif - - -# End of Makefile.VC. +# +# VARCem Virtual ARchaeological Computer EMulator. +# An emulator of (mostly) x86-based PC systems and devices, +# using the ISA,EISA,VLB,MCA and PCI system buses, roughly +# spanning the era between 1981 and 1995. +# +# This file is part of the VARCem Project. +# +# Makefile for Windows using Visual Studio 2015. +# +# Version: @(#)Makefile.VC 1.0.57 2019/01/13 +# +# Author: Fred N. van Kempen, +# +# Copyright 2017-2019 Fred N. van Kempen. +# +# Redistribution and use in source and binary forms, with +# or without modification, are permitted provided that the +# following conditions are met: +# +# 1. Redistributions of source code must retain the entire +# above notice, this list of conditions and the following +# disclaimer. +# +# 2. Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the +# following disclaimer in the documentation and/or other +# materials provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names +# of its contributors may be used to endorse or promote +# products derived from this software without specific +# prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +# Various compile-time options. +ifndef STUFF + STUFF := +endif + +# Add feature selections here. +ifndef EXTRAS + EXTRAS := +endif + + +# Defaults for several build options (possibly defined in a chained file.) +ifndef AUTODEP + AUTODEP := n +endif +ifndef CRASHDUMP + CRASHDUMP := n +endif +ifndef CROSS + CROSS := n +endif +ifndef DEBUG + DEBUG := n +endif +ifndef LOGGING + LOGGING := n +endif +ifndef PROFILER + PROFILER := n +endif +ifndef OPTIM + OPTIM := n +endif +ifndef RELEASE + RELEASE := n +endif +ifndef X64 + X64 := n +endif +ifndef DYNAREC + DYNAREC := y +endif +ifndef WX + WX := n +endif +ifndef USB + USB := n +endif +ifndef VNS + VNS := n +endif +ifndef SDL + SDL := n +endif +ifndef D2D + D2D := n +endif +ifndef VNC + VNC := n +endif +ifndef RDP + RDP := n +endif +ifndef PNG + PNG := n +endif +ifndef DEV_BUILD + DEV_BUILD := n +endif +ifndef DEV_BRANCH + DEV_BRANCH := n +endif +ifndef AMD_K + AMD_K := n +endif +ifndef LASERXT + LASERXT := n +endif +ifndef PORTABLE3 + PORTABLE3 := n +endif +ifndef I686 + I686 := n +endif +ifndef OPENAL + OPENAL := y +endif +ifndef FLUIDSYNTH + FLUIDSYNTH := y +endif +ifndef MUNT + MUNT := y +endif +ifndef PAS16 + PAS16 := n +endif +ifndef GUSMAX + GUSMAX := n +endif +ifndef XL24 + XL24 := n +endif +ifndef WONDER + WONDER := n +endif +ifndef HOSTCD + HOSTCD := n +endif +ifndef PRINTER + PRINTER := n +endif + +# Name of the executable. +NETIF := pcap_if +ifndef PROG + ifneq ($(WX), n) + PROG := WxVARCem + else + PROG := VARCem + endif +endif +ifeq ($(DEBUG), y) + PROG := $(PROG)-d + NETIF := $(NETIF)-d + LOGGING := y +else + ifeq ($(LOGGING), y) + PROG := $(PROG)-l + endif +endif + + +# Which modules to include a development build. +ifeq ($(DEV_BUILD), y) + CRASHDUMP := y + DEV_BRANCH := y + AMD_K := y + LASERXT := y + PORTABLE3 := y + I686 := y + PAS16 := y + GUSMAX := y + XL24 := y + WONDER := y + HOSTCD := y + PRINTER := y +endif + + +# WxWidgets basic info. Extract using the config program. +ifneq ($(WX), n) + EXPATH += wx + WX_CONFIG := wx-config.exe + ifeq ($(WX), y) + WX_PATH := C:/MinGW32/WxWidgets + WX_FLAGS := -I$(WX_PATH)/lib/wx/include/msw-unicode-3.0 \ + -I$(WX_PATH)/include/wx-3.0 \ + -D__WXMSW__ -DWX_PRECOMP -D_FILE_OFFSET_BITS=64 -pthread +# -lwx_mswu_gl-3.0 -lwxtiff-3.0 -llzma + WX_LIBS := -mthreads -L$(WX_PATH)/lib \ + -lwx_mswu-3.0.dll \ + -lrpcrt4 -loleaut32 -lole32 -luuid \ + -lwinspool -lwinmm -lshell32 -lcomctl32 \ + -lcomdlg32 -ladvapi32 -lwsock32 -lgdi32 + endif + ifeq ($(WX), static) + WX_PATH := C:/MinGW32/WxWidgets + WX_FLAGS := -I$(WX_PATH)/lib/wx/include/msw-unicode-3.0 \ + -I$(WX_PATH)/include/wx-3.0 \ + -D__WXMSW__ -DWX_PRECOMP -D_FILE_OFFSET_BITS=64 -pthread +# -lwx_mswu_gl-3.0 -lwxtiff-3.0 -llzma + WX_LIBS := -mthreads -L$(WX_PATH)/lib \ + -lwx_mswu-3.0 -lwxscintilla-3.0 \ + -lwxjpeg-3.0 -lwxpng-3.0 -lwxzlib-3.0 \ + -lwxregexu-3.0 -lwxexpat-3.0 \ + -lrpcrt4 -loleaut32 -lole32 -luuid \ + -lwinspool -lwinmm -lshell32 -lcomctl32 \ + -lcomdlg32 -ladvapi32 -lwsock32 -lgdi32 + endif +endif + + +######################################################################### +# Nothing should need changing from here on.. # +######################################################################### + +VPATH := $(EXPATH) . cpu \ + devices \ + devices/cdrom devices/disk devices/floppy \ + devices/floppy/lzf devices/input devices/input/game \ + devices/network devices/network/slirp devices/ports \ + devices/printer devices/sio devices/system devices/scsi \ + devices/misc \ + devices/sound \ + devices/sound/munt devices/sound/munt/c_interface \ + devices/sound/munt/sha1 devices/sound/munt/srchelper \ + devices/sound/resid-fp \ + devices/video \ + machines ui win + + +# +# Select the required build environment. +# +VCOPTS := -D_CRT_SECURE_NO_WARNINGS -D__MSC__ +ifeq ($(X64), y) + ARCH := x64 + CPP := cl -nologo + CC := cl -nologo +else + ARCH := x86 + CPP := cl -nologo + CC := cl -nologo #-TP +endif +PREPROC := cl -nologo -EP +MCPP := mcpp.exe +LINK := link -nologo +WINDRES := rc -nologo -r -d_MSC_VER + +SYSINC := -Iwin/msvc/Include -Iwin/mingw/include +SYSLIB := + +DEPS = -MMD -MF $*.d +DEPFILE := win\msvc\.depends + +# Set up the correct toolchain flags. +OPTS := $(EXTRAS) $(STUFF) $(VCOPTS) \ + -D_USE_MATH_DEFINES \ + -D_CRT_NONSTDC_NO_DEPRECATE \ + -D_WINSOCK_DEPRECATED_NO_WARNINGS \ + -D_CRT_SECURE_NO_WARNINGS \ + -D_CRT_STDIO_ISO_WIDE_SPECIFIERS \ + $(WPCAPINC) $(SYSINC) +AFLAGS := #/arch:SSE2 +RFLAGS := /n +COPTS := -W3 +CXXOPTS := -EHsc +DOPTS := +ifeq ($(X64), y) +LOPTS := -MACHINE:$(ARCH) -LIBPATH:win\msvc\Lib\$(ARCH) +LOPTS_C := -SUBSYSTEM:CONSOLE +LOPTS_W := -SUBSYSTEM:WINDOWS +else +LOPTS := -MACHINE:$(ARCH) -LIBPATH:win\msvc\Lib\$(ARCH) +LOPTS_C := -SUBSYSTEM:CONSOLE,5.01 +LOPTS_W := -SUBSYSTEM:WINDOWS,5.01 +endif +ifdef BUILD + OPTS += -DBUILD=$(BUILD) +endif +ifdef COMMIT + OPTS += -DCOMMIT=0x$(COMMIT) +endif +ifdef UPSTREAM + OPTS += -DUPSTREAM=0x$(UPSTREAM) +endif +ifdef EXFLAGS + OPTS += $(EXFLAGS) +endif +ifdef EXINC + OPTS += -I$(EXINC) +endif +OPTS += $(SYSINC) +ifeq ($(OPTIM), y) + AFLAGS := /arch:AVX2 +endif +ifeq ($(DEBUG), y) + OPTS += -D_DEBUG + DOPTS += -MTd -Gs -Zi + RFLAGS += -D_DEBUG + LOPTS += -debug + ifndef COPTIM + COPTIM := -Od + endif +else + LOPTS += -LTCG + DOPTS := -MT -GL + ifndef COPTIM + COPTIM := -O2 + endif +endif +ifeq ($(LOGGING), y) + OPTS += -D_LOGGING + RFLAGS += -D_LOGGING +endif +ifeq ($(CRASHDUMP), y) + OPTS += -DUSE_CRASHDUMP +endif +ifeq ($(RELEASE), y) + OPTS += -DRELEASE_BUILD + RFLAGS += -DRELEASE_BUILD +endif +ifeq ($(PROFILER), y) + LOPTS += /MAP +endif +ifeq ($(VRAMDUMP), y) + OPTS += -DENABLE_VRAM_DUMP + RFLAGS += -DENABLE_VRAM_DUMP +endif +ifeq ($(X64), y) + PLATCG := codegen_x86-64.obj + CGOPS := codegen_ops_x86-64.h + VCG := vid_voodoo_codegen_x86-64.h +else + PLATCG := codegen_x86.obj + CGOPS := codegen_ops_x86.h + VCG := vid_voodoo_codegen_x86.h +endif +LIBS := ddraw.lib dinput8.lib dxguid.lib d3d9.lib d3dx9.lib \ + version.lib comctl32.lib winmm.lib comdlg32.lib \ + advapi32.lib gdi32.lib shell32.lib user32.lib \ + ws2_32.lib wsock32.lib iphlpapi.lib psapi.lib +ifeq ($(DEBUG), y) +LIBS += libcmtd.lib libvcruntimed.lib libucrtd.lib +endif + + +# Optional modules. +MISCOBJ := +ifeq ($(DYNAREC), y) + OPTS += -DUSE_DYNAREC + RFLAGS += -DUSE_DYNAREC + DYNARECOBJ := 386_dynarec_ops.obj \ + codegen.obj \ + codegen_ops.obj \ + codegen_timing_common.obj codegen_timing_486.obj \ + codegen_timing_686.obj codegen_timing_pentium.obj \ + codegen_timing_winchip.obj $(PLATCG) +endif + +ifeq ($(VNS), y) + OPTS += -DUSE_VNS + MISCOBJ += net_vns.obj +endif + +ifeq ($(OPENAL), y) + OPTS += -DUSE_OPENAL +endif + +ifeq ($(FLUIDSYNTH), y) + OPTS += -DUSE_FLUIDSYNTH + MISCOBJ += midi_fluidsynth.obj +endif + +ifeq ($(MUNT), y) + OPTS += -DUSE_MUNT + MISCOBJ += midi_mt32.obj \ + Analog.obj BReverbModel.obj File.obj FileStream.obj \ + LA32Ramp.obj LA32FloatWaveGenerator.obj \ + LA32WaveGenerator.obj MidiStreamParser.obj Part.obj \ + Partial.obj PartialManager.obj Poly.obj ROMInfo.obj \ + SampleRateConverter_dummy.obj Synth.obj Tables.obj \ + TVA.obj TVF.obj TVP.obj sha1.obj c_interface.obj +endif + +# N=no, Y=yes,linked, D=yes,dynamic, S=yes,static +ifneq ($(SDL), n) + OPTS += -DUSE_SDL + RFLAGS += -DUSE_SDL + ifneq ($(SDL_PATH), ) + OPTS += -I$(SDL_PATH)/include/msvc -I$(SDL_PATH)/include + ifeq ($(X64), y) + LOPTS += -LIBPATH:$(SDL_PATH)\lib\msvc\x64 + else + LOPTS += -LIBPATH:$(SDL_PATH)\lib\msvc\x86 + endif + endif + ifeq ($(SDL), y) + LIBS += sdl2.lib + endif + SDLOBJ := win_sdl.obj +endif + +# N=no, Y=yes,linked, D=yes,dynamic, S=yes,static +ifneq ($(D2D), n) + ifeq ($(D2D), d) + OPTS += -DUSE_D2D=2 + else + OPTS += -DUSE_D2D=1 + endif + RFLAGS += -DUSE_D2D + ifneq ($(D2D_PATH), ) + OPTS += -I$(D2D_PATH)/include/msvc -I$(D2D_PATH)/include + ifeq ($(X64), y) + LOPTS += -LIBPATH:$(D2D_PATH)\lib\msvc\x64 + else + LOPTS += -LIBPATH:$(D2D_PATH)\lib\msvc\x86 + endif + endif + ifeq ($(D2D), y) + LIBS += d2d1.lib + endif + D2DOBJ := win_d2d.obj +endif + +# N=no, Y=yes,linked, D=yes,dynamic, S=yes,static +ifneq ($(VNC), n) + OPTS += -DUSE_VNC + RFLAGS += -DUSE_VNC + ifneq ($(VNC_PATH), ) + OPTS += -I$(VNC_PATH)/include/msvc -I$(VNC_PATH)/include + ifeq ($(X64), y) + LOPTS += -LIBPATH:$(VNC_PATH)\lib\x64 + else + LOPTS += -LIBPATH:$(VNC_PATH)\lib\x86 + endif + endif + ifeq ($(VNC), y) + LIBS += libvncserver.lib + endif + MISCOBJ += vnc.obj vnc_keymap.obj +endif + +# N=no, Y=yes,linked, D=yes,dynamic, S=yes,static +ifneq ($(RDP), n) + OPTS += -DUSE_RDP + RFLAGS += -DUSE_RDP + ifneq ($(RDP_PATH), ) + OPTS += -I$(RDP_PATH)/include/msvc -I$(RDP_PATH)/include + ifeq ($(X64), y) + LOPTS += -LIBPATH:$(RDP_PATH)\lib\x64 + else + LOPTS += -LIBPATH:$(RDP_PATH)\lib\x86 + endif + endif + ifeq ($(RDP), y) + LIBS += rdpsrvr.lib + endif + MISCOBJ += rdp.obj +endif + +# N=no, Y=yes,linked, D=yes,dynamic, S=yes,static +ifneq ($(PNG), n) + ifeq ($(PNG), d) + OPTS += -DUSE_LIBPNG=2 + else + OPTS += -DUSE_LIBPNG=1 + endif + RFLAGS += -DUSE_LIBPNG + ifneq ($(PNG_PATH), ) + OPTS += -I$(PNG_PATH)/include/msvc -I$(PNG_PATH)/include + ifeq ($(X64), y) + LOPTS += -LIBPATH:$(PNG_PATH)\lib\x64 + else + LOPTS += -LIBPATH:$(PNG_PATH)\lib\x86 + endif + endif + ifeq ($(PNG), y) + LIBS += libpng16_dll.lib #zlib.lib + endif + MISCOBJ += png.obj +endif + +# N=no, Y=yes,linked, D=yes,dynamic, S=yes,static +ifneq ($(WX), n) + OPTS += -DUSE_WX $(WX_FLAGS) + LIBS += $(WX_LIBS) -lm + UIOBJ := wx_main.obj wx_ui.obj wx_stbar.obj wx_render.obj +else + UIOBJ := win_ui.obj \ + win_ddraw.obj win_d3d.obj $(SDLOBJ) $(D2DOBJ) \ + win_dialog.obj win_about.obj win_settings.obj \ + win_devconf.obj win_snd_gain.obj win_new_image.obj +endif + + +# Options for the DEV branch. +ifeq ($(DEV_BRANCH), y) + OPTS += -DDEV_BRANCH + DEVBROBJ := + + ifeq ($(AMD_K), y) + OPTS += -DUSE_AMD_K + endif + + ifeq ($(LASERXT), y) + OPTS += -DUSE_LASERXT + DEVBROBJ += m_xt_laserxt.obj + endif + + ifeq ($(PORTABLE3), y) + OPTS += -DUSE_PORTABLE3 + endif + + ifeq ($(I686), y) + OPTS += -DUSE_I686 + endif + + ifeq ($(PAS16), y) + OPTS += -DUSE_PAS16 + DEVBROBJ += snd_pas16.obj + endif + + ifeq ($(GUSMAX), y) + OPTS += -DUSE_GUSMAX + DEVBROBJ += snd_cs423x.obj + endif + + ifeq ($(XL24), y) + OPTS += -DUSE_XL24 + endif + + ifeq ($(WONDER), y) + OPTS += -DUSE_WONDER + endif + + ifeq ($(HOSTCD), y) + OPTS += -DUSE_HOST_CDROM + endif + + ifeq ($(PRINTER), y) + OPTS += -DUSE_PRINTER + DEVBROBJ += prt_parallel.obj + endif +endif + + +# Final versions of the toolchain flags. +LDFLAGS := $(LOPTS) +CFLAGS := $(WX_FLAGS) $(OPTS) $(COPTS) $(COPTIM) $(DOPTS) $(AFLAGS) +CXXFLAGS := $(WX_FLAGS) $(OPTS) $(CXXOPTS) $(COPTS) $(COPTIM) $(DOPTS) $(AFLAGS) + + +######################################################################### +# Create the (final) list of objects to build. # +######################################################################### + +RESDLL := VARCem-$(LANG) + +MAINOBJ := pc.obj config.obj misc.obj random.obj timer.obj io.obj \ + mem.obj rom.obj rom_load.obj device.obj nvr.obj + +UIOBJ += ui_main.obj ui_lang.obj ui_stbar.obj ui_vidapi.obj \ + ui_cdrom.obj ui_new_image.obj ui_misc.obj + +SYSOBJ := dma.obj nmi.obj pic.obj pit.obj ppi.obj pci.obj mca.obj \ + mcr.obj memregs.obj nvr_at.obj nvr_ps2.obj + +CPUOBJ := cpu.obj cpu_table.obj \ + 808x.obj 386.obj x86seg.obj x87.obj \ + 386_dynarec.obj $(DYNARECOBJ) + +MCHOBJ := machine.obj machine_table.obj \ + m_xt.obj m_xt_compaq.obj \ + m_xt_t1000.obj m_xt_t1000_vid.obj \ + m_xt_xi8088.obj \ + m_pcjr.obj \ + m_amstrad.obj m_europc.obj \ + m_olivetti_m24.obj m_tandy.obj \ + m_at.obj \ + m_at_ali1429.obj m_at_commodore.obj \ + m_at_neat.obj m_at_headland.obj \ + m_at_t3100e.obj m_at_t3100e_vid.obj \ + m_ps1.obj m_ps1_hdc.obj \ + m_ps2_isa.obj m_ps2_mca.obj \ + m_at_opti495.obj m_at_scat.obj \ + m_at_compaq.obj m_at_wd76c10.obj \ + m_at_sis471.obj m_at_sis496.obj \ + m_at_4x0.obj + +INTELOBJ := intel.obj \ + intel_flash.obj \ + intel_sio.obj \ + intel_piix.obj + +DEVOBJ := bugger.obj \ + isamem.obj isartc.obj \ + game.obj game_dev.obj \ + parallel.obj parallel_dev.obj \ + prt_text.obj prt_cpmap.obj prt_escp.obj \ + serial.obj \ + sio_fdc37c66x.obj sio_fdc37c669.obj sio_fdc37c93x.obj \ + sio_pc87306.obj sio_w83877f.obj sio_um8669f.obj \ + keyboard.obj \ + keyboard_xt.obj keyboard_at.obj \ + mouse.obj \ + mouse_serial.obj mouse_ps2.obj mouse_bus.obj \ + joystick.obj \ + js_standard.obj js_ch_fs_pro.obj \ + js_sw_pad.obj js_tm_fcs.obj + +FDDOBJ := fdc.obj \ + fdd.obj \ + fdd_common.obj fdd_86f.obj \ + fdd_fdi.obj fdi2raw.obj lzf_c.obj lzf_d.obj \ + fdd_imd.obj fdd_img.obj fdd_json.obj fdd_td0.obj + +HDDOBJ := hdd.obj \ + hdd_image.obj hdd_table.obj \ + hdc.obj \ + hdc_st506_xt.obj hdc_st506_at.obj \ + hdc_esdi_at.obj hdc_esdi_mca.obj \ + hdc_ide_ata.obj hdc_ide_xta.obj hdc_xtide.obj + +CDROMOBJ := cdrom.obj \ + cdrom_speed.obj \ + cdrom_dosbox.obj cdrom_image.obj + +ZIPOBJ := zip.obj + +ifeq ($(USB), y) +USBOBJ := usb.obj +endif + +SCSIOBJ := scsi.obj \ + scsi_device.obj scsi_disk.obj scsi_cdrom.obj \ + scsi_x54x.obj scsi_aha154x.obj scsi_buslogic.obj \ + scsi_ncr5380.obj scsi_ncr53c810.obj + +NETOBJ := network.obj \ + network_dev.obj \ + net_pcap.obj \ + net_slirp.obj \ + net_dp8390.obj \ + net_ne2000.obj net_wd80x3.obj net_3c503.obj + +SNDOBJ := sound.obj \ + sound_dev.obj \ + openal.obj \ + snd_opl.obj snd_dbopl.obj \ + dbopl.obj nukedopl.obj \ + snd_resid.obj \ + convolve.obj convolve-sse.obj envelope.obj extfilt.obj \ + filter.obj pot.obj sid.obj voice.obj wave6581__ST.obj \ + wave6581_P_T.obj wave6581_PS_.obj wave6581_PST.obj \ + wave8580__ST.obj wave8580_P_T.obj wave8580_PS_.obj \ + wave8580_PST.obj wave.obj \ + midi.obj midi_system.obj \ + snd_speaker.obj \ + snd_lpt_dac.obj snd_lpt_dss.obj \ + snd_adlib.obj snd_adlibgold.obj snd_ad1848.obj snd_audiopci.obj \ + snd_cms.obj \ + snd_gus.obj \ + snd_sb.obj snd_sb_dsp.obj \ + snd_emu8k.obj snd_mpu401.obj \ + snd_sn76489.obj snd_ssi2001.obj \ + snd_wss.obj \ + snd_ym7128.obj + +VIDOBJ := video.obj \ + video_dev.obj \ + vid_cga.obj vid_cga_comp.obj \ + vid_cga_compaq.obj \ + vid_mda.obj \ + vid_hercules.obj vid_herculesplus.obj vid_incolor.obj \ + vid_colorplus.obj \ + vid_genius.obj \ + vid_sigma.obj \ + vid_wy700.obj \ + vid_ega.obj vid_ega_render.obj \ + vid_svga.obj vid_svga_render.obj \ + vid_vga.obj \ + vid_ati_eeprom.obj \ + vid_ati18800.obj vid_ati28800.obj \ + vid_ati_mach64.obj vid_ati68860_ramdac.obj \ + vid_bt48x_ramdac.obj vid_icd2061.obj vid_ics2595.obj \ + vid_cl54xx.obj \ + vid_et4000.obj vid_sc1502x_ramdac.obj \ + vid_et4000w32.obj vid_stg_ramdac.obj \ + vid_oak_oti.obj \ + vid_paradise.obj \ + vid_ti_cf62011.obj \ + vid_tvga.obj \ + vid_tgui9440.obj vid_tkd8001_ramdac.obj \ + vid_s3.obj vid_s3_virge.obj \ + vid_sdac_ramdac.obj \ + vid_voodoo.obj + +PLATOBJ := win.obj \ + win_lang.obj win_opendir.obj win_dynld.obj win_thread.obj \ + win_cdrom.obj win_keyboard.obj win_mouse.obj \ + win_joystick.obj win_midi.obj +ifeq ($(CRASHDUMP), y) +PLATOBJ += win_crashdump.obj +endif + + +OBJ := $(MAINOBJ) $(CPUOBJ) $(MCHOBJ) $(SYSOBJ) $(DEVOBJ) \ + $(INTELOBJ) $(FDDOBJ) $(CDROMOBJ) $(ZIPOBJ) $(HDDOBJ) \ + $(USBOBJ) $(NETOBJ) $(SCSIOBJ) $(SNDOBJ) $(VIDOBJ) \ + $(UIOBJ) $(PLATOBJ) $(MISCOBJ) $(DEVBROBJ) +ifdef EXOBJ +OBJ += $(EXOBJ) +endif + + +# Build module rules. +ifeq ($(AUTODEP), y) +%.obj: %.c + @$(CC) $(CFLAGS) -Fo$@ -c $< + @$(MCPP) $(OPTS) $(DEPS) $< + +%.obj: %.cpp + @$(CPP) $(CXXFLAGS) -Fo$@ -c $< + @$(MCPP) $(OPTS) $(DEPS) $< +else +%.obj: %.c + @$(CC) $(CFLAGS) -Fo$@ -c $< + +%.obj: %.cpp + @$(CPP) $(CXXFLAGS) -Fo$@ -c $< + +%.d: %.c $(wildcard $*.d) + $(MCPP) $(OPTS) $(DEPS) $< >NUL + +%.d: %.cpp $(wildcard $*.d) + $(MCPP) $(OPTS) $(DEPS) $< >NUL +endif + + +all: $(PREBUILD) $(PROG).exe $(NETIF).exe $(POSTBUILD) + +# +# This rule creates a script (command file) that figures out which +# language we want to make (its argument is the 2-letter language +# name, or none) by looking it up in the database of supported ones, +# and then it calls the (this) Makefile back with the proper args +# for that target. +# +# We do it this way so it can also be used by the VC project files. +# +win/Mklang.cmd: win/msvc/Makefile.VC + @echo @SET PATH=$(PATH) >>win\Mklang.cmd + @echo @SETLOCAL >>win\Mklang.cmd + @echo @SET LANG=none >>win\Mklang.cmd + @echo @FOR /F "eol=# tokens=1,2,3,4* delims=, " %%%%i in (ui\lang\VARCem.lang) do @if "%%1"=="%%%%i" set LANG=%%%%i LANGID=%%%%j PRILANG=%%%%k SUBLANG=%%%%l >>win\Mklang.cmd + @echo @IF NOT "%%LANG%%"=="none" @$(MAKE) -fwin/msvc/Makefile.VC "RFLAGS=$(RFLAGS) $(EXTRAS)" LANG=%%LANG%% VARCem-%%1.dll >>win\Mklang.cmd + + +langs: win/Mklang.cmd +ifdef LANG + @echo Generating localization $(LANG) .. +else + @echo Generating localizations.. + @FOR /F "eol=# tokens=1 delims=, " %%i in (ui\lang\VARCem.lang) do @win\Mklang %%i +endif + @-del win\Mklang.cmd + +$(RESDLL).rc: VARCem.rpp + @win\msvc\preproc $< $@ "-DPREAMBLE=" "-DLANG=$(LANG)" "-DLANGID=$(LANGID)" "-DPRILANG=$(PRILANG)" "-DSUBLANG=$(SUBLANG)" + +$(RESDLL).res: $(RESDLL).rc VARCem-common.rc + @echo Processing $(RESDLL).rc .. + @$(WINDRES) $(RFLAGS) -fo$@ $< + +$(RESDLL).dll: $(RESDLL).res + @echo Linking $(RESDLL).dll .. + @$(LINK) /DLL /NOENTRY $(LDFLAGS) -OUT:$@ $(RESDLL).res + @-del $(RESDLL).rc + +VARCem.res: VARCem.rc win/VARCem.mpp + @win\msvc\preproc win/VARCem.mpp VARCem.manifest + @echo Processing $< + @$(WINDRES) $(RFLAGS) $(EXTRAS) -fo$@ $< + +$(PROG).exe: $(OBJ) VARCem.res + @echo Linking $(PROG).exe .. + @$(LINK) $(LDFLAGS) $(LOPTS_W) -OUT:$(PROG).exe \ + $(OBJ) VARCem.res $(LIBS) + +pcap_if.res: pcap_if.rc + @echo Processing $< + @$(WINDRES) $(RFLAGS) -fo$@ $< + +$(NETIF).exe: pcap_if.obj win_dynld.obj pcap_if.res + @echo Linking $(NETIF).exe .. + @$(LINK) $(LDFLAGS) $(LOPTS_C) -OUT:$@ \ + pcap_if.obj win_dynld.obj pcap_if.res + +clean: + @echo Cleaning objects.. + @-del *.obj 2>NUL + @-del *.res 2>NUL + +clobber: Mklang.cmd clean + @echo Cleaning executables.. + @-del *.d 2>NUL + @-del *.exe 2>NUL +ifeq ($(DEBUG), y) + @-del *.ilk 2>NUL + @-del *.pdb 2>NUL +endif +ifeq ($(PROFILER), y) + @-del *.map 2>NUL +endif + @-del *.manifest 2>NUL + @-del *.dll 2>NUL + @-del win\Mklang.cmd +# @del $(DEPFILE) 2>NUL + +ifneq ($(AUTODEP), y) +depclean: + @del $(DEPFILE) 2>NUL + @echo Creating dependencies.. + @echo # Run "make depends" to re-create this file. >$(DEPFILE) + +depends: DEPOBJ=$(OBJ:%.obj=%.d) +depends: depclean $(OBJ:%.obj=%.d) + @-cat $(DEPOBJ) >>$(DEPFILE) + @del $(DEPOBJ) + +$(DEPFILE): +endif + + +# Module dependencies. +ifeq ($(AUTODEP), y) +#-include $(OBJ:%.obj=%.d) (better, but sloooowwwww) +-include *.d +else +include $(wildcard $(DEPFILE)) +endif + + +# End of Makefile.VC. diff --git a/src/win/msvc/vc15/VARCem.vcxproj b/src/win/msvc/vc15/VARCem.vcxproj index 7e28f99..3a31d40 100644 --- a/src/win/msvc/vc15/VARCem.vcxproj +++ b/src/win/msvc/vc15/VARCem.vcxproj @@ -1,748 +1,748 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - true - true - _MSC_VER - _MSC_VER - - - - - Document - Generating Manifest file... - Generating Manifest file... - Generating Manifest file... - Generating Manifest file... - VARCem.manifest - VARCem.manifest - VARCem.manifest - VARCem.manifest - VARCem.rc - VARCem.rc - VARCem.rc - VARCem.rc - cl -nologo -EP %(FullPath) > $(SolutionDir)..\..\%(Outputs) - cl -nologo -EP %(FullPath) > $(SolutionDir)..\..\%(Outputs) - cl -nologo -EP %(FullPath) > $(SolutionDir)..\..\%(Outputs) - cl -nologo -EP %(FullPath) > $(SolutionDir)..\..\%(Outputs) - - - - 15.0 - {6E445F28-CA8F-430F-8CCF-C59C53516AC5} - Win32Proj - VARCem - 8.1 - - - - Application - true - v141 - NotSet - - - Application - false - v141 - true - NotSet - - - Application - true - v141 - NotSet - - - Application - false - v141 - true - NotSet - - - - - - - - - - - - - - - - - - - - - - - - - true - $(ProjectDir)\..\Lib\x86;$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86) - false - - - true - $(ProjectDir)\..\Lib\x64;$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64) - false - - - false - $(ProjectDir)\..\Lib\x86;$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86) - false - - - false - $(ProjectDir)\..\Lib\x64;$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64) - false - - - - NotUsing - Level3 - Disabled - true - WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) - - - Windows - DebugFull - winmm.lib;ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;iphlpapi.lib;psapi.lib;Comctl32.lib;DInput8.lib;d3d9.lib;d3dx9.lib;ddraw.lib;dxguid.lib;version.lib;%(AdditionalDependencies) - 5.01 - - - $(ProjectDir)\..\..\..\..\src;%(AdditionalIncludeDirectories) - SKIP_MANIFEST - - - - - NotUsing - Level3 - Disabled - true - _DEBUG;_WINDOWS;%(PreprocessorDefinitions) - - - Windows - DebugFull - winmm.lib;ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;iphlpapi.lib;psapi.lib;Comctl32.lib;DInput8.lib;d3d9.lib;d3dx9.lib;ddraw.lib;dxguid.lib;version.lib;%(AdditionalDependencies) - 5.01 - - - $(ProjectDir)\..\..\..\..\src;%(AdditionalIncludeDirectories) - - - - - NotUsing - Level3 - MaxSpeed - true - true - true - WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) - - - Windows - true - true - DebugFull - winmm.lib;ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;iphlpapi.lib;psapi.lib;Comctl32.lib;DInput8.lib;d3d9.lib;d3dx9.lib;ddraw.lib;dxguid.lib;version.lib;%(AdditionalDependencies) - 5.01 - - - $(ProjectDir)\..\..\..\..\src;%(AdditionalIncludeDirectories) - SKIP_MANIFEST - - - - - NotUsing - Level3 - MaxSpeed - true - true - true - NDEBUG;_WINDOWS;%(PreprocessorDefinitions) - - - Windows - true - true - DebugFull - winmm.lib;ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;iphlpapi.lib;psapi.lib;Comctl32.lib;DInput8.lib;d3d9.lib;d3dx9.lib;ddraw.lib;dxguid.lib;version.lib;%(AdditionalDependencies) - 5.01 - - - $(ProjectDir)\..\..\..\..\src;%(AdditionalIncludeDirectories) - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + true + _MSC_VER + _MSC_VER + + + + + Document + Generating Manifest file... + Generating Manifest file... + Generating Manifest file... + Generating Manifest file... + VARCem.manifest + VARCem.manifest + VARCem.manifest + VARCem.manifest + VARCem.rc + VARCem.rc + VARCem.rc + VARCem.rc + cl -nologo -EP %(FullPath) > $(SolutionDir)..\..\%(Outputs) + cl -nologo -EP %(FullPath) > $(SolutionDir)..\..\%(Outputs) + cl -nologo -EP %(FullPath) > $(SolutionDir)..\..\%(Outputs) + cl -nologo -EP %(FullPath) > $(SolutionDir)..\..\%(Outputs) + + + + 15.0 + {6E445F28-CA8F-430F-8CCF-C59C53516AC5} + Win32Proj + VARCem + 8.1 + + + + Application + true + v141 + NotSet + + + Application + false + v141 + true + NotSet + + + Application + true + v141 + NotSet + + + Application + false + v141 + true + NotSet + + + + + + + + + + + + + + + + + + + + + + + + + true + $(ProjectDir)\..\Lib\x86;$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86) + false + + + true + $(ProjectDir)\..\Lib\x64;$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64) + false + + + false + $(ProjectDir)\..\Lib\x86;$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86) + false + + + false + $(ProjectDir)\..\Lib\x64;$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64) + false + + + + NotUsing + Level3 + Disabled + true + WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + + + Windows + DebugFull + winmm.lib;ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;iphlpapi.lib;psapi.lib;Comctl32.lib;DInput8.lib;d3d9.lib;d3dx9.lib;ddraw.lib;dxguid.lib;version.lib;%(AdditionalDependencies) + 5.01 + + + $(ProjectDir)\..\..\..\..\src;%(AdditionalIncludeDirectories) + SKIP_MANIFEST + + + + + NotUsing + Level3 + Disabled + true + _DEBUG;_WINDOWS;%(PreprocessorDefinitions) + + + Windows + DebugFull + winmm.lib;ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;iphlpapi.lib;psapi.lib;Comctl32.lib;DInput8.lib;d3d9.lib;d3dx9.lib;ddraw.lib;dxguid.lib;version.lib;%(AdditionalDependencies) + 5.01 + + + $(ProjectDir)\..\..\..\..\src;%(AdditionalIncludeDirectories) + + + + + NotUsing + Level3 + MaxSpeed + true + true + true + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + + + Windows + true + true + DebugFull + winmm.lib;ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;iphlpapi.lib;psapi.lib;Comctl32.lib;DInput8.lib;d3d9.lib;d3dx9.lib;ddraw.lib;dxguid.lib;version.lib;%(AdditionalDependencies) + 5.01 + + + $(ProjectDir)\..\..\..\..\src;%(AdditionalIncludeDirectories) + SKIP_MANIFEST + + + + + NotUsing + Level3 + MaxSpeed + true + true + true + NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + + + Windows + true + true + DebugFull + winmm.lib;ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;iphlpapi.lib;psapi.lib;Comctl32.lib;DInput8.lib;d3d9.lib;d3dx9.lib;ddraw.lib;dxguid.lib;version.lib;%(AdditionalDependencies) + 5.01 + + + $(ProjectDir)\..\..\..\..\src;%(AdditionalIncludeDirectories) + + + + + \ No newline at end of file diff --git a/src/win/win_serial.c b/src/win/win_serial.c index a3a42bc..24da2b6 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.4 2018/10/07 + * Version: @(#)win_serial.c 1.0.5 2018/11/22 * * Author: Fred N. van Kempen, * @@ -53,79 +53,88 @@ #include #include #include -#define PLAT_SERIAL_C #include "../emu.h" #include "../plat.h" #include "../devices/ports/serial.h" +typedef struct { + char name[80]; /* name of open port */ + void (*rd_done)(void *, int); + void *rd_arg; + HANDLE handle; + OVERLAPPED rov, /* READ and WRITE events */ + wov; + int tmo; /* current timeout value */ + DCB dcb, /* terminal settings */ + odcb; + thread_t *tid; /* pointer to receiver thread */ + char buff[1024]; + int icnt, ihead, itail; +} serial_t; + + /* Handle the receiving of data from the host port. */ static void -bhtty_reader(void *arg) +reader_thread(void *arg) { - BHTTY *pp = (BHTTY *)arg; - unsigned char b; + serial_t *dev = (serial_t *)arg; + uint8_t b; DWORD n; - pclog("%s: thread started\n", pp->name); + INFO("%s: thread started\n", dev->name); /* As long as the channel is open.. */ - while (pp->tid != NULL) { + while (dev->tid != NULL) { /* Post a READ on the device. */ n = 0; - if (ReadFile(pp->handle, &b, (DWORD)1, &n, &pp->rov) == FALSE) { + if (ReadFile(dev->handle, &b, (DWORD)1, &n, &dev->rov) == FALSE) { n = GetLastError(); if (n != ERROR_IO_PENDING) { /* Not good, we got an error. */ - pclog("%s: I/O error %d in read!\n", pp->name, n); + ERRLOG("%s: I/O error %i in read!\n", dev->name, n); break; } /* The read is pending, wait for it.. */ - if (GetOverlappedResult(pp->handle, &pp->rov, &n, TRUE) == FALSE) { + if (GetOverlappedResult(dev->handle, &dev->rov, &n, TRUE) == FALSE) { n = GetLastError(); - pclog("%s: I/O error %d in read!\n", pp->name, n); + ERRLOG("%s: I/O error %i in read!\n", dev->name, n); break; } } -pclog("%s: got %d bytes of data\n", pp->name, n); +pclog(0,"%s: got %i bytes of data\n", dev->name, n); if (n == 1) { /* We got data, update stuff. */ - if (pp->icnt < sizeof(pp->buff)) { -pclog("%s: queued byte %02x (%d)\n", pp->name, b, pp->icnt+1); - pp->buff[pp->ihead++] = b; - pp->ihead &= (sizeof(pp->buff)-1); - pp->icnt++; + if (dev->icnt < sizeof(dev->buff)) { +pclog(0,"%s: queued byte %02x (%i)\n", dev->name, b, dev->icnt+1); + dev->buff[dev->ihead++] = b; + dev->ihead &= (sizeof(dev->buff)-1); + dev->icnt++; /* Do a callback to let them know. */ - if (pp->rd_done != NULL) - pp->rd_done(pp->rd_arg, n); + if (dev->rd_done != NULL) + dev->rd_done(dev->rd_arg, n); } else { - pclog("%s: RX buffer overrun!\n", pp->name); + ERRLOG("%s: RX buffer overrun!\n", dev->name); } } } /* Error or done, clean up. */ - pp->tid = NULL; - pclog("%s: thread stopped.\n", pp->name); + dev->tid = NULL; + INFO("%s: thread stopped.\n", dev->name); } /* Set the state of a port. */ -int -bhtty_sstate(BHTTY *pp, void *arg) +static int +set_state(serial_t *dev, void *arg) { - /* Make sure we can do this. */ - if (arg == NULL) { - pclog("%s: invalid argument\n", pp->name); - return(-1); - } - - if (SetCommState(pp->handle, (DCB *)arg) == FALSE) { - /* Mark an error. */ - pclog("%s: set state: %d\n", pp->name, GetLastError()); + if (SetCommState(dev->handle, (DCB *)arg) == FALSE) { + /* Mark as error. */ + ERRLOG("%s: set state: %i\n", dev->name, GetLastError()); return(-1); } @@ -134,18 +143,12 @@ bhtty_sstate(BHTTY *pp, void *arg) /* Fetch the state of a port. */ -int -bhtty_gstate(BHTTY *pp, void *arg) +static int +get_state(serial_t *dev, void *arg) { - /* Make sure we can do this. */ - if (arg == NULL) { - pclog("%s: invalid argument\n", pp->name); - return(-1); - } - - if (GetCommState(pp->handle, (DCB *)arg) == FALSE) { - /* Mark an error. */ - pclog("%s: get state: %d\n", pp->name, GetLastError()); + if (GetCommState(dev->handle, (DCB *)arg) == FALSE) { + /* Mark as error. */ + ERRLOG("%s: get state: %i\n", dev->name, GetLastError()); return(-1); } @@ -154,42 +157,42 @@ bhtty_gstate(BHTTY *pp, void *arg) /* Enable or disable RTS/CTS mode (hardware handshaking.) */ -int -bhtty_crtscts(BHTTY *pp, char yesno) +static int +set_crtscts(serial_t *dev, int8_t yes) { /* Get the current mode. */ - if (bhtty_gstate(pp, &pp->dcb) < 0) return(-1); + if (get_state(dev, &dev->dcb) < 0) return(-1); - switch(yesno) { + switch (yes) { case 0: /* disable CRTSCTS */ - pp->dcb.fOutxDsrFlow = 0; /* disable DSR/DCD mode */ - pp->dcb.fDsrSensitivity = 0; + dev->dcb.fOutxDsrFlow = 0; /* disable DSR/DCD mode */ + dev->dcb.fDsrSensitivity = 0; - pp->dcb.fOutxCtsFlow = 0; /* disable RTS/CTS mode */ + dev->dcb.fOutxCtsFlow = 0; /* disable RTS/CTS mode */ - pp->dcb.fTXContinueOnXoff = 0; /* disable XON/XOFF mode */ - pp->dcb.fOutX = 0; - pp->dcb.fInX = 0; + dev->dcb.fTXContinueOnXoff = 0; /* disable XON/XOFF mode */ + dev->dcb.fOutX = 0; + dev->dcb.fInX = 0; break; case 1: /* enable CRTSCTS */ - pp->dcb.fOutxDsrFlow = 0; /* disable DSR/DCD mode */ - pp->dcb.fDsrSensitivity = 0; + dev->dcb.fOutxDsrFlow = 0; /* disable DSR/DCD mode */ + dev->dcb.fDsrSensitivity = 0; - pp->dcb.fOutxCtsFlow = 1; /* enable RTS/CTS mode */ + dev->dcb.fOutxCtsFlow = 1; /* enable RTS/CTS mode */ - pp->dcb.fTXContinueOnXoff = 0; /* disable XON/XOFF mode */ - pp->dcb.fOutX = 0; - pp->dcb.fInX = 0; + dev->dcb.fTXContinueOnXoff = 0; /* disable XON/XOFF mode */ + dev->dcb.fOutX = 0; + dev->dcb.fInX = 0; break; default: - pclog("%s: invalid parameter '%d'!\n", pp->name, yesno); + ERRLOG("%s: invalid parameter '%i'!\n", dev->name, yes); return(-1); } /* Set new mode. */ - if (bhtty_sstate(pp, &pp->dcb) < 0) return(-1); + if (set_state(dev, &dev->dcb) < 0) return(-1); return(0); } @@ -197,13 +200,15 @@ bhtty_crtscts(BHTTY *pp, char yesno) /* Set the port parameters. */ int -bhtty_params(BHTTY *pp, char dbit, char par, char sbit) +plat_serial_params(void *arg, char dbit, char par, char sbit) { + serial_t *dev = (serial_t *)arg; + /* Get the current mode. */ - if (bhtty_gstate(pp, &pp->dcb) < 0) return(-1); + if (get_state(dev, &dev->dcb) < 0) return(-1); /* Set the desired word length. */ - switch((int)dbit) { + switch ((int)dbit) { case -1: /* no change */ break; @@ -214,36 +219,36 @@ bhtty_params(BHTTY *pp, char dbit, char par, char sbit) case 7: case 8: - pp->dcb.ByteSize = dbit; + dev->dcb.ByteSize = dbit; break; default: - pclog("%s: invalid parameter '%d'!\n", pp->name, dbit); + ERRLOG("%s: invalid parameter '%i'!\n", dev->name, dbit); return(-1); } /* Set the type of parity encoding. */ - switch((int)par) { + switch ((int)par) { case -1: /* no change */ case ' ': break; case 0: case 'N': - pp->dcb.fParity = FALSE; - pp->dcb.Parity = NOPARITY; + dev->dcb.fParity = FALSE; + dev->dcb.Parity = NOPARITY; break; case 1: case 'O': - pp->dcb.fParity = TRUE; - pp->dcb.Parity = ODDPARITY; + dev->dcb.fParity = TRUE; + dev->dcb.Parity = ODDPARITY; break; case 2: case 'E': - pp->dcb.fParity = TRUE; - pp->dcb.Parity = EVENPARITY; + dev->dcb.fParity = TRUE; + dev->dcb.Parity = EVENPARITY; break; case 3: @@ -253,30 +258,30 @@ bhtty_params(BHTTY *pp, char dbit, char par, char sbit) break; default: - pclog("%s: invalid parameter '%c'!\n", pp->name, par); + ERRLOG("%s: invalid parameter '%c'!\n", dev->name, par); return(-1); } /* Set the number of stop bits. */ - switch((int)sbit) { + switch ((int)sbit) { case -1: /* no change */ break; case 1: - pp->dcb.StopBits = ONESTOPBIT; + dev->dcb.StopBits = ONESTOPBIT; break; case 2: - pp->dcb.StopBits = TWOSTOPBITS; + dev->dcb.StopBits = TWOSTOPBITS; break; default: - pclog("%s: invalid parameter '%d'!\n", pp->name, sbit); + ERRLOG("%s: invalid parameter '%i'!\n", dev->name, sbit); return(-1); } /* Set new mode. */ - if (bhtty_sstate(pp, &pp->dcb) < 0) return(-1); + if (set_state(dev, &dev->dcb) < 0) return(-1); return(0); } @@ -284,13 +289,14 @@ bhtty_params(BHTTY *pp, char dbit, char par, char sbit) /* Put a port in transparent ("raw") state. */ void -bhtty_raw(BHTTY *pp, void *arg) +plat_serial_raw(void *arg, void *data) { - DCB *dcb = (DCB *)arg; + serial_t *dev = (serial_t *)arg; + DCB *dcb = (DCB *)data; /* Make sure we can do this. */ - if (arg == NULL) { - pclog("%s: invalid parameter\n", pp->name); + if (dcb == NULL) { + ERRLOG("%s: invalid parameter\n", dev->name); return; } @@ -328,10 +334,12 @@ bhtty_raw(BHTTY *pp, void *arg) /* Set the port speed. */ int -bhtty_speed(BHTTY *pp, long speed) +plat_serial_speed(void *arg, long speed) { + serial_t *dev = (serial_t *)arg; + /* Get the current mode and speed. */ - if (bhtty_gstate(pp, &pp->dcb) < 0) return(-1); + if (get_state(dev, &dev->dcb) < 0) return(-1); /* * Set speed. @@ -340,10 +348,10 @@ bhtty_speed(BHTTY *pp, long speed) * with DCB_xxx speed values here, but we removed that * and just hardcode the speed value into DCB. --FvK */ - pp->dcb.BaudRate = speed; + dev->dcb.BaudRate = speed; /* Set new speed. */ - if (bhtty_sstate(pp, &pp->dcb) < 0) return(-1); + if (set_state(dev, &dev->dcb) < 0) return(-1); return(0); } @@ -351,25 +359,26 @@ bhtty_speed(BHTTY *pp, long speed) /* Clean up and flush. */ int -bhtty_flush(BHTTY *pp) +plat_serial_flush(void *arg) { + serial_t *dev = (serial_t *)arg; DWORD dwErrs; COMSTAT cst; /* First, clear any errors. */ - (void)ClearCommError(pp->handle, &dwErrs, &cst); + (void)ClearCommError(dev->handle, &dwErrs, &cst); /* Now flush all buffers. */ - if (PurgeComm(pp->handle, + if (PurgeComm(dev->handle, (PURGE_RXABORT | PURGE_TXABORT | \ PURGE_RXCLEAR | PURGE_TXCLEAR)) == FALSE) { - pclog("%s: flush: %d\n", pp->name, GetLastError()); + ERRLOG("%s: flush: %i\n", dev->name, GetLastError()); return(-1); } /* Re-clear any errors. */ - if (ClearCommError(pp->handle, &dwErrs, &cst) == FALSE) { - pclog("%s: clear errors: %d\n", pp->name, GetLastError()); + if (ClearCommError(dev->handle, &dwErrs, &cst) == FALSE) { + ERRLOG("%s: clear errors: %i\n", dev->name, GetLastError()); return(-1); } @@ -377,80 +386,76 @@ bhtty_flush(BHTTY *pp) } -/* Close an open serial port. */ +/* API: close an open serial port. */ void -bhtty_close(BHTTY *pp) +plat_serial_close(void *arg) { + serial_t *dev = (serial_t *)arg; + /* If the polling thread is running, stop it. */ - (void)bhtty_active(pp, 0); + plat_serial_active(arg, 0); /* Close the event handles. */ - if (pp->rov.hEvent != INVALID_HANDLE_VALUE) - CloseHandle(pp->rov.hEvent); - if (pp->wov.hEvent != INVALID_HANDLE_VALUE) - CloseHandle(pp->wov.hEvent); + if (dev->rov.hEvent != INVALID_HANDLE_VALUE) + CloseHandle(dev->rov.hEvent); + if (dev->wov.hEvent != INVALID_HANDLE_VALUE) + CloseHandle(dev->wov.hEvent); - if (pp->handle != INVALID_HANDLE_VALUE) { - pclog("%s: closing host port\n", pp->name); + if (dev->handle != INVALID_HANDLE_VALUE) { + INFO("%s: closing host port\n", dev->name); /* Restore the previous port state, if any. */ - (void)bhtty_sstate(pp, &pp->odcb); + set_state(dev, &dev->odcb); /* Close the port. */ - CloseHandle(pp->handle); - pp->handle = INVALID_HANDLE_VALUE; + CloseHandle(dev->handle); } /* Release the control block. */ - free(pp); + free(dev); } -/* Open a host serial port for I/O. */ -BHTTY * -bhtty_open(char *port, int tmo) +/* API: open a host serial port for I/O. */ +void * +plat_serial_open(const char *port, int tmo) { char temp[84]; COMMTIMEOUTS to; COMMCONFIG conf; - BHTTY *pp; + serial_t *dev; DWORD d; /* First things first... create a control block. */ - if ((pp = (BHTTY *)mem_alloc(sizeof(BHTTY))) == NULL) { - pclog("%s: out of memory!\n", port); + if ((dev = (serial_t *)mem_alloc(sizeof(serial_t))) == NULL) { + ERRLOG("%s: out of memory!\n", port); return(NULL); } - memset(pp, 0x00, sizeof(BHTTY)); - strncpy(pp->name, port, sizeof(pp->name)-1); + memset(dev, 0x00, sizeof(serial_t)); + strncpy(dev->name, port, sizeof(dev->name)-1); /* Try a regular Win32 serial port. */ - sprintf(temp, "\\\\.\\%s", pp->name); - if ((pp->handle = CreateFile(temp, - (GENERIC_READ|GENERIC_WRITE), - 0, - NULL, - OPEN_EXISTING, - FILE_FLAG_OVERLAPPED, - 0)) == INVALID_HANDLE_VALUE) { - pclog("%s: open port: %d\n", pp->name, GetLastError()); - free(pp); + sprintf(temp, "\\\\.\\%s", dev->name); + if ((dev->handle = CreateFile(temp, + (GENERIC_READ|GENERIC_WRITE), + 0, + NULL, + OPEN_EXISTING, + FILE_FLAG_OVERLAPPED, + 0)) == INVALID_HANDLE_VALUE) { + ERRLOG("%s: open port: %i\n", dev->name, GetLastError()); + free(dev); return(NULL); } /* Create event handles. */ - pp->rov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); - pp->wov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + dev->rov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + dev->wov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); /* Set up buffer size of the port. */ - if (SetupComm(pp->handle, 32768L, 32768L) == FALSE) { - /* This fails on FTDI-based devices. */ - pclog("%s: set buffers: %d\n", pp->name, GetLastError()); -#if 0 - CloseHandle(pp->handle); - free(pp); - return(NULL); -#endif + if (SetupComm(dev->handle, 32768L, 32768L) == FALSE) { + /* This fails on FTDI-based devices, so, not fatal. */ + ERRLOG("%s: set buffers: %i\n", dev->name, GetLastError()); } /* Grab default config for the driver and set it. */ @@ -461,48 +466,44 @@ bhtty_open(char *port, int tmo) /* Change config here... */ /* Set new configuration. */ - if (SetCommConfig(pp->handle, &conf, d) == FALSE) { - /* This fails on FTDI-based devices. */ - pclog("%s: set configuration: %d\n", pp->name, GetLastError()); -#if 0 - CloseHandle(pp->handle); - free(pp); - return(NULL); -#endif + if (SetCommConfig(dev->handle, &conf, d) == FALSE) { + /* This fails on FTDI-based devices, so, not fatal. */ + ERRLOG("%s: set config: %i\n", dev->name, GetLastError()); } } - pclog("%s: host port '%s' open\n", pp->name, temp); + ERRLOG("%s: host port '%s' open\n", dev->name, temp); /* * We now have an open port. To allow for clean exit * of the application, we first retrieve the port's * current settings, and save these for later. */ - if (bhtty_gstate(pp, &pp->odcb) < 0) { - (void)bhtty_close(pp); + if (get_state(dev, &dev->odcb) < 0) { + plat_serial_close(dev); return(NULL); } - memcpy(&pp->dcb, &pp->odcb, sizeof(DCB)); + memcpy(&dev->dcb, &dev->odcb, sizeof(DCB)); /* Force the port to BINARY mode. */ - bhtty_raw(pp, &pp->dcb); + plat_serial_raw(dev, &dev->dcb); /* Set new state of this port. */ - if (bhtty_sstate(pp, &pp->dcb) < 0) { - (void)bhtty_close(pp); + if (set_state(dev, &dev->dcb) < 0) { + plat_serial_close(dev); return(NULL); } /* Just to make sure.. disable RTS/CTS mode. */ - (void)bhtty_crtscts(pp, 0); + set_crtscts(dev, 0); /* Set new timeout values. */ - if (GetCommTimeouts(pp->handle, &to) == FALSE) { - pclog("%s: error %d while getting current TO\n", - pp->name, GetLastError()); - (void)bhtty_close(pp); + if (GetCommTimeouts(dev->handle, &to) == FALSE) { + ERRLOG("%s: error %i while getting current TO\n", + dev->name, GetLastError()); + plat_serial_close(dev); return(NULL); } + if (tmo < 0) { /* No timeout, immediate return. */ to.ReadIntervalTimeout = MAXDWORD; @@ -517,34 +518,36 @@ bhtty_open(char *port, int tmo) to.ReadTotalTimeoutMultiplier = MAXDWORD; to.ReadTotalTimeoutConstant = tmo; } - if (SetCommTimeouts(pp->handle, &to) == FALSE) { - pclog("%s: error %d while setting TO\n", pp->name, GetLastError()); - (void)bhtty_close(pp); + if (SetCommTimeouts(dev->handle, &to) == FALSE) { + ERRLOG("%s: error %i while setting TO\n", dev->name, GetLastError()); + plat_serial_close(dev); return(NULL); } /* Clear all errors and flush all buffers. */ - if (bhtty_flush(pp) < 0) { - (void)bhtty_close(pp); + if (plat_serial_flush(dev) < 0) { + plat_serial_close(dev); return(NULL); } - return(pp); + return(dev); } -/* Activate the I/O for this port. */ +/* API: activate the I/O for this port. */ int -bhtty_active(BHTTY *pp, int flg) +plat_serial_active(void *arg, int flg) { + serial_t *dev = (serial_t *)arg; + if (flg) { - pclog("%s: starting thread..\n", pp->name); - pp->tid = thread_create(bhtty_reader, pp); + INFO("%s: starting thread..\n", dev->name); + dev->tid = thread_create(reader_thread, dev); } else { - if (pp->tid != NULL) { - pclog("%s: stopping thread..\n", pp->name); - thread_kill(pp->tid); - pp->tid = NULL; + if (dev->tid != NULL) { + INFO("%s: stopping thread..\n", dev->name); + thread_kill(dev->tid); + dev->tid = NULL; } } @@ -552,25 +555,26 @@ bhtty_active(BHTTY *pp, int flg) } -/* Try to write data to an open port. */ +/* API: try to write data to an open port. */ int -bhtty_write(BHTTY *pp, unsigned char val) +plat_serial_write(void *arg, unsigned char val) { + serial_t *dev = (serial_t *)arg; DWORD n = 0; -pclog("%s: writing byte %02x\n", pp->name, val); - if (WriteFile(pp->handle, &val, 1, &n, &pp->wov) == FALSE) { +pclog(0,"%s: writing byte %02x\n", dev->name, val); + if (WriteFile(dev->handle, &val, 1, &n, &dev->wov) == FALSE) { n = GetLastError(); if (n != ERROR_IO_PENDING) { /* Not good, we got an error. */ - pclog("%s: I/O error %d in write!\n", pp->name, n); + ERRLOG("%s: I/O error %i in write!\n", dev->name, n); return(-1); } /* The write is pending, wait for it.. */ - if (GetOverlappedResult(pp->handle, &pp->wov, &n, TRUE) == FALSE) { + if (GetOverlappedResult(dev->handle, &dev->wov, &n, TRUE) == FALSE) { n = GetLastError(); - pclog("%s: I/O error %d in write!\n", pp->name, n); + ERRLOG("%s: I/O error %i in write!\n", dev->name, n); return(-1); } } @@ -580,22 +584,24 @@ pclog("%s: writing byte %02x\n", pp->name, val); /* - * Try to read data from an open port. + * API: try to read data from an open port. * * For now, we will use one byte per call. Eventually, * we should go back to loading a buffer full of data, * just to speed things up a bit. --FvK */ int -bhtty_read(BHTTY *pp, unsigned char *bufp, int max) +plat_serial_read(void *arg, unsigned char *bufp, int max) { - if (pp->icnt == 0) return(0); + serial_t *dev = (serial_t *)arg; + + if (dev->icnt == 0) return(0); while (max-- > 0) { - *bufp++ = pp->buff[pp->itail++]; -pclog("%s: dequeued byte %02x (%d)\n", pp->name, *(bufp-1), pp->icnt); - pp->itail &= (sizeof(pp->buff)-1); - if (--pp->icnt == 0) break; + *bufp++ = dev->buff[dev->itail++]; +pclog(0,"%s: dequeued byte %02x (%i)\n", dev->name, *(bufp-1), dev->icnt); + dev->itail &= (sizeof(dev->buff)-1); + if (--dev->icnt == 0) break; } return(max);