diff --git a/src/CPU/386_ops.h b/src/CPU/386_ops.h index c1aa2ff66..71a6f1e4b 100644 --- a/src/CPU/386_ops.h +++ b/src/CPU/386_ops.h @@ -227,6 +227,17 @@ static int op0F_l_a32(uint32_t fetchdat) return x86_opcodes_0f[opcode | 0x300](fetchdat >> 8); } +static int opREP_ignore(uint32_t fetchdat) +{ + fetchdat = fastreadl(cs + cpu_state.pc); + if (cpu_state.abrt) return 0; + cpu_state.pc++; + + CLOCK_CYCLES((is486) ? 1 : 3); + PREFETCH_PREFIX(); + return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); +} + OpFn OP_TABLE(286_0f)[1024] = { /*16-bit data, 16-bit addr*/ @@ -1416,180 +1427,180 @@ OpFn OP_TABLE(REPE)[1024] = { /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*20*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opES_REPE_w_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCS_REPE_w_a16,ILLEGAL, -/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opSS_REPE_w_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opDS_REPE_w_a16,ILLEGAL, +/*00*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, +/*10*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, +/*20*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opES_REPE_w_a16,opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opCS_REPE_w_a16,opREP_ignore, +/*30*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opSS_REPE_w_a16,opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opDS_REPE_w_a16,opREP_ignore, -/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opFS_REPE_w_a16,opGS_REPE_w_a16,op_66_REPE, op_67_REPE, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opREP_INSB_a16, opREP_INSW_a16, opREP_OUTSB_a16,opREP_OUTSW_a16, -/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*40*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, +/*50*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, +/*60*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opFS_REPE_w_a16,opGS_REPE_w_a16,op_66_REPE, op_67_REPE, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_INSB_a16, opREP_INSW_a16, opREP_OUTSB_a16,opREP_OUTSW_a16, +/*70*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, -/*80*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*90*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*a0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opREP_MOVSB_a16,opREP_MOVSW_a16,opREP_CMPSB_a16_E,opREP_CMPSW_a16_E,ILLEGAL, ILLEGAL, opREP_STOSB_a16,opREP_STOSW_a16,opREP_LODSB_a16,opREP_LODSW_a16,opREP_SCASB_a16_E,opREP_SCASW_a16_E, -/*b0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*80*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, +/*90*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, +/*a0*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_MOVSB_a16,opREP_MOVSW_a16,opREP_CMPSB_a16_E,opREP_CMPSW_a16_E,opREP_ignore, opREP_ignore, opREP_STOSB_a16,opREP_STOSW_a16,opREP_LODSB_a16,opREP_LODSW_a16,opREP_SCASB_a16_E,opREP_SCASW_a16_E, +/*b0*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, -/*c0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*c0*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, +/*d0*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, +/*e0*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, +/*f0*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, /*32-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*20*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opES_REPE_l_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCS_REPE_l_a16,ILLEGAL, -/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opSS_REPE_l_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opDS_REPE_l_a16,ILLEGAL, +/*00*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, +/*10*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, +/*20*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opES_REPE_l_a16,opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opCS_REPE_l_a16,opREP_ignore, +/*30*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opSS_REPE_l_a16,opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opDS_REPE_l_a16,opREP_ignore, -/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opFS_REPE_l_a16,opGS_REPE_l_a16,op_66_REPE, op_67_REPE, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opREP_INSB_a16, opREP_INSL_a16, opREP_OUTSB_a16,opREP_OUTSL_a16, -/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*40*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, +/*50*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, +/*60*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opFS_REPE_l_a16,opGS_REPE_l_a16,op_66_REPE, op_67_REPE, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_INSB_a16, opREP_INSL_a16, opREP_OUTSB_a16,opREP_OUTSL_a16, +/*70*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, -/*80*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*90*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*a0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opREP_MOVSB_a16,opREP_MOVSL_a16,opREP_CMPSB_a16_E,opREP_CMPSL_a16_E,ILLEGAL, ILLEGAL, opREP_STOSB_a16,opREP_STOSL_a16,opREP_LODSB_a16,opREP_LODSL_a16,opREP_SCASB_a16_E,opREP_SCASL_a16_E, -/*b0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*80*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, +/*90*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, +/*a0*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_MOVSB_a16,opREP_MOVSL_a16,opREP_CMPSB_a16_E,opREP_CMPSL_a16_E,opREP_ignore, opREP_ignore, opREP_STOSB_a16,opREP_STOSL_a16,opREP_LODSB_a16,opREP_LODSL_a16,opREP_SCASB_a16_E,opREP_SCASL_a16_E, +/*b0*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, -/*c0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*c0*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, +/*d0*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, +/*e0*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, +/*f0*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, /*16-bit data, 32-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*20*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opES_REPE_w_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCS_REPE_w_a32,ILLEGAL, -/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opSS_REPE_w_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opDS_REPE_w_a32,ILLEGAL, +/*00*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, +/*10*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, +/*20*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opES_REPE_w_a32,opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opCS_REPE_w_a32,opREP_ignore, +/*30*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opSS_REPE_w_a32,opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opDS_REPE_w_a32,opREP_ignore, -/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opFS_REPE_w_a32,opGS_REPE_w_a32,op_66_REPE, op_67_REPE, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opREP_INSB_a32, opREP_INSW_a32, opREP_OUTSB_a32,opREP_OUTSW_a32, -/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*40*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, +/*50*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, +/*60*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opFS_REPE_w_a32,opGS_REPE_w_a32,op_66_REPE, op_67_REPE, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_INSB_a32, opREP_INSW_a32, opREP_OUTSB_a32,opREP_OUTSW_a32, +/*70*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, -/*80*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*90*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*a0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opREP_MOVSB_a32,opREP_MOVSW_a32,opREP_CMPSB_a32_E,opREP_CMPSW_a32_E,ILLEGAL, ILLEGAL, opREP_STOSB_a32,opREP_STOSW_a32,opREP_LODSB_a32,opREP_LODSW_a32,opREP_SCASB_a32_E,opREP_SCASW_a32_E, -/*b0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*80*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, +/*90*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, +/*a0*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_MOVSB_a32,opREP_MOVSW_a32,opREP_CMPSB_a32_E,opREP_CMPSW_a32_E,opREP_ignore, opREP_ignore, opREP_STOSB_a32,opREP_STOSW_a32,opREP_LODSB_a32,opREP_LODSW_a32,opREP_SCASB_a32_E,opREP_SCASW_a32_E, +/*b0*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, -/*c0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*c0*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, +/*d0*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, +/*e0*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, +/*f0*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, /*32-bit data, 32-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*20*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opES_REPE_l_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCS_REPE_l_a32,ILLEGAL, -/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opSS_REPE_l_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opDS_REPE_l_a32,ILLEGAL, +/*00*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, +/*10*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, +/*20*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opES_REPE_l_a32,opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opCS_REPE_l_a32,opREP_ignore, +/*30*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opSS_REPE_l_a32,opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opDS_REPE_l_a32,opREP_ignore, -/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opFS_REPE_l_a32,opGS_REPE_l_a32,op_66_REPE, op_67_REPE, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opREP_INSB_a32, opREP_INSL_a32, opREP_OUTSB_a32,opREP_OUTSL_a32, -/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*40*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, +/*50*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, +/*60*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opFS_REPE_l_a32,opGS_REPE_l_a32,op_66_REPE, op_67_REPE, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_INSB_a32, opREP_INSL_a32, opREP_OUTSB_a32,opREP_OUTSL_a32, +/*70*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, -/*80*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*90*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*a0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opREP_MOVSB_a32,opREP_MOVSL_a32,opREP_CMPSB_a32_E,opREP_CMPSL_a32_E,ILLEGAL, ILLEGAL, opREP_STOSB_a32,opREP_STOSL_a32,opREP_LODSB_a32,opREP_LODSL_a32,opREP_SCASB_a32_E,opREP_SCASL_a32_E, -/*b0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*80*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, +/*90*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, +/*a0*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_MOVSB_a32,opREP_MOVSL_a32,opREP_CMPSB_a32_E,opREP_CMPSL_a32_E,opREP_ignore, opREP_ignore, opREP_STOSB_a32,opREP_STOSL_a32,opREP_LODSB_a32,opREP_LODSL_a32,opREP_SCASB_a32_E,opREP_SCASL_a32_E, +/*b0*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, -/*c0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*c0*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, +/*d0*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, +/*e0*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, +/*f0*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, }; OpFn OP_TABLE(REPNE)[1024] = { /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*20*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opES_REPNE_w_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCS_REPNE_w_a16,ILLEGAL, -/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opSS_REPNE_w_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opDS_REPNE_w_a16,ILLEGAL, +/*00*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, +/*10*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, +/*20*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opES_REPNE_w_a16,opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opCS_REPNE_w_a16,opREP_ignore, +/*30*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opSS_REPNE_w_a16,opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opDS_REPNE_w_a16,opREP_ignore, -/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opFS_REPNE_w_a16,opGS_REPNE_w_a16,op_66_REPNE, op_67_REPNE, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opREP_INSB_a16, opREP_INSW_a16, opREP_OUTSB_a16,opREP_OUTSW_a16, -/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*40*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, +/*50*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, +/*60*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opFS_REPNE_w_a16,opGS_REPNE_w_a16,op_66_REPNE, op_67_REPNE, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_INSB_a16, opREP_INSW_a16, opREP_OUTSB_a16,opREP_OUTSW_a16, +/*70*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, -/*80*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*90*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*a0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opREP_MOVSB_a16,opREP_MOVSW_a16,opREP_CMPSB_a16_NE,opREP_CMPSW_a16_NE,ILLEGAL, ILLEGAL, opREP_STOSB_a16,opREP_STOSW_a16,opREP_LODSB_a16,opREP_LODSW_a16,opREP_SCASB_a16_NE,opREP_SCASW_a16_NE, -/*b0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*80*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, +/*90*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, +/*a0*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_MOVSB_a16,opREP_MOVSW_a16,opREP_CMPSB_a16_NE,opREP_CMPSW_a16_NE,opREP_ignore, opREP_ignore, opREP_STOSB_a16,opREP_STOSW_a16,opREP_LODSB_a16,opREP_LODSW_a16,opREP_SCASB_a16_NE,opREP_SCASW_a16_NE, +/*b0*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, -/*c0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*c0*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, +/*d0*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, +/*e0*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, +/*f0*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, /*32-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*20*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opES_REPNE_l_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCS_REPNE_l_a16,ILLEGAL, -/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opSS_REPNE_l_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opDS_REPNE_l_a16,ILLEGAL, +/*00*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, +/*10*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, +/*20*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opES_REPNE_l_a16,opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opCS_REPNE_l_a16,opREP_ignore, +/*30*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opSS_REPNE_l_a16,opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opDS_REPNE_l_a16,opREP_ignore, -/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opFS_REPNE_l_a16,opGS_REPNE_l_a16,op_66_REPNE, op_67_REPNE, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opREP_INSB_a16, opREP_INSL_a16, opREP_OUTSB_a16,opREP_OUTSL_a16, -/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*40*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, +/*50*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, +/*60*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opFS_REPNE_l_a16,opGS_REPNE_l_a16,op_66_REPNE, op_67_REPNE, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_INSB_a16, opREP_INSL_a16, opREP_OUTSB_a16,opREP_OUTSL_a16, +/*70*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, -/*80*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*90*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*a0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opREP_MOVSB_a16,opREP_MOVSL_a16,opREP_CMPSB_a16_NE,opREP_CMPSL_a16_NE,ILLEGAL, ILLEGAL, opREP_STOSB_a16,opREP_STOSL_a16,opREP_LODSB_a16,opREP_LODSL_a16,opREP_SCASB_a16_NE,opREP_SCASL_a16_NE, -/*b0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*80*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, +/*90*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, +/*a0*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_MOVSB_a16,opREP_MOVSL_a16,opREP_CMPSB_a16_NE,opREP_CMPSL_a16_NE,opREP_ignore, opREP_ignore, opREP_STOSB_a16,opREP_STOSL_a16,opREP_LODSB_a16,opREP_LODSL_a16,opREP_SCASB_a16_NE,opREP_SCASL_a16_NE, +/*b0*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, -/*c0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*c0*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, +/*d0*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, +/*e0*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, +/*f0*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, /*16-bit data, 32-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*20*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opES_REPNE_w_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCS_REPNE_w_a32,ILLEGAL, -/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opSS_REPNE_w_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opDS_REPNE_w_a32,ILLEGAL, +/*00*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, +/*10*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, +/*20*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opES_REPNE_w_a32,opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opCS_REPNE_w_a32,opREP_ignore, +/*30*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opSS_REPNE_w_a32,opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opDS_REPNE_w_a32,opREP_ignore, -/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opFS_REPNE_w_a32,opGS_REPNE_w_a32,op_66_REPNE, op_67_REPNE, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opREP_INSB_a32, opREP_INSW_a32, opREP_OUTSB_a32,opREP_OUTSW_a32, -/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*40*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, +/*50*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, +/*60*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opFS_REPNE_w_a32,opGS_REPNE_w_a32,op_66_REPNE, op_67_REPNE, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_INSB_a32, opREP_INSW_a32, opREP_OUTSB_a32,opREP_OUTSW_a32, +/*70*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, -/*80*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*90*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*a0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opREP_MOVSB_a32,opREP_MOVSW_a32,opREP_CMPSB_a32_NE,opREP_CMPSW_a32_NE,ILLEGAL, ILLEGAL, opREP_STOSB_a32,opREP_STOSW_a32,opREP_LODSB_a32,opREP_LODSW_a32,opREP_SCASB_a32_NE,opREP_SCASW_a32_NE, -/*b0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*80*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, +/*90*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, +/*a0*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_MOVSB_a32,opREP_MOVSW_a32,opREP_CMPSB_a32_NE,opREP_CMPSW_a32_NE,opREP_ignore, opREP_ignore, opREP_STOSB_a32,opREP_STOSW_a32,opREP_LODSB_a32,opREP_LODSW_a32,opREP_SCASB_a32_NE,opREP_SCASW_a32_NE, +/*b0*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, -/*c0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*c0*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, +/*d0*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, +/*e0*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, +/*f0*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, /*32-bit data, 32-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*20*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opES_REPNE_l_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCS_REPNE_l_a32,ILLEGAL, -/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opSS_REPNE_l_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opDS_REPNE_l_a32,ILLEGAL, +/*00*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, +/*10*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, +/*20*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opES_REPNE_l_a32,opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opCS_REPNE_l_a32,opREP_ignore, +/*30*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opSS_REPNE_l_a32,opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opDS_REPNE_l_a32,opREP_ignore, -/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opFS_REPNE_l_a32,opGS_REPNE_l_a32,op_66_REPNE, op_67_REPNE, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opREP_INSB_a32, opREP_INSL_a32, opREP_OUTSB_a32,opREP_OUTSL_a32, -/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*40*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, +/*50*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, +/*60*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opFS_REPNE_l_a32,opGS_REPNE_l_a32,op_66_REPNE, op_67_REPNE, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_INSB_a32, opREP_INSL_a32, opREP_OUTSB_a32,opREP_OUTSL_a32, +/*70*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, -/*80*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*90*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*a0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opREP_MOVSB_a32,opREP_MOVSL_a32,opREP_CMPSB_a32_NE,opREP_CMPSL_a32_NE,ILLEGAL, ILLEGAL, opREP_STOSB_a32,opREP_STOSL_a32,opREP_LODSB_a32,opREP_LODSL_a32,opREP_SCASB_a32_NE,opREP_SCASL_a32_NE, -/*b0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*80*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, +/*90*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, +/*a0*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_MOVSB_a32,opREP_MOVSL_a32,opREP_CMPSB_a32_NE,opREP_CMPSL_a32_NE,opREP_ignore, opREP_ignore, opREP_STOSB_a32,opREP_STOSL_a32,opREP_LODSB_a32,opREP_LODSL_a32,opREP_SCASB_a32_NE,opREP_SCASL_a32_NE, +/*b0*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, -/*c0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*c0*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, +/*d0*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, +/*e0*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, +/*f0*/ opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, opREP_ignore, }; diff --git a/src/NETWORK/network.c b/src/NETWORK/network.c index 87d2613ac..1534d047f 100644 --- a/src/NETWORK/network.c +++ b/src/NETWORK/network.c @@ -111,7 +111,7 @@ network_attach(void *dev, uint8_t *mac, NETRXCB rx) case NET_TYPE_PCAP: ret = network_pcap_setup(mac, rx, dev); if (ret < 0) { - plat_msgbox_error(IDS_2219); + plat_msgbox_error(IDS_2139); network_type = NET_TYPE_NONE; } break; diff --git a/src/SOUND/snd_emu8k.c b/src/SOUND/snd_emu8k.c index c9982de11..af4c7cbbf 100644 --- a/src/SOUND/snd_emu8k.c +++ b/src/SOUND/snd_emu8k.c @@ -3,6 +3,7 @@ freq = 2^((in - 0xe000) / 4096)*/ /*LFO - lowest (0.042 Hz) = 2^20 steps = 1048576 highest (10.72 Hz) = 2^12 steps = 4096*/ +#include #include #include #include "../ibm.h" @@ -14,92 +15,455 @@ #include "sound.h" #include "snd_emu8k.h" +#define FILTER_INITIAL +/* #define FILTER_MOOG */ +/* #define FILTER_CONSTANT */ + + +/* #define EMU8K_DEBUG_REGISTERS */ + +char *PORT_NAMES[][8]={ + /* Data 0 ( 0x620/0x622) */ + { /* Register 0 */ + "AWE_CPF", + /* Register 1 */ + "AWE_PTRX", + /* Register 2 */ + "AWE_CVCF", + /* Register 3 */ + "AWE_VTFT", + /* Register 4 */ + "Unk-620-4", + /* Register 5 */ + "Unk-620-5", + /* Register 6 */ + "AWE_PSST", + /* Register 7 */ + "AWE_CSL", + }, + /* Data 1 0xA20 */ + { /* Register 0 */ + "AWE_CCCA", + /* Register 1 */ + 0, + /* + * + "AWE_HWCF4" + "AWE_HWCF5" + "AWE_HWCF6" + "AWE_HWCF7" + "AWE_SMALR" + "AWE_SMARR" + "AWE_SMALW" + "AWE_SMARW" + "AWE_SMLD" + "AWE_SMRD" + "AWE_WC" + "AWE_HWCF1" + "AWE_HWCF2" + "AWE_HWCF3" + */ + /* Register 2 */ + 0, /* "AWE_INIT1", */ + /* Register 3 */ + 0, /* "AWE_INIT3", */ + /* Register 4 */ + "AWE_ENVVOL", + /* Register 5 */ + "AWE_DCYSUSV", + /* Register 6 */ + "AWE_ENVVAL", + /* Register 7 */ + "AWE_DCYSUS", + }, + /* Data 2 0xA22 */ + { /* Register 0 */ + "AWE_CCCA", + /* Register 1 */ + 0, + /* Register 2 */ + 0, /* "AWE_INIT2", */ + /* Register 3 */ + 0, /* "AWE_INIT4", */ + /* Register 4 */ + "AWE_ATKHLDV", + /* Register 5 */ + "AWE_LFO1VAL", + /* Register 6 */ + "AWE_ATKHLD", + /* Register 7 */ + "AWE_LFO2VAL", + }, + /* Data 3 0xE20 */ + { /* Register 0 */ + "AWE_IP", + /* Register 1 */ + "AWE_IFATN", + /* Register 2 */ + "AWE_PEFE", + /* Register 3 */ + "AWE_FMMOD", + /* Register 4 */ + "AWE_TREMFRQ", + /* Register 5 */ + "AWE_FM2FRQ2", + /* Register 6 */ + 0, + /* Register 7 */ + 0, + }, +}; enum { ENV_STOPPED = 0, - ENV_ATTACK = 1, - ENV_DECAY = 2, - ENV_SUSTAIN = 3, - ENV_RELEASE = 4 + ENV_DELAY = 1, + ENV_ATTACK = 2, + ENV_HOLD = 3, + /* ENV_DECAY = 4, */ + ENV_SUSTAIN = 5, + /* ENV_RELEASE = 6, */ + ENV_RAMP_DOWN = 7, + ENV_RAMP_UP = 8 }; + +static int random_helper = 0; +int dmareadbit = 0; +int dmawritebit = 0; + + +/* cubic and linear tables resolution. Note: higher than 10 does not improve the result. */ +#define CUBIC_RESOLUTION_LOG 10 +#define CUBIC_RESOLUTION (1<> 15 to move back to +/-1 range). */ +static int32_t lfotable[65536]; +/* Table to transform the speed parameter to emu8k_mem_internal_t range. */ +static int64_t lfofreqtospeed[256]; -#define READ16(addr, var) switch ((addr) & 2) \ + +/* these lines come from the awe32faq, describing the NRPN control for the initial filter + where it describes a linear increment filter instead of an octave-incremented one. + NRPN LSB 21 (Initial Filter Cutoff) + Range : [0, 127] + Unit : 62Hz + Filter cutoff from 100Hz to 8000Hz */ + +/* This table comes from the awe32faq, describing the NRPN control for the filter Q. + I don't know if is meant to be interpreted as the actual measured output of the + filter or what. Especially, I don't understand the "low" and "high" ranges. + What is otherwise documented is that the Q ranges from 0dB to 24dB and the attenuation + is half of the Q ( i.e. for 12dB Q, attenuate the input signal with -6dB) */ +/*InitialFilterCutoff = RegisterValue*31.25Hz+100Hz */ +/*Coeff Low Fc(Hz)Low Q(dB)High Fc(kHz)High Q(dB)DC Attenuation(dB) +0 92 5 Flat Flat -0.0 +1 93 6 8.5 0.5 -0.5 +2 94 8 8.3 1 -1.2 +3 95 10 8.2 2 -1.8 +4 96 11 8.1 3 -2.5 +5 97 13 8.0 4 -3.3 +6 98 14 7.9 5 -4.1 +7 99 16 7.8 6 -5.5 +8 100 17 7.7 7 -6.0 +9 100 19 7.5 9 -6.6 +10 100 20 7.4 10 -7.2 +11 100 22 7.3 11 -7.9 +12 100 23 7.2 13 -8.5 +13 100 25 7.1 15 -9.3 +14 100 26 7.1 16 -10.1 +15 100 28 7.0 18 -11.0 +*/ +/* Attenuation as above, codified in amplitude, and Q as in High Q. */ +static int32_t filter_atten[16] = { + 65536, 61869, 57079, 53269, 49145, 44820, 40877, 34792, 32845, 30653, 28607, + 26392, 24630, 22463, 20487, 18470 +}; + + +static int32_t filt_coeffs[16][256][3]; + +#define READ16_SWITCH(addr, var) switch ((addr) & 2) \ { \ case 0: ret = (var) & 0xffff; break; \ case 2: ret = ((var) >> 16) & 0xffff; break; \ } -#define WRITE16(addr, var, val) switch ((addr) & 2) \ +#define WRITE16_SWITCH(addr, var, val) switch ((addr) & 2) \ { \ case 0: var = (var & 0xffff0000) | (val); break; \ case 2: var = (var & 0x0000ffff) | ((val) << 16); break; \ } -static __inline int16_t EMU8K_READ(emu8k_t *emu8k, uint16_t addr) +#ifdef EMU8K_DEBUG_REGISTERS +uint32_t dw_value = 0; +uint32_t last_read = 0; +uint32_t last_write = 0; +uint32_t rep_count_r = 0; +uint32_t rep_count_w = 0; + +# define READ16(addr, var) READ16_SWITCH(addr, var) \ + if ((addr) & 2) { \ + const char *name=0; \ + switch(addr) { \ + case 0x620: case 0x622: \ + name = PORT_NAMES[0][emu8k->cur_reg]; \ + break; \ + case 0xA20: \ + name = PORT_NAMES[1][emu8k->cur_reg]; \ + break; \ + case 0xA22: \ + name = PORT_NAMES[2][emu8k->cur_reg]; \ + break; \ + } \ + if (name == 0) { \ + /*pclog("EMU8K READ %04X-%02X(%d): %04X\n",addr,(emu8k->cur_reg)<<5|emu8k->cur_voice, emu8k->cur_voice,ret);*/ \ + } else { \ + /*pclog("EMU8K READ %s (%d): %04X\n",name,emu8k->cur_voice, ret);*/ \ + }\ + } +# define WRITE16(addr, var, val) WRITE16_SWITCH(addr, var, val) \ + if ((addr) & 2) { \ + const char *name=0; \ + switch(addr) { \ + case 0x620: case 0x622: \ + name = PORT_NAMES[0][emu8k->cur_reg]; \ + break; \ + case 0xA20: \ + name = PORT_NAMES[1][emu8k->cur_reg]; \ + break; \ + case 0xA22: \ + name = PORT_NAMES[2][emu8k->cur_reg]; \ + break; \ + } \ + if (name == 0) { \ + /*pclog("EMU8K WRITE %04X-%02X(%d): %04X\n",addr,(emu8k->cur_reg)<<5|emu8k->cur_voice,emu8k->cur_voice, val);*/ \ + } else { \ + pclog("EMU8K WRITE %s (%d): %04X\n",name,emu8k->cur_voice, val); \ + }\ + } + +#else +# define READ16(addr, var) READ16_SWITCH(addr, var) +# define WRITE16(addr, var, val) WRITE16_SWITCH(addr, var, val) +#endif /* EMU8K_DEBUG_REGISTERS */ + + +static inline int16_t EMU8K_READ(emu8k_t *emu8k, uint32_t addr) +{ + const register emu8k_mem_pointers_t addrmem = {{addr}}; + return emu8k->ram_pointers[addrmem.hb_address][addrmem.lw_address]; +} + +static inline int16_t EMU8K_READ_INTERP_LINEAR(emu8k_t *emu8k, uint32_t int_addr, uint16_t fract) +{ + /* The interpolation in AWE32 used a so-called patented 3-point interpolation + ( I guess some sort of spline having one point before and one point after). + Also, it has the consequence that the playback is delayed by one sample. + I simulate the "one sample later" than the address with addr+1 and addr+2 + instead of +0 and +1 */ + int16_t dat1 = EMU8K_READ(emu8k, int_addr+1); + int32_t dat2 = EMU8K_READ(emu8k, int_addr+2); + dat1 += ((dat2-(int32_t)dat1)* fract) >> 16; + return dat1; +} + +static inline int16_t EMU8K_READ_INTERP_CUBIC(emu8k_t *emu8k, uint32_t int_addr, uint16_t fract) +{ +/* if ((addr & EMU8K_FM_MEM_ADDRESS) == EMU8K_FM_MEM_ADDRESS) { */ + /* TODO: I still have to verify how this works, but I think that + the card could use two oscillators (usually 31 and 32) where it would + be writing the OPL3 output, and to which, chorus and reverb could be applied to get + those effects for OPL3 sounds. */ +/* } */ + + /* This is cubic interpolation. + Not the same than 3-point interpolation, but a better approximation than linear + interpolation. + Also, it takes into account the "Note that the actual audio location is the point + 1 word higher than this value due to interpolation offset". + That's why the pointers are 0, 1, 2, 3 and not -1, 0, 1, 2 */ + int32_t dat2 = EMU8K_READ(emu8k, int_addr+1); + if (fract) { + const int32_t *table = &cubic_table[fract>>(16-CUBIC_RESOLUTION_LOG)]; + const int32_t dat1 = EMU8K_READ(emu8k, int_addr); + const int32_t dat3 = EMU8K_READ(emu8k, int_addr+2); + const int32_t dat4 = EMU8K_READ(emu8k, int_addr+3); + /* 16bit*16bit and back to 16bit. (using >> 15 because the table is signed integer) + Warning: there exists the possibility of interger overflow. */ + dat2 = (int16_t)((dat1*table[0] + dat2*table[1] + dat3*table[2] + dat4*table[3]) >> 15); + } + return dat2; +} + +static inline void EMU8K_WRITE(emu8k_t *emu8k, uint32_t addr, uint16_t val) { addr &= EMU8K_MEM_ADDRESS_MASK; - /* TODO: I've read that the AWE64 Gold model had a 4MB Rom. It would be interesting - to find that rom and do some tests with it. */ - if (addr < EMU8K_ROM_MEM_1MB_END) - return emu8k->rom[addr]; - if (addr < EMU8K_RAM_MEM_START || addr >= emu8k->ram_end_addr) - return 0; - if (!emu8k->ram) - return 0; - return emu8k->ram[addr - EMU8K_RAM_MEM_START]; -} - -static __inline int16_t EMU8K_READ_INTERP(emu8k_t *emu8k, uint16_t addr) -{ - int16_t dat1 = EMU8K_READ(emu8k, addr >> 8); - int16_t dat2 = EMU8K_READ(emu8k, (addr >> 8) + 1); - return ((dat1 * (0xff - (addr & 0xff))) + (dat2 * (addr & 0xff))) >> 8; -} - -static __inline void EMU8K_WRITE(emu8k_t *emu8k, uint16_t addr, uint16_t val) -{ - if ( !emu8k->ram || addr < EMU8K_RAM_MEM_START) + if ( !emu8k->ram || addr < EMU8K_RAM_MEM_START || addr >= EMU8K_FM_MEM_ADDRESS ) return; - /* It looks like if an application writes to a memory part outside of the available amount on the card, - it wraps, and opencubicplayer uses that to detect the amount of memory, as opposed to simply check - at the address that it has just tried to write. */ - addr &= EMU8K_MEM_ADDRESS_MASK; + /* It looks like if an application writes to a memory part outside of the available + amount on the card, it wraps, and opencubicplayer uses that to detect the amount + of memory, as opposed to simply check at the address that it has just tried to write. */ while (addr >= emu8k->ram_end_addr) { addr -= emu8k->ram_end_addr - EMU8K_RAM_MEM_START; } emu8k->ram[addr - EMU8K_RAM_MEM_START] = val; } -static int ff = 0; - uint16_t emu8k_inw(uint16_t addr, void *p) { emu8k_t *emu8k = (emu8k_t *)p; uint16_t ret = 0xffff; -/* pclog("emu8k_inw %04X reg=%i voice=%i\n", addr, emu8k->cur_reg, emu8k->cur_voice);*/ - addr -= 0x220; - switch (addr & 0xc02) +#ifdef EMU8K_DEBUG_REGISTERS + if (addr == 0xE22) { + pclog("EMU8K READ POINTER: %d\n", + ((0x80 | ((random_helper + 1) & 0x1F)) << 8) | (emu8k->cur_reg << 5) | emu8k->cur_voice); + } else if ((addr&0xF00) == 0x600) { + /* These are automatically reported by READ16 */ + } else if ((addr&0xF00) == 0xA00 && emu8k->cur_reg == 0) { + /* These are automatically reported by READ16 */ + } else if ((addr&0xF00) == 0xA00 && emu8k->cur_reg == 1) { + uint32_t tmpz = ((addr&0xF00) << 16)|(emu8k->cur_reg<<5); + if (tmpz != last_read) { + if (rep_count_r>1) { + pclog("EMU8K ...... for %d times\n", rep_count_r); + rep_count_r=0; + } + last_read=tmpz; + pclog("EMU8K READ RAM I/O or configuration or clock \n"); + } + } + else if ((addr&0xF00) == 0xA00 && (emu8k->cur_reg == 2 || emu8k->cur_reg == 3)) { + uint32_t tmpz = ((addr&0xF00) << 16); + if (tmpz != last_read) { + if (rep_count_r>1) { + pclog("EMU8K ...... for %d times\n", rep_count_r); + rep_count_r=0; + } + last_read=tmpz; + pclog("EMU8K READ INIT \n"); + } + } + else { + uint32_t tmpz = (addr << 16)|(emu8k->cur_reg<<5)| emu8k->cur_voice; + if (tmpz != last_read) { + char* name = 0; + uint16_t val = 0xBAAD; + if (addr == 0xA20) { + name = PORT_NAMES[1][emu8k->cur_reg]; + switch (emu8k->cur_reg) + { + case 2: val = emu8k->init1[emu8k->cur_voice]; break; + case 3: val = emu8k->init3[emu8k->cur_voice]; break; + case 4: val = emu8k->voice[emu8k->cur_voice].envvol; break; + case 5: val = emu8k->voice[emu8k->cur_voice].dcysusv; break; + case 6: val = emu8k->voice[emu8k->cur_voice].envval; break; + case 7: val = emu8k->voice[emu8k->cur_voice].dcysus; break; + } + } + if (addr == 0xA22) { + name = PORT_NAMES[2][emu8k->cur_reg]; + switch (emu8k->cur_reg) + { + case 2: val = emu8k->init2[emu8k->cur_voice]; break; + case 3: val = emu8k->init4[emu8k->cur_voice]; break; + case 4: val = emu8k->voice[emu8k->cur_voice].atkhldv; break; + case 5: val = emu8k->voice[emu8k->cur_voice].lfo1val; break; + case 6: val = emu8k->voice[emu8k->cur_voice].atkhld; break; + case 7: val = emu8k->voice[emu8k->cur_voice].lfo2val; break; + } + } + if (addr == 0xE20) { + name = PORT_NAMES[3][emu8k->cur_reg]; + switch (emu8k->cur_reg) + { + case 0: val = emu8k->voice[emu8k->cur_voice].ip; break; + case 1: val = emu8k->voice[emu8k->cur_voice].ifatn; break; + case 2: val = emu8k->voice[emu8k->cur_voice].pefe; break; + case 3: val = emu8k->voice[emu8k->cur_voice].fmmod; break; + case 4: val = emu8k->voice[emu8k->cur_voice].tremfrq; break; + case 5: val = emu8k->voice[emu8k->cur_voice].fm2frq2;break; + case 6: val = 0xffff; break; + case 7: val = 0x1c | ((emu8k->id & 0x0002) ? 0xff02 : 0); break; + } + + } + if (rep_count_r>1) { + pclog("EMU8K ...... for %d times\n", rep_count_r); + } + if (name == 0) { + pclog("EMU8K READ %04X-%02X(%d/%d): %04X\n",addr,(emu8k->cur_reg)<<5|emu8k->cur_voice, emu8k->cur_reg, emu8k->cur_voice,val); + } + + rep_count_r=0; + last_read=tmpz; + } + rep_count_r++; + } +#endif /* EMU8K_DEBUG_REGISTERS */ + + + switch (addr & 0xF02) { - case 0x400: case 0x402: /*Data0*/ + case 0x600: case 0x602: /*Data0*/ /* also known as BLASTER+0x400 and EMU+0x000 */ switch (emu8k->cur_reg) { case 0: - { - uint32_t var = (emu8k->voice[emu8k->cur_voice].cpf & 0xFFFF0000) | ((emu8k->voice[emu8k->cur_voice].addr >> 16) & 0xFFFF); - READ16(addr, var); - return ret; - } + READ16(addr, emu8k->voice[emu8k->cur_voice].cpf); + return ret; case 1: READ16(addr, emu8k->voice[emu8k->cur_voice].ptrx); @@ -113,8 +477,13 @@ uint16_t emu8k_inw(uint16_t addr, void *p) READ16(addr, emu8k->voice[emu8k->cur_voice].vtft); return ret; - case 4: case 5: /*???*/ - return 0xffff; + case 4: + READ16(addr, emu8k->voice[emu8k->cur_voice].unknown_data0_4); + return ret; + + case 5: + READ16(addr, emu8k->voice[emu8k->cur_voice].unknown_data0_5); + return ret; case 6: READ16(addr, emu8k->voice[emu8k->cur_voice].psst); @@ -126,20 +495,30 @@ uint16_t emu8k_inw(uint16_t addr, void *p) } break; - case 0x800: /*Data1*/ + case 0xA00: /*Data1*/ /* also known as BLASTER+0x800 and EMU+0x400 */ switch (emu8k->cur_reg) { case 0: - { - emu8k->voice[emu8k->cur_voice].ccca = - (emu8k->voice[emu8k->cur_voice].ccca & 0xFF000000) | ((emu8k->voice[emu8k->cur_voice].addr >> 32) & EMU8K_MEM_ADDRESS_MASK); - READ16(addr, emu8k->voice[emu8k->cur_voice].ccca); - return ret; - } + READ16(addr, emu8k->voice[emu8k->cur_voice].ccca); + return ret; case 1: switch (emu8k->cur_voice) { + case 9: + READ16(addr, emu8k->hwcf4); + return ret; + case 10: + READ16(addr, emu8k->hwcf5); + return ret; + /* Actually, these two might be command words rather than registers, or some LFO position/buffer reset. */ + case 13: + READ16(addr, emu8k->hwcf6); + return ret; + case 14: + READ16(addr, emu8k->hwcf7); + return ret; + case 20: READ16(addr, emu8k->smalr); return ret; @@ -157,10 +536,10 @@ uint16_t emu8k_inw(uint16_t addr, void *p) { uint16_t val = emu8k->smld_buffer; emu8k->smld_buffer = EMU8K_READ(emu8k, emu8k->smalr); -/* pclog("emu8k_SMLR in %04X (%04X) %08X\n", val, emu8k->smld_buffer, emu8k->smalr);*/ - emu8k->smalr++; + emu8k->smalr = (emu8k->smalr+1) & EMU8K_MEM_ADDRESS_MASK; return val; } + /*The EMU8000 PGM describes the return values of these registers as 'a VLSI error'*/ case 29: /*Configuration Word 1*/ return (emu8k->hwcf1 & 0xfe) | (emu8k->hwcf3 & 0x01); @@ -171,69 +550,108 @@ uint16_t emu8k_inw(uint16_t addr, void *p) } break; - case 2: /*INIT1*/ - case 3: /*INIT3*/ - return 0xffff; /*Can we read anything useful from here?*/ + case 2: + return emu8k->init1[emu8k->cur_voice]; + case 3: + return emu8k->init3[emu8k->cur_voice]; + + case 4: + return emu8k->voice[emu8k->cur_voice].envvol; + case 5: return emu8k->voice[emu8k->cur_voice].dcysusv; + + case 6: + return emu8k->voice[emu8k->cur_voice].envval; case 7: return emu8k->voice[emu8k->cur_voice].dcysus; } break; - case 0x802: /*Data2*/ + case 0xA02: /*Data2*/ /* also known as BLASTER+0x802 and EMU+0x402 */ switch (emu8k->cur_reg) { case 0: - { - READ16(addr, emu8k->voice[emu8k->cur_voice].ccca); - return ret; - } + READ16(addr, emu8k->voice[emu8k->cur_voice].ccca); + return ret; case 1: switch (emu8k->cur_voice) { + case 9: + READ16(addr, emu8k->hwcf4); + return ret; + case 10: + READ16(addr, emu8k->hwcf5); + return ret; + /* Actually, these two might be command words rather than registers, or some LFO position/buffer reset. */ + case 13: + READ16(addr, emu8k->hwcf6); + return ret; + case 14: + READ16(addr, emu8k->hwcf7); + return ret; + + /* Simulating empty/full bits by unsetting it once read. */ case 20: - READ16(addr, emu8k->smalr | ff); - ff ^= 0x80000000; + READ16(addr, emu8k->smalr|dmareadbit); + /* xor with itself to set to zero faster. */ + dmareadbit^=dmareadbit; return ret; case 21: - READ16(addr, emu8k->smarr | ff); - ff ^= 0x80000000; + READ16(addr, emu8k->smarr|dmareadbit); + /* xor with itself to set to zero faster. */ + dmareadbit^=dmareadbit; return ret; case 22: - READ16(addr, emu8k->smalw); + READ16(addr, emu8k->smalw|dmawritebit); + /* xor with itself to set to zero faster. */ + dmawritebit^=dmawritebit; return ret; case 23: - READ16(addr, emu8k->smarw); + READ16(addr, emu8k->smarw|dmawritebit); + /* xor with itself to set to zero faster. */ + dmawritebit^=dmawritebit; return ret; case 26: { uint16_t val = emu8k->smrd_buffer; emu8k->smrd_buffer = EMU8K_READ(emu8k, emu8k->smarr); -/* pclog("emu8k_SMRR in %04X (%04X) %08X\n", val, emu8k->smrd_buffer, emu8k->smarr);*/ - emu8k->smarr++; + emu8k->smarr = (emu8k->smarr+1) & EMU8K_MEM_ADDRESS_MASK; return val; } - - case 27: /*Sample Counter*/ + /*TODO: We need to improve the precision of this clock, since + it is used by programs to wait. Not critical, but should help reduce + the amount of calls and wait time */ + case 27: /*Sample Counter ( 44Khz clock) */ return emu8k->wc; } break; - case 2: /*INIT2*/ - case 3: /*INIT4*/ - return 0xffff; /*Can we read anything useful from here?*/ + case 2: + return emu8k->init2[emu8k->cur_voice]; + + case 3: + return emu8k->init4[emu8k->cur_voice]; case 4: return emu8k->voice[emu8k->cur_voice].atkhldv; + + case 5: + return emu8k->voice[emu8k->cur_voice].lfo1val; + + case 6: + return emu8k->voice[emu8k->cur_voice].atkhld; + + case 7: + return emu8k->voice[emu8k->cur_voice].lfo2val; } break; - case 0xc00: /*Data3*/ + case 0xE00: /*Data3*/ /* also known as BLASTER+0xC00 and EMU+0x800 */ switch (emu8k->cur_reg) { case 0: @@ -261,34 +679,96 @@ uint16_t emu8k_inw(uint16_t addr, void *p) return 0x1c | ((emu8k->id & 0x0002) ? 0xff02 : 0); } break; - case 0xc02: + + case 0xE02: /* Pointer */ /* also known as BLASTER+0xC02 and EMU+0x802 */ /* LS five bits = channel number, next 3 bits = register number and MS 8 bits = VLSI test register. - Impulse tracker tests the non variability of the LS byte and the variability - of the MS byte to determine that it really is an AWE32. */ - return ((rand()&0xFF) << 8) | (emu8k->cur_reg << 5) | emu8k->cur_voice; + Impulse tracker tests the non variability of the LS byte that it has set, and the variability + of the MS byte to determine that it really is an AWE32. + cubic player has a similar code, where it waits until value & 0x1000 is nonzero, and then waits again until it changes to zero. */ + random_helper = (random_helper + 1) & 0x1F; + return ((0x80 | random_helper) << 8) | (emu8k->cur_reg << 5) | emu8k->cur_voice; } -/* fatal("Bad EMU8K inw from %08X\n", addr);*/ + pclog("EMU8K READ : Unknown register read: %04X-%02X(%d/%d) \n", addr, (emu8k->cur_reg << 5) | emu8k->cur_voice, emu8k->cur_reg, emu8k->cur_voice); return 0xffff; } void emu8k_outw(uint16_t addr, uint16_t val, void *p) { - float q; emu8k_t *emu8k = (emu8k_t *)p; + /* TODO: I would like to not call this here, but i found it was needed or else cubic player would not finish opening (take a looot more of time than usual). + Basically, being here means that the audio is generated in the emulation thread, instead of the audio thread. */ emu8k_update(emu8k); -/* pclog("emu8k_outw : addr=%08X reg=%i voice=%i val=%04X\n", addr, emu8k->cur_reg, emu8k->cur_voice, val);*/ - addr -= 0x220; - switch (addr & 0xc02) + +#ifdef EMU8K_DEBUG_REGISTERS + if (addr == 0xE22) { + /* pclog("EMU8K WRITE POINTER: %d\n", val); */ + } else if ((addr&0xF00) == 0x600) { + /* These are automatically reported by WRITE16 */ + } else if ((addr&0xF00) == 0xA00 && emu8k->cur_reg == 0) { + /* These are automatically reported by WRITE16 */ + } else if ((addr&0xF00) == 0xA00 && emu8k->cur_reg == 1) { + uint32_t tmpz = ((addr&0xF00) << 16)|(emu8k->cur_reg<<5); + if (tmpz != last_write) { + if (rep_count_w>1) { + pclog("EMU8K ...... for %d times\n", rep_count_w); + rep_count_w=0; + } + last_write=tmpz; + pclog("EMU8K WRITE RAM I/O or configuration \n"); + } + } + else if ((addr&0xF00) == 0xA00 && (emu8k->cur_reg == 2 || emu8k->cur_reg == 3)) { + uint32_t tmpz = ((addr&0xF00) << 16); + if (tmpz != last_write) { + if (rep_count_w>1) { + pclog("EMU8K ...... for %d times\n", rep_count_w); + rep_count_w=0; + } + last_write=tmpz; + pclog("EMU8K WRITE INIT \n"); + } + } + else if (addr != 0xE22) { + uint32_t tmpz = (addr << 16)|(emu8k->cur_reg<<5)| emu8k->cur_voice; + if (tmpz != last_write) { + char* name = 0; + if (addr == 0xA20) { + name = PORT_NAMES[1][emu8k->cur_reg]; + } + else if (addr == 0xA22) { + name = PORT_NAMES[2][emu8k->cur_reg]; + } + else if (addr == 0xE20) { + name = PORT_NAMES[3][emu8k->cur_reg]; + } + + if (rep_count_w>1) { + pclog("EMU8K ...... for %d times\n", rep_count_w); + } + if (name == 0) { + pclog("EMU8K WRITE %04X-%02X(%d/%d): %04X\n",addr,(emu8k->cur_reg)<<5|emu8k->cur_voice,emu8k->cur_reg,emu8k->cur_voice, val); + } else { + pclog("EMU8K WRITE %s (%d): %04X\n",name,emu8k->cur_voice, val); \ + } + + rep_count_w=0; + last_write=tmpz; + } + rep_count_w++; + } +#endif /* EMU8K_DEBUG_REGISTERS */ + + + switch (addr & 0xF02) { - case 0x400: case 0x402: /*Data0*/ + case 0x600: case 0x602: /*Data0*/ switch (emu8k->cur_reg) { case 0: WRITE16(addr, emu8k->voice[emu8k->cur_voice].cpf, val); - /* Ignoring any effect over writing to the "fractional address". The docs says that this value is constantly - updating, so it has no actual effect. */ + /* The docs says that this value is constantly updating, and it should have no actual effect. Actions should be done over ptrx */ return; case 1: @@ -297,46 +777,69 @@ void emu8k_outw(uint16_t addr, uint16_t val, void *p) case 2: WRITE16(addr, emu8k->voice[emu8k->cur_voice].cvcf, val); + /* The docs says that this value is constantly updating, and it should have no actual effect. Actions should be done over vtft */ return; case 3: WRITE16(addr, emu8k->voice[emu8k->cur_voice].vtft, val); return; + case 4: + WRITE16(addr, emu8k->voice[emu8k->cur_voice].unknown_data0_4, val); + return; + + case 5: + WRITE16(addr, emu8k->voice[emu8k->cur_voice].unknown_data0_5, val); + return; + case 6: - WRITE16(addr, emu8k->voice[emu8k->cur_voice].psst, val); - /* TODO: Should we update only on MSB update, or this could be used as some sort of hack by applications? */ - emu8k->voice[emu8k->cur_voice].loop_start = (uint64_t)(emu8k->voice[emu8k->cur_voice].psst & EMU8K_MEM_ADDRESS_MASK) << 32; - if (addr & 2) { - emu8k->voice[emu8k->cur_voice].vol_l = val >> 8; - emu8k->voice[emu8k->cur_voice].vol_r = 255 - (val >> 8); + emu8k_voice_t *emu_voice = &emu8k->voice[emu8k->cur_voice]; + WRITE16(addr, emu_voice->psst, val); + /* TODO: Should we update only on MSB update, or this could be used as some sort of hack by applications? */ + emu_voice->loop_start.int_address = emu_voice->psst & EMU8K_MEM_ADDRESS_MASK; + if (addr & 2) + { + emu_voice->vol_l = emu_voice->psst_pan; + emu_voice->vol_r = 255 - (emu_voice->psst_pan); + } } -/* pclog("emu8k_outl : write PSST %08X l %i r %i\n", emu8k->voice[emu8k->cur_voice].psst, emu8k->voice[emu8k->cur_voice].vol_l, emu8k->voice[emu8k->cur_voice].vol_r);*/ return; case 7: WRITE16(addr, emu8k->voice[emu8k->cur_voice].csl, val); /* TODO: Should we update only on MSB update, or this could be used as some sort of hack by applications? */ - emu8k->voice[emu8k->cur_voice].loop_end = (uint64_t)(emu8k->voice[emu8k->cur_voice].csl & EMU8K_MEM_ADDRESS_MASK) << 32; -/* pclog("emu8k_outl : write CSL %08X\n", emu8k->voice[emu8k->cur_voice].csl);*/ + emu8k->voice[emu8k->cur_voice].loop_end.int_address = emu8k->voice[emu8k->cur_voice].csl & EMU8K_MEM_ADDRESS_MASK; return; } break; - case 0x800: /*Data1*/ + case 0xA00: /*Data1*/ switch (emu8k->cur_reg) { case 0: WRITE16(addr, emu8k->voice[emu8k->cur_voice].ccca, val); /* TODO: Should we update only on MSB update, or this could be used as some sort of hack by applications? */ - emu8k->voice[emu8k->cur_voice].addr = (uint64_t)(emu8k->voice[emu8k->cur_voice].ccca & EMU8K_MEM_ADDRESS_MASK) << 32; -/* pclog("emu8k_outl : write CCCA %08X\n", emu8k->voice[emu8k->cur_voice].ccca);*/ + emu8k->voice[emu8k->cur_voice].addr.int_address = emu8k->voice[emu8k->cur_voice].ccca & EMU8K_MEM_ADDRESS_MASK; return; case 1: switch (emu8k->cur_voice) { + case 9: + WRITE16(addr, emu8k->hwcf4, val); + return; + case 10: + WRITE16(addr, emu8k->hwcf5, val); + return; + /* Actually, these two might be command words rather than registers, or some LFO position/buffer reset. */ + case 13: + WRITE16(addr, emu8k->hwcf6, val); + return; + case 14: + WRITE16(addr, emu8k->hwcf7, val); + return; + case 20: WRITE16(addr, emu8k->smalr, val); return; @@ -352,149 +855,361 @@ void emu8k_outw(uint16_t addr, uint16_t val, void *p) case 26: EMU8K_WRITE(emu8k, emu8k->smalw, val); -/* pclog("emu8k_SMLW %04X %08X\n", val, emu8k->smalw);*/ -/* if (val = 0xffff && emu8k->smalw == 0x200000) - output = 3;*/ - emu8k->smalw++; - break; + emu8k->smalw = (emu8k->smalw+1) & EMU8K_MEM_ADDRESS_MASK; + return; - case 29: /*Configuration Word 1*/ + case 29: emu8k->hwcf1 = val; return; - case 30: /*Configuration Word 2*/ + case 30: emu8k->hwcf2 = val; return; - case 31: /*Configuration Word 3*/ + case 31: emu8k->hwcf3 = val; return; } break; - case 5: -/* pclog("emu8k_outw : write DCYSUSV %04X\n", val);*/ - emu8k->voice[emu8k->cur_voice].dcysusv = val; - emu8k->voice[emu8k->cur_voice].env_sustain = (((val >> 8) & 0x7f) << 5) << 9; - if (val & 0x8000) /*Release*/ - { - emu8k->voice[emu8k->cur_voice].env_state = ENV_RELEASE; - emu8k->voice[emu8k->cur_voice].env_release = val & 0x7f; - } - else /*Decay*/ - emu8k->voice[emu8k->cur_voice].env_decay = val & 0x7f; - if (val & 0x80) - emu8k->voice[emu8k->cur_voice].env_state = ENV_STOPPED; + /* TODO: Read Reverb, Chorus and equalizer setups */ + case 2: + emu8k->init1[emu8k->cur_voice] = val; return; - case 7: -/* pclog("emu8k_outw : write DCYSUS %04X\n", val);*/ - emu8k->voice[emu8k->cur_voice].dcysus = val; - emu8k->voice[emu8k->cur_voice].menv_sustain = (((val >> 8) & 0x7f) << 5) << 9; - if (val & 0x8000) /*Release*/ - { - emu8k->voice[emu8k->cur_voice].menv_state = ENV_RELEASE; - emu8k->voice[emu8k->cur_voice].menv_release = val & 0x7f; + case 3: + emu8k->init3[emu8k->cur_voice] = val; + if (emu8k->init1[0] != 0x03FF) { + /* If not in initialization, configure chorus */ + if (emu8k->cur_voice == 9) { + emu8k->chorus_engine.feedback = (val&0xFF); + } + else if (emu8k->cur_voice == 12) { + emu8k->chorus_engine.delay_samples_central = val; + } + } + return; + + case 4: + emu8k->voice[emu8k->cur_voice].envvol = val; + emu8k->voice[emu8k->cur_voice].vol_envelope.delay_samples = ENVVOL_TO_EMU_SAMPLES(val); + return; + + case 5: + { + emu8k->voice[emu8k->cur_voice].dcysusv = val; + emu8k_envelope_t * const vol_env = &emu8k->voice[emu8k->cur_voice].vol_envelope; + emu8k->voice[emu8k->cur_voice].env_engine_on = DCYSUSV_GENERATOR_ENGINE_ON(val); + + /* Converting the input in dBs to envelope value range. */ + vol_env->sustain_value_db_oct = DCYSUSV_SUS_TO_ENV_RANGE(DCYSUSV_SUSVALUE_GET(val)); + vol_env->ramp_amount_db_oct = env_decay_to_dbs_or_oct[DCYSUSV_DECAYRELEASE_GET(val)]; + if (DCYSUSV_IS_RELEASE(val)) + { + if (vol_env->state == ENV_DELAY || vol_env->state == ENV_ATTACK || vol_env->state == ENV_HOLD) { + vol_env->value_db_oct = env_vol_amplitude_to_db[vol_env->value_amp_hz >> 5] << 5; + if (vol_env->value_db_oct > (1 << 21)) { + vol_env->value_db_oct = 1 << 21; + } + } + + vol_env->state = (vol_env->value_db_oct >= vol_env->sustain_value_db_oct) ? ENV_RAMP_DOWN : ENV_RAMP_UP; + } + } + return; + + case 6: + emu8k->voice[emu8k->cur_voice].envval = val; + emu8k->voice[emu8k->cur_voice].mod_envelope.delay_samples = ENVVAL_TO_EMU_SAMPLES(val); + return; + + case 7: + { + emu8k->voice[emu8k->cur_voice].dcysus = val; + emu8k_envelope_t* const mod_env = &emu8k->voice[emu8k->cur_voice].mod_envelope; + mod_env->sustain_value_db_oct = DCYSUS_SUS_TO_ENV_RANGE(DCYSUS_SUSVALUE_GET(val)); + mod_env->ramp_amount_db_oct = env_decay_to_dbs_or_oct[DCYSUS_DECAYRELEASE_GET(val)]; + if (DCYSUS_IS_RELEASE(val)) + { + if (mod_env->state == ENV_DELAY || mod_env->state == ENV_ATTACK || mod_env->state == ENV_HOLD) { + mod_env->value_db_oct = env_mod_hertz_to_octave[mod_env->value_amp_hz >> 9] << 9; + if (mod_env->value_db_oct >= (1 << 21)) { + mod_env->value_db_oct = (1 << 21)-1; + } + } + + mod_env->state = (mod_env->value_db_oct >= mod_env->sustain_value_db_oct) ? ENV_RAMP_DOWN : ENV_RAMP_UP; + } } - else /*Decay*/ - emu8k->voice[emu8k->cur_voice].menv_decay = val & 0x7f; - if (val & 0x80) - emu8k->voice[emu8k->cur_voice].menv_state = ENV_STOPPED; return; } break; - case 0x802: /*Data2*/ + case 0xA02: /*Data2*/ switch (emu8k->cur_reg) { case 0: { - WRITE16(addr, emu8k->voice[emu8k->cur_voice].ccca, val); - emu8k->voice[emu8k->cur_voice].addr = (uint64_t)(emu8k->voice[emu8k->cur_voice].ccca & EMU8K_MEM_ADDRESS_MASK) << 32; - /* TODO: Since "fractional address" is a separate register (cpf), should we add its contents to .addr or we assume that it - is reset to zero? */ - - q = (float)(emu8k->voice[emu8k->cur_voice].ccca >> 28) / 15.0f; - q /= 10.0f; /*Horrible and wrong hack*/ - emu8k->voice[emu8k->cur_voice].q = (int32_t)((1.0f / (0.707f + q)) * 256.0f); - -/* pclog("emu8k_outl : write CCCA %08X Q %f invQ %X\n", emu8k->voice[emu8k->cur_voice].ccca, q, emu8k->voice[emu8k->cur_voice].q);*/ + emu8k_voice_t *emu_voice = &emu8k->voice[emu8k->cur_voice]; + WRITE16(addr, emu_voice->ccca, val); + emu_voice->addr.int_address = emu_voice->ccca & EMU8K_MEM_ADDRESS_MASK; + uint32_t paramq = CCCA_FILTQ_GET(emu_voice->ccca); + emu_voice->filt_att = filter_atten[paramq]; + emu_voice->filterq_idx = paramq; } return; case 1: switch (emu8k->cur_voice) { - case 20: - WRITE16(addr, emu8k->smalr, val); + case 9: + WRITE16(addr, emu8k->hwcf4, val); + emu8k->chorus_engine.delay_offset_samples_right.addr = emu8k->hwcf4<<24; /* (1/256th of a 44Khz sample) */ return; - case 21: - WRITE16(addr, emu8k->smarr, val); + case 10: + { + WRITE16(addr, emu8k->hwcf5, val); + /* The scale of this value is unknown. I've taken it as milliHz. + Another interpretation could be periods. (and so, Hz = 1/period) */ + double osc_speed = emu8k->hwcf5; +#if 1 /* milliHz */ + /* milliHz to lfotable samples. */ + osc_speed *= 65.536/44100.0; +#elif 0 /* periods */ + osc_speed = 1.0/osc_speed; + /* Hz to lfotable samples. */ + osc_speed *= 65536/44100.0; +#endif + /* left shift 32bits for 32.32 fixed.point */ + osc_speed *= 65536.0*65536.0; + emu8k->chorus_engine.lfo_inc.addr = (uint64_t)osc_speed; + } return; - case 22: - WRITE16(addr, emu8k->smalw, val); + /* Actually, these two might be command words rather than registers, or some LFO position/buffer reset. */ + case 13: + WRITE16(addr, emu8k->hwcf6, val); return; - case 23: - WRITE16(addr, emu8k->smarw, val); + case 14: + WRITE16(addr, emu8k->hwcf7, val); + return; + + case 20: /* Top 8 bits are for Empty (MT) bit or non-addressable. */ + WRITE16(addr, emu8k->smalr, val&0xFF); + dmareadbit=0x8000; + return; + case 21: /* Top 8 bits are for Empty (MT) bit or non-addressable. */ + WRITE16(addr, emu8k->smarr, val&0xFF); + dmareadbit=0x8000; + return; + case 22: /* Top 8 bits are for full bit or non-addressable. */ + WRITE16(addr, emu8k->smalw, val&0xFF); + return; + case 23: /* Top 8 bits are for full bit or non-addressable. */ + WRITE16(addr, emu8k->smarw, val&0xFF); return; case 26: + dmawritebit=0x8000; EMU8K_WRITE(emu8k, emu8k->smarw, val); -/* pclog("emu8k_SMRW %04X %08X\n", val, emu8k->smarw);*/ emu8k->smarw++; - break; + return; } break; + /* TODO: Read Reverb, Chorus and equalizer setups */ + case 2: + emu8k->init2[emu8k->cur_voice] = val; + return; + case 3: + emu8k->init4[emu8k->cur_voice] = val; + if (emu8k->init1[0] != 0x03FF) { + /* If not in initialization, configure chorus */ + if (emu8k->cur_voice == 3) { + emu8k->chorus_engine.lfodepth_samples = ((val&0xFF)*emu8k->chorus_engine.delay_samples_central) >> 8; + } + } + return ; + case 4: -/* pclog("emu8k_outw : write ATKHLDV %04X\n", val);*/ - emu8k->voice[emu8k->cur_voice].atkhldv = val; - emu8k->voice[emu8k->cur_voice].env_attack = (val & 0x7f) << 6; - if (!(val & 0x8000)) /*Trigger attack*/ - emu8k->voice[emu8k->cur_voice].env_state = ENV_ATTACK; + { + emu8k->voice[emu8k->cur_voice].atkhldv = val; + emu8k_envelope_t* const vol_env = &emu8k->voice[emu8k->cur_voice].vol_envelope; + vol_env->attack_samples = env_attack_to_samples[ATKHLDV_ATTACK(val)]; + if (vol_env->attack_samples == 0) { + /* Eternal Mute? */ + vol_env->attack_amount_amp_hz = 0; + } + else { + /* Linear amplitude increase each sample. */ + vol_env->attack_amount_amp_hz = (1<<21) / vol_env->attack_samples; + } + vol_env->hold_samples = ATKHLDV_HOLD_TO_EMU_SAMPLES(val); + if (ATKHLDV_TRIGGER(val)) + { + /* TODO: I assume that "envelope trigger" is the same as new note + (since changing the IP can be done when modulating pitch too) */ + emu8k->voice[emu8k->cur_voice].lfo1_count.addr = 0; + emu8k->voice[emu8k->cur_voice].lfo2_count.addr = 0; + + vol_env->value_amp_hz = 0; + if (vol_env->delay_samples) + { + vol_env->state = ENV_DELAY; + } + else if (vol_env->attack_amount_amp_hz == 0) + { + vol_env->state = ENV_STOPPED; + } + else + { + vol_env->state = ENV_ATTACK; + /* TODO: Verify if "never attack" means eternal mute, + * or it means skip attack, go to hold". + if (vol_env->attack_amount == 0) + { + vol_env->value = (1 << 21); + vol_env->state = ENV_HOLD; + }*/ + } + } + } + return; + + case 5: + emu8k->voice[emu8k->cur_voice].lfo1val = val; + /* TODO: verify if this is set once, or set every time. */ + emu8k->voice[emu8k->cur_voice].lfo1_delay_samples = LFOxVAL_TO_EMU_SAMPLES(val); return; case 6: -/* pclog("emu8k_outw : write ATKHLD %04X\n", val);*/ - emu8k->voice[emu8k->cur_voice].atkhld = val; - emu8k->voice[emu8k->cur_voice].menv_attack = (val & 0x7f) << 6; - if (!(val & 0x8000)) /*Trigger attack*/ - emu8k->voice[emu8k->cur_voice].menv_state = ENV_ATTACK; + { + emu8k->voice[emu8k->cur_voice].atkhld = val; + emu8k_envelope_t* const mod_env = &emu8k->voice[emu8k->cur_voice].mod_envelope; + mod_env->attack_samples = env_attack_to_samples[ATKHLD_ATTACK(val)]; + if (mod_env->attack_samples == 0) { + /* Eternal Mute? */ + mod_env->attack_amount_amp_hz = 0; + } + else { + /* Linear amplitude increase each sample. */ + mod_env->attack_amount_amp_hz = (1<<21) / mod_env->attack_samples; + } + mod_env->hold_samples = ATKHLD_HOLD_TO_EMU_SAMPLES(val); + if (ATKHLD_TRIGGER(val)) + { + mod_env->value_amp_hz = 0; + mod_env->value_db_oct = 0; + if (mod_env->delay_samples) + { + mod_env->state = ENV_DELAY; + } + else if (mod_env->attack_amount_amp_hz == 0) + { + mod_env->state = ENV_STOPPED; + } + else + { + mod_env->state = ENV_ATTACK; + /* TODO: Verify if "never attack" means eternal start, + * or it means skip attack, go to hold". + if (mod_env->attack_amount == 0) + { + mod_env->value = (1 << 21); + mod_env->state = ENV_HOLD; + }*/ + } + } + } + return; + + case 7: + emu8k->voice[emu8k->cur_voice].lfo2val = val; + emu8k->voice[emu8k->cur_voice].lfo2_delay_samples = LFOxVAL_TO_EMU_SAMPLES(val); + return; } break; - case 0xc00: /*Data3*/ + case 0xE00: /*Data3*/ switch (emu8k->cur_reg) { case 0: emu8k->voice[emu8k->cur_voice].ip = val; - emu8k->voice[emu8k->cur_voice].pitch = val; + emu8k->voice[emu8k->cur_voice].ptrx_pit_target = freqtable[val] >> 18; return; case 1: - emu8k->voice[emu8k->cur_voice].ifatn = val; - emu8k->voice[emu8k->cur_voice].attenuation = attentable[val & 0xff]; - emu8k->voice[emu8k->cur_voice].cutoff = (val >> 8); -/* pclog("Attenuation now %02X %i\n", val & 0xff, emu8k->voice[emu8k->cur_voice].attenuation);*/ + { + emu8k_voice_t * const the_voice = &emu8k->voice[emu8k->cur_voice]; + the_voice->ifatn = val; + the_voice->initial_att = (((int32_t)the_voice->ifatn_attenuation <<21)/0xFF); + the_voice->vtft_vol_target = attentable[the_voice->ifatn_attenuation]; + + the_voice->initial_filter = (((int32_t)the_voice->ifatn_init_filter <<21)/0xFF); + if (the_voice->ifatn_init_filter==0xFF) { + the_voice->vtft_filter_target = 0xFFFF; + } else { + the_voice->vtft_filter_target = the_voice->initial_filter >> 5; + } + } return; case 2: - emu8k->voice[emu8k->cur_voice].pefe = val; - emu8k->voice[emu8k->cur_voice].fe_height = (int8_t)(val & 0xff); + { + emu8k_voice_t * const the_voice = &emu8k->voice[emu8k->cur_voice]; + the_voice->pefe = val; + if (the_voice->pefe_modenv_filter_height < 0) { + the_voice->fixed_modenv_filter_height = the_voice->pefe_modenv_filter_height*0x4000/0x80; + } else { + the_voice->fixed_modenv_filter_height = the_voice->pefe_modenv_filter_height*0x4000/0x7F; + } + if (the_voice->pefe_modenv_pitch_height < 0) { + the_voice->fixed_modenv_pitch_height = the_voice->pefe_modenv_pitch_height*0x4000/0x80; + } else { + the_voice->fixed_modenv_pitch_height = the_voice->pefe_modenv_pitch_height*0x4000/0x7F; + } + } return; case 3: - emu8k->voice[emu8k->cur_voice].fmmod = val; - emu8k->voice[emu8k->cur_voice].lfo1_fmmod = (val >> 8); + { + emu8k_voice_t * const the_voice = &emu8k->voice[emu8k->cur_voice]; + the_voice->fmmod = val; + if (the_voice->fmmod_lfo1_filt_mod < 0) { + the_voice->fixed_lfo1_filt_mod = the_voice->fmmod_lfo1_filt_mod*0x4000/0x80; + } else { + the_voice->fixed_lfo1_filt_mod = the_voice->fmmod_lfo1_filt_mod*0x4000/0x7F; + } + if (the_voice->fmmod_lfo1_vibrato < 0) { + the_voice->fixed_lfo1_vibrato = the_voice->fmmod_lfo1_vibrato*0x4000/0x80; + } else { + the_voice->fixed_lfo1_vibrato = the_voice->fmmod_lfo1_vibrato*0x4000/0x7F; + } + } return; case 4: - emu8k->voice[emu8k->cur_voice].tremfrq = val; - emu8k->voice[emu8k->cur_voice].lfo1_trem = (val >> 8); + { + emu8k_voice_t * const the_voice = &emu8k->voice[emu8k->cur_voice]; + the_voice->tremfrq = val; + the_voice->lfo1_speed = lfofreqtospeed[the_voice->tremfrq_lfo1_freq]; + if (the_voice->tremfrq_lfo1_tremolo < 0) { + the_voice->fixed_lfo1_tremolo = the_voice->tremfrq_lfo1_tremolo*0x4000/0x80; + } else { + the_voice->fixed_lfo1_tremolo = the_voice->tremfrq_lfo1_tremolo*0x4000/0x7F; + } + } return; case 5: - emu8k->voice[emu8k->cur_voice].fm2frq2 = val; - emu8k->voice[emu8k->cur_voice].lfo2_fmmod = (val >> 8); + { + emu8k_voice_t * const the_voice = &emu8k->voice[emu8k->cur_voice]; + the_voice->fm2frq2 = val; + the_voice->lfo2_speed = lfofreqtospeed[the_voice->fm2frq2_lfo2_freq]; + if (the_voice->fm2frq2_lfo2_vibrato < 0) { + the_voice->fixed_lfo2_vibrato = the_voice->fm2frq2_lfo2_vibrato*0x4000/0x80; + } else { + the_voice->fixed_lfo2_vibrato = the_voice->fm2frq2_lfo2_vibrato*0x4000/0x7F; + } + } return; case 7: /*ID?*/ @@ -503,15 +1218,19 @@ void emu8k_outw(uint16_t addr, uint16_t val, void *p) } break; - case 0xc02: /*Pointer*/ + case 0xE02: /*Pointer*/ emu8k->cur_voice = (val & 31); emu8k->cur_reg = ((val >> 5) & 7); return; } + pclog("EMU8K WRITE: Unknown register write: %04X-%02X(%d/%d): %04X \n", addr, (emu8k->cur_reg)<<5|emu8k->cur_voice, emu8k->cur_reg,emu8k->cur_voice, val); + } uint8_t emu8k_inb(uint16_t addr, void *p) { + /* Reading a single byte is a feature that at least Impulse tracker uses, + but only on detection code and not for odd addresses. */ if (addr & 1) return emu8k_inw(addr & ~1, p) >> 1; return emu8k_inw(addr, p) & 0xff; @@ -519,259 +1238,704 @@ uint8_t emu8k_inb(uint16_t addr, void *p) void emu8k_outb(uint16_t addr, uint8_t val, void *p) { + /* FIXME: AWE32 docs says that you cannot write in bytes, but if + an app were to use this, the content of the LSByte would be lost. */ if (addr & 1) emu8k_outw(addr & ~1, val << 8, p); else emu8k_outw(addr, val, p); } -void emu8k_update(emu8k_t *emu8k) +void emu8k_work_chorus(int32_t *inbuf, int32_t *outbuf, emu8k_chorus_eng_t *engine, int count) { - int32_t *buf; - int pos; - int c; - - int new_pos = (sound_pos_global * 44100) / 48000; - if (emu8k->pos < new_pos) + int pos; + for (pos = 0; pos < count; pos++) { + if (*inbuf != 0 ) { + pclog("chorus: bufferin pos:%d val:%d\n", pos, *inbuf); + } - buf = &emu8k->buffer[emu8k->pos*2]; - - for (pos = emu8k->pos; pos < new_pos; pos++) - emu8k->buffer[pos*2] = emu8k->buffer[pos*2 + 1] = 0; + + /* TODO: linear interpolate if the quality is not good enough. */ + int32_t offset_lfo = (lfotable[engine->lfo_pos.int_address] * engine->lfodepth_samples) >> 16; + int32_t fraction_part = (lfotable[engine->lfo_pos.int_address] * engine->lfodepth_samples) & 0xFFFF; - for (c = 0; c < 32; c++) - { - buf = &emu8k->buffer[emu8k->pos*2]; - - for (pos = emu8k->pos; pos < new_pos; pos++) - { - int32_t voice_l, voice_r; - int32_t dat; - int lfo1_vibrato, lfo2_vibrato; - - if (freqtable[emu8k->voice[c].pitch] >> 32) - dat = EMU8K_READ(emu8k, emu8k->voice[c].addr >> 32); - else - dat = EMU8K_READ_INTERP(emu8k, emu8k->voice[c].addr >> 24); + /* Work left */ + int32_t read = engine->write - engine->delay_samples_central - offset_lfo; + int next_value = read + 1; + if(read < 0) { + read += SOUNDBUFLEN; + if(next_value < 0) next_value += SOUNDBUFLEN; + } + else if(next_value >= SOUNDBUFLEN) { + next_value -= SOUNDBUFLEN; + if(read >= SOUNDBUFLEN) read -= SOUNDBUFLEN; + } + int32_t dat1 = engine->chorus_left_buffer[read]; + int32_t dat2 = engine->chorus_left_buffer[next_value]; + dat1 += ((dat2-(int32_t)dat1)* fraction_part) >> 16; + + engine->chorus_left_buffer[engine->write] = *inbuf + ((dat1 * engine->feedback)>>8); + + + /* Work right */ + read = engine->write - engine->delay_samples_central - engine->delay_offset_samples_right.int_address + offset_lfo; + if (fraction_partdelay_offset_samples_right.fract_address) { + fraction_part+=0x10000 - engine->delay_offset_samples_right.fract_address; + read--; + } else { + fraction_part -= engine->delay_offset_samples_right.fract_address; + } + + next_value = read + 1; + if(read < 0) { + read += SOUNDBUFLEN; + if(next_value < 0) next_value += SOUNDBUFLEN; + } + else if(next_value >= SOUNDBUFLEN) { + next_value -= SOUNDBUFLEN; + if(read >= SOUNDBUFLEN) read -= SOUNDBUFLEN; + } + int32_t dat3 = engine->chorus_right_buffer[read]; + int32_t dat4 = engine->chorus_right_buffer[next_value]; + dat3 += ((dat4-(int32_t)dat3)* fraction_part) >> 16; + + engine->chorus_right_buffer[engine->write] = *inbuf + ((dat3 * engine->feedback)>>8); + + ++engine->write; + engine->write %= SOUNDBUFLEN; + engine->lfo_pos.addr +=engine->lfo_inc.addr; + engine->lfo_pos.int_address %= SOUNDBUFLEN; - dat = (dat * emu8k->voice[c].attenuation) >> 16; - - dat = (dat * envtable[emu8k->voice[c].env_vol >> 9]) >> 16; - - if ((emu8k->voice[c].ccca >> 28) || (emu8k->voice[c].cutoff != 0xff)) - { - int cutoff = emu8k->voice[c].cutoff + ((emu8k->voice[c].menv_vol * emu8k->voice[c].fe_height) >> 20); - if (cutoff < 0) - cutoff = 0; - if (cutoff > 255) - cutoff = 255; - - emu8k->voice[c].vhp = ((-emu8k->voice[c].vbp * emu8k->voice[c].q) >> 8) - emu8k->voice[c].vlp - dat; - emu8k->voice[c].vlp += (emu8k->voice[c].vbp * filt_w0[cutoff]) >> 8; - emu8k->voice[c].vbp += (emu8k->voice[c].vhp * filt_w0[cutoff]) >> 8; - if (emu8k->voice[c].vlp < -32767) - dat = -32767; - else if (emu8k->voice[c].vlp > 32767) - dat = 32767; - else - dat = (int16_t)emu8k->voice[c].vlp; - } - - voice_l = (dat * emu8k->voice[c].vol_l) >> 7; - voice_r = (dat * emu8k->voice[c].vol_r) >> 7; - - (*buf++) += voice_l * 8192; - (*buf++) += voice_r * 8192; - - switch (emu8k->voice[c].env_state) - { - case ENV_ATTACK: - emu8k->voice[c].env_vol += emu8k->voice[c].env_attack; - emu8k->voice[c].vtft |= 0xffff0000; - if (emu8k->voice[c].env_vol >= (1 << 21)) - { - emu8k->voice[c].env_vol = 1 << 21; - emu8k->voice[c].env_state = ENV_DECAY; - } - break; - - case ENV_DECAY: - emu8k->voice[c].env_vol -= emu8k->voice[c].env_decay; - emu8k->voice[c].vtft = (emu8k->voice[c].vtft & ~0xffff0000) | ((emu8k->voice[c].env_sustain >> 5) << 16); - if (emu8k->voice[c].env_vol <= emu8k->voice[c].env_sustain) - { - emu8k->voice[c].env_vol = emu8k->voice[c].env_sustain; - emu8k->voice[c].env_state = ENV_SUSTAIN; - } - break; - - case ENV_RELEASE: - emu8k->voice[c].env_vol -= emu8k->voice[c].env_release; - emu8k->voice[c].vtft &= ~0xffff0000; - if (emu8k->voice[c].env_vol <= 0) - { - emu8k->voice[c].env_vol = 0; - emu8k->voice[c].env_state = ENV_STOPPED; - } - break; - } - - if (emu8k->voice[c].env_vol >= (1 << 21)) - emu8k->voice[c].cvcf &= ~0xffff0000; - else - emu8k->voice[c].cvcf = (emu8k->voice[c].cvcf & ~0xffff0000) | ((emu8k->voice[c].env_vol >> 5) << 16); - - switch (emu8k->voice[c].menv_state) - { - case ENV_ATTACK: - emu8k->voice[c].menv_vol += emu8k->voice[c].menv_attack; - if (emu8k->voice[c].menv_vol >= (1 << 21)) - { - emu8k->voice[c].menv_vol = 1 << 21; - emu8k->voice[c].menv_state = ENV_DECAY; - } - break; - - case ENV_DECAY: - emu8k->voice[c].menv_vol -= emu8k->voice[c].menv_decay; - if (emu8k->voice[c].menv_vol <= emu8k->voice[c].menv_sustain) - { - emu8k->voice[c].menv_vol = emu8k->voice[c].menv_sustain; - emu8k->voice[c].menv_state = ENV_SUSTAIN; - } - break; - - case ENV_RELEASE: - emu8k->voice[c].menv_vol -= emu8k->voice[c].menv_release; - if (emu8k->voice[c].menv_vol <= 0) - { - emu8k->voice[c].menv_vol = 0; - emu8k->voice[c].menv_state = ENV_STOPPED; - } - break; - } - - lfo1_vibrato = (lfotable[(emu8k->voice[c].lfo1_count >> 8) & 4095] * emu8k->voice[c].lfo1_fmmod) >> 9; - lfo2_vibrato = (lfotable[(emu8k->voice[c].lfo2_count >> 8) & 4095] * emu8k->voice[c].lfo2_fmmod) >> 9; - - emu8k->voice[c].addr += freqtable[(emu8k->voice[c].pitch + lfo1_vibrato + lfo2_vibrato) & 0xffff]; - if (emu8k->voice[c].addr >= emu8k->voice[c].loop_end) - emu8k->voice[c].addr -= (emu8k->voice[c].loop_end - emu8k->voice[c].loop_start); - - emu8k->voice[c].lfo1_count += (emu8k->voice[c].tremfrq & 0xff); - emu8k->voice[c].lfo2_count += (emu8k->voice[c].fm2frq2 & 0xff); - } - } - - buf = &emu8k->buffer[emu8k->pos*2]; - - for (pos = emu8k->pos; pos < new_pos; pos++) - { - buf[0] >>= 15; - buf[1] >>= 15; - - if (buf[0] < -32768) - buf[0] = -32768; - else if (buf[0] > 32767) - buf[0] = 32767; - - if (buf[1] < -32768) - buf[1] = -32768; - else if (buf[1] > 32767) - buf[1] = 32767; - - buf += 2; - } - - emu8k->wc += (new_pos - emu8k->pos); - - emu8k->pos = new_pos; + (*outbuf++) += dat1; + (*outbuf++) += dat3; + inbuf++; } } +void emu8k_work_reverb(emu8k_t *emu8k, int new_pos) +{ + /* TODO: Work reverb and add into buf */ +} +void emu8k_work_eq(emu8k_t *emu8k, int new_pos) +{ + /* TODO: Work EQ over buf */ +} + + +void emu8k_update(emu8k_t *emu8k) +{ + int new_pos = (sound_pos_global * 44100) / 48000; + if (emu8k->pos >= new_pos) + return; + + int32_t *buf; + emu8k_voice_t* emu_voice; + int pos; + int c; + + /* Clean the buffer since we will accumulate into it. */ + buf = &emu8k->buffer[emu8k->pos*2]; + memset(buf, 0, 2*(new_pos-emu8k->pos)*sizeof(emu8k->buffer[0])); + memset(&emu8k->chorus_in_buffer[emu8k->pos], 0, (new_pos-emu8k->pos)*sizeof(emu8k->chorus_in_buffer[0])); + + /* Voices section */ + for (c = 0; c < 32; c++) + { + emu_voice = &emu8k->voice[c]; + buf = &emu8k->buffer[emu8k->pos*2]; + + for (pos = emu8k->pos; pos < new_pos; pos++) + { + int32_t dat; + + /* Waveform oscillator */ + dat = EMU8K_READ_INTERP_LINEAR(emu8k, emu_voice->addr.int_address, + emu_voice->addr.fract_address); + + + /* Filter section */ + if (emu_voice->filterq_idx || emu_voice->cvcf_curr_filt_ctoff != 0xFFFF ) { + /* apply gain and move to 24bit. */ + int cutoff = emu_voice->cvcf_curr_filt_ctoff >> 8; + const int64_t coef0 = filt_coeffs[emu_voice->filterq_idx][cutoff][0]; + const int64_t coef1 = filt_coeffs[emu_voice->filterq_idx][cutoff][1]; + const int64_t coef2 = filt_coeffs[emu_voice->filterq_idx][cutoff][2]; + /* clip at twice the range */ + #define ClipBuffer(buf) (buf < -16777216) ? -16777216 : (buf > 16777216) ? 16777216 : buf + + #ifdef FILTER_INITIAL + #define NOOP(x) (void)x; + NOOP(coef1) + /* Apply expected attenuation. (FILTER_MOOG does it implicitly, but this one doesn't). + Work in 23 bits + (at 24bits there's an integer overflow that I haven't been able to locate). */ + dat = (dat * emu_voice->filt_att) >> 8; + + int64_t vhp = ((-emu_voice->filt_buffer[0] * coef2) >> 24) - emu_voice->filt_buffer[1] - dat; + emu_voice->filt_buffer[1] += (emu_voice->filt_buffer[0] * coef0) >> 24; + emu_voice->filt_buffer[0] += (vhp * coef0) >> 24; + dat = (int32_t)(emu_voice->filt_buffer[1] >> 8); + if (dat > 32767) { dat = 32767; } + else if (dat < -32768) { dat = -32768; } + + #elif defined FILTER_MOOG + + /* move to 24bits */ + dat <<= 8; + + dat -= (coef2 * emu_voice->filt_buffer[4]) >> 24; /* feedback */ + int64_t t1 = emu_voice->filt_buffer[1]; + emu_voice->filt_buffer[1] = ((dat + emu_voice->filt_buffer[0]) * coef0 - emu_voice->filt_buffer[1] * coef1) >> 24; + emu_voice->filt_buffer[1] = ClipBuffer(emu_voice->filt_buffer[1]); + + int64_t t2 = emu_voice->filt_buffer[2]; + emu_voice->filt_buffer[2] = ((emu_voice->filt_buffer[1] + t1) * coef0 - emu_voice->filt_buffer[2] * coef1) >> 24; + emu_voice->filt_buffer[2] = ClipBuffer(emu_voice->filt_buffer[2]); + + int64_t t3 = emu_voice->filt_buffer[3]; + emu_voice->filt_buffer[3] = ((emu_voice->filt_buffer[2] + t2) * coef0 - emu_voice->filt_buffer[3] * coef1) >> 24; + emu_voice->filt_buffer[3] = ClipBuffer(emu_voice->filt_buffer[3]); + + emu_voice->filt_buffer[4] = ((emu_voice->filt_buffer[3] + t3) * coef0 - emu_voice->filt_buffer[4] * coef1) >> 24; + emu_voice->filt_buffer[4] = ClipBuffer(emu_voice->filt_buffer[4]); + + emu_voice->filt_buffer[0] = ClipBuffer(dat); + + dat = (int32_t)(emu_voice->filt_buffer[4] >> 8); + if (dat > 32767) { dat = 32767; } + else if (dat < -32768) { dat = -32768; } + + #elif defined FILTER_CONSTANT + + /* Apply expected attenuation. (FILTER_MOOG does it implicitly, but this one is constant gain). Also stay at 24bits. */ + dat = (dat * emu_voice->filt_att) >> 8; + + emu_voice->filt_buffer[0] = (coef1 * emu_voice->filt_buffer[0] + + coef0 * (dat + + ((coef2 * (emu_voice->filt_buffer[0] - emu_voice->filt_buffer[1]))>>24)) + ) >> 24; + emu_voice->filt_buffer[1] = (coef1 * emu_voice->filt_buffer[1] + + coef0 * emu_voice->filt_buffer[0]) >> 24; + + emu_voice->filt_buffer[0] = ClipBuffer(emu_voice->filt_buffer[0]); + emu_voice->filt_buffer[1] = ClipBuffer(emu_voice->filt_buffer[1]); + + dat = (int32_t)(emu_voice->filt_buffer[1] >> 8); + if (dat > 32767) { dat = 32767; } + else if (dat < -32768) { dat = -32768; } + + #endif + + } + if (( emu8k->hwcf3 & 0x04) && !CCCA_DMA_ACTIVE(emu_voice->ccca)) + { + /* volume and pan */ + dat = (dat * emu_voice->cvcf_curr_volume) >> 16; + + (*buf++) += (dat * emu_voice->vol_l) >> 8; + (*buf++) += (dat * emu_voice->vol_r) >> 8; + + /* Effects section */ + if (emu_voice->ptrx_revb_send > 0) + { + /* TODO: Accumulate into reverb send buffer for processing after the voice loop */ + } + if (emu_voice->csl_chor_send > 0) + { + emu8k->chorus_in_buffer[pos]+=(dat*emu_voice->csl_chor_send) >> 8; + } + } + + if ( emu_voice->env_engine_on) { + + int32_t attenuation = emu_voice->initial_att; + int32_t filtercut = emu_voice->initial_filter; + int32_t currentpitch = emu_voice->ip; + /* run envelopes */ + emu8k_envelope_t *volenv = &emu_voice->vol_envelope; + switch (volenv->state) + { + case ENV_DELAY: + volenv->delay_samples--; + if (volenv->delay_samples <=0) + { + volenv->state=ENV_ATTACK; + } + attenuation = 0x1FFFFF; + break; + + case ENV_ATTACK: + /* Attack amount is in linear amplitude */ + volenv->value_amp_hz += volenv->attack_amount_amp_hz; + if (volenv->value_amp_hz >= (1 << 21)) + { + volenv->value_amp_hz = 1 << 21; + volenv->value_db_oct = 0; + if (volenv->hold_samples) + { + volenv->state = ENV_HOLD; + } + else + { + /* RAMP_UP since db value is inverted and it is 0 at this point. */ + volenv->state = ENV_RAMP_UP; + } + } + attenuation += env_vol_amplitude_to_db[volenv->value_amp_hz >> 5] << 5; + break; + + case ENV_HOLD: + volenv->hold_samples--; + if (volenv->hold_samples <=0) + { + volenv->state=ENV_RAMP_UP; + } + attenuation += volenv->value_db_oct; + break; + + case ENV_RAMP_DOWN: + /* Decay/release amount is in fraction of dBs and is always positive */ + volenv->value_db_oct -= volenv->ramp_amount_db_oct; + if (volenv->value_db_oct <= volenv->sustain_value_db_oct) + { + volenv->value_db_oct = volenv->sustain_value_db_oct; + volenv->state = ENV_SUSTAIN; + } + attenuation += volenv->value_db_oct; + break; + + case ENV_RAMP_UP: + /* Decay/release amount is in fraction of dBs and is always positive */ + volenv->value_db_oct += volenv->ramp_amount_db_oct; + if (volenv->value_db_oct >= volenv->sustain_value_db_oct) + { + volenv->value_db_oct = volenv->sustain_value_db_oct; + volenv->state = ENV_SUSTAIN; + } + attenuation += volenv->value_db_oct; + break; + + case ENV_SUSTAIN: + attenuation += volenv->value_db_oct; + break; + + case ENV_STOPPED: + attenuation = 0x1FFFFF; + break; + } + + emu8k_envelope_t *modenv = &emu_voice->mod_envelope; + switch (modenv->state) + { + case ENV_DELAY: + modenv->delay_samples--; + if (modenv->delay_samples <=0) + { + modenv->state=ENV_ATTACK; + } + break; + + case ENV_ATTACK: + /* Attack amount is in linear amplitude */ + modenv->value_amp_hz += modenv->attack_amount_amp_hz; + modenv->value_db_oct = env_mod_hertz_to_octave[modenv->value_amp_hz >> 5] << 5; + if (modenv->value_amp_hz >= (1 << 21)) + { + modenv->value_amp_hz = 1 << 21; + modenv->value_db_oct = 1 << 21; + if (modenv->hold_samples) + { + modenv->state = ENV_HOLD; + } + else + { + modenv->state = ENV_RAMP_DOWN; + } + } + break; + + case ENV_HOLD: + modenv->hold_samples--; + if (modenv->hold_samples <=0) + { + modenv->state=ENV_RAMP_UP; + } + break; + + case ENV_RAMP_DOWN: + /* Decay/release amount is in fraction of octave and is always positive */ + modenv->value_db_oct -= modenv->ramp_amount_db_oct; + if (modenv->value_db_oct <= modenv->sustain_value_db_oct) + { + modenv->value_db_oct = modenv->sustain_value_db_oct; + modenv->state = ENV_SUSTAIN; + } + break; + + case ENV_RAMP_UP: + /* Decay/release amount is in fraction of octave and is always positive */ + modenv->value_db_oct += modenv->ramp_amount_db_oct; + if (modenv->value_db_oct >= modenv->sustain_value_db_oct) + { + modenv->value_db_oct = modenv->sustain_value_db_oct; + modenv->state = ENV_SUSTAIN; + } + break; + } + + /* run lfos */ + if (emu_voice->lfo1_delay_samples) + { + emu_voice->lfo1_delay_samples--; + } + else + { + emu_voice->lfo1_count.addr += emu_voice->lfo1_speed; + emu_voice->lfo1_count.int_address &= 0xFFFF; + } + if (emu_voice->lfo2_delay_samples) + { + emu_voice->lfo2_delay_samples--; + } + else + { + emu_voice->lfo2_count.addr += emu_voice->lfo2_speed; + emu_voice->lfo2_count.int_address &= 0xFFFF; + } + + if (emu_voice->fixed_modenv_pitch_height) { + currentpitch += ((modenv->value_db_oct>>9)*emu_voice->fixed_modenv_pitch_height) >> 14; + } + + if (emu_voice->fixed_lfo1_vibrato) { + int32_t lfo1_vibrato = (lfotable[emu_voice->lfo1_count.int_address]*emu_voice->fixed_lfo1_vibrato) >> 17; + currentpitch += lfo1_vibrato; + } + if (emu_voice->fixed_lfo2_vibrato) { + int32_t lfo2_vibrato = (lfotable[emu_voice->lfo2_count.int_address]*emu_voice->fixed_lfo2_vibrato) >> 17; + currentpitch += lfo2_vibrato; + } + + if (emu_voice->fixed_modenv_filter_height) { + filtercut += ((modenv->value_db_oct>>9)*emu_voice->fixed_modenv_filter_height) >> 5; + } + + if (emu_voice->fixed_lfo1_filt_mod) { + int32_t lfo1_filtmod = (lfotable[emu_voice->lfo1_count.int_address]*emu_voice->fixed_lfo1_filt_mod) >> 9; + filtercut += lfo1_filtmod; + } + + if (emu_voice->fixed_lfo1_tremolo) { + int32_t lfo1_tremolo = (lfotable[emu_voice->lfo1_count.int_address]*emu_voice->fixed_lfo1_tremolo) >> 10; + attenuation += lfo1_tremolo; + } + + if (currentpitch > 0xFFFF) currentpitch = 0xFFFF; + if (currentpitch < 0) currentpitch = 0; + if (attenuation > 0x1FFFFF) attenuation = 0x1FFFFF; + if (attenuation < 0) attenuation = 0; + if (filtercut > 0x1FFFFF) filtercut = 0x1FFFFF; + if (filtercut < 0) filtercut = 0; + + emu_voice->vtft_vol_target = env_vol_db_to_vol_target[attenuation >> 5]; + emu_voice->vtft_filter_target = filtercut >> 5; + emu_voice->ptrx_pit_target = freqtable[currentpitch]>>18; + + /*if (modenv->state==ENV_ATTACK|| modenv->state==ENV_RAMP_UP|| modenv->state==ENV_RAMP_DOWN) { + pclog("EMUMODENV ch:%d %d:%08X - %08X : %08X - %08X\n", c, modenv->state, modenv->value_amp_hz, modenv->value_db_oct, modenv->attack_amount_amp_hz,modenv->ramp_amount_db_oct); + } + + if (emu_voice->fixed_modenv_pitch_height ||emu_voice->fixed_lfo1_vibrato || emu_voice->fixed_lfo2_vibrato) { + if (currentpitch!=old_pitch) { + pclog("EMUPitch ch:%d :%04X\n", c, currentpitch); + old_pitch=currentpitch; + } + } + if (emu_voice->fixed_modenv_filter_height ||emu_voice->fixed_lfo1_filt_mod) { + if (filtercut!=old_cut) { + pclog("EMUFilter ch:%d :%04X\n", c, filtercut); + old_cut=filtercut; + } + }*/ + } +/* +I've recopilated these sentences to get an idea of how to loop + +- Set its PSST register and its CLS register to zero to cause no loops to occur. +-Setting the Loop Start Offset and the Loop End Offset to the same value, will cause the oscillator to loop the entire memory. + +-Setting the PlayPosition greater than the Loop End Offset, will cause the oscillator to play in reverse, back to the Loop End Offset. It's pretty neat, but appears to be uncontrollable (the rate at which the samples are played in reverse). + +-Note that due to interpolator offset, the actual loop point is one greater than the start address +-Note that due to interpolator offset, the actual loop point will end at an address one greater than the loop address +-Note that the actual audio location is the point 1 word higher than this value due to interpolation offset +-In programs that use the awe, they generally set the loop address as "loopaddress -1" to compensate for the above. +(Note: I am already using address+1 in the interpolators so these things are already as they should.) +*/ + emu_voice->addr.addr += ((uint64_t)emu_voice->cpf_curr_pitch) << 18; + if (emu_voice->addr.addr >= emu_voice->loop_end.addr) + { + emu_voice->addr.int_address -= (emu_voice->loop_end.int_address - emu_voice->loop_start.int_address); + emu_voice->addr.int_address &= EMU8K_MEM_ADDRESS_MASK; + } + + /* TODO: How and when are the target and current values updated */ + emu_voice->cpf_curr_pitch = emu_voice->ptrx_pit_target; + emu_voice->cvcf_curr_volume = emu_voice->vtft_vol_target; + emu_voice->cvcf_curr_filt_ctoff = emu_voice->vtft_filter_target; + } + + /* Update EMU voice registers. */ + emu_voice->ccca = emu_voice->ccca_qcontrol | emu_voice->addr.int_address; + emu_voice->cpf_curr_frac_addr = emu_voice->addr.fract_address; + } + + + buf = &emu8k->buffer[emu8k->pos*2]; + emu8k_work_reverb(emu8k, new_pos); + emu8k_work_chorus(&emu8k->chorus_in_buffer[emu8k->pos], buf, &emu8k->chorus_engine, new_pos-emu8k->pos); + emu8k_work_eq(emu8k, new_pos); + + /* Clip signal */ + for (pos = emu8k->pos; pos < new_pos; pos++) + { + if (buf[0] < -32768) + buf[0] = -32768; + else if (buf[0] > 32767) + buf[0] = 32767; + + if (buf[1] < -32768) + buf[1] = -32768; + else if (buf[1] > 32767) + buf[1] = 32767; + + buf += 2; + } + + /* Update EMU clock. */ + emu8k->wc += (new_pos - emu8k->pos); + + emu8k->pos = new_pos; +} +/* onboard_ram in kilobytes */ void emu8k_init(emu8k_t *emu8k, int onboard_ram) { + uint32_t const BLOCK_SIZE_WORDS = 0x10000; FILE *f; int c; double out; - + f = romfopen(L"roms/sound/awe32.raw", L"rb"); if (!f) - fatal("ROMS/SOUND/AWE32.RAW not found\n"); + fatal("AWE32.RAW not found\n"); + emu8k->rom = malloc(1024 * 1024); + fread(emu8k->rom, 1024 * 1024, 1, f); + fclose(f); + /*AWE-DUMP creates ROM images offset by 2 bytes, so if we detect this + then correct it*/ + if (emu8k->rom[3] == 0x314d && emu8k->rom[4] == 0x474d) + { + memmove(&emu8k->rom[0], &emu8k->rom[1], (1024 * 1024) - 2); + emu8k->rom[0x7ffff] = 0; + } + + emu8k->empty = malloc(2*BLOCK_SIZE_WORDS); + memset(emu8k->empty, 0, 2*BLOCK_SIZE_WORDS); + + int j=0; + for (;j<0x8;j++) + { + emu8k->ram_pointers[j]=emu8k->rom+(j*BLOCK_SIZE_WORDS); + } + for (;j<0x20;j++) + { + emu8k->ram_pointers[j]=emu8k->empty; + } + if (onboard_ram) { /* Clip to 28MB, since that's the max that we can address. */ if (onboard_ram > 0x7000) onboard_ram = 0x7000; emu8k->ram = malloc(onboard_ram * 1024); - emu8k->ram_end_addr = EMU8K_RAM_MEM_START + ((onboard_ram * 1024) / 2); + memset(emu8k->ram, 0, onboard_ram * 1024); + const int i_end=onboard_ram>>7; + int i=0; + for(;iram_pointers[j]=emu8k->ram+(i*BLOCK_SIZE_WORDS); + } + emu8k->ram_end_addr = EMU8K_RAM_MEM_START + (onboard_ram<<9); } else { emu8k->ram = 0; emu8k->ram_end_addr = EMU8K_RAM_MEM_START; } - - emu8k->rom = malloc(1024 * 1024); - - fread(emu8k->rom, 1024 * 1024, 1, f); - fclose(f); - - /*AWE-DUMP creates ROM images offset by 2 bytes, so if we detect this - then correct it*/ - if (emu8k->rom[3] == 0x314d && emu8k->rom[4] == 0x474d) + for (;j < 0x100;j++) { - memcpy(&emu8k->rom[0], &emu8k->rom[1], (1024 * 1024) - 2); - emu8k->rom[0x7ffff] = 0; + emu8k->ram_pointers[j]=emu8k->empty; + } + io_sethandler(0x0620, 0x0004, emu8k_inb, emu8k_inw, NULL, emu8k_outb, emu8k_outw, NULL, emu8k); io_sethandler(0x0a20, 0x0004, emu8k_inb, emu8k_inw, NULL, emu8k_outb, emu8k_outw, NULL, emu8k); io_sethandler(0x0e20, 0x0004, emu8k_inb, emu8k_inw, NULL, emu8k_outb, emu8k_outw, NULL, emu8k); - /*Create frequency table*/ + /*Create frequency table. (Convert initial pitch register value to a linear speed change) + * The input is encoded such as 0xe000 is center note (no pitch shift) + * and from then on , changing up or down 0x1000 (4096) increments/decrements an octave. + * Note that this is in reference to the 44.1Khz clock that the channels play at. + * The 65536 * 65536 is in order to left-shift the 32bit value to a 64bit value as a 32.32 fixed point. + */ for (c = 0; c < 0x10000; c++) { freqtable[c] = (uint64_t)(exp2((double)(c - 0xe000) / 4096.0) * 65536.0 * 65536.0); } + /* Shortcut: minimum pitch equals stopped. I don't really know if this is true, but it's better + since some programs set the pitch to 0 for unused channels. */ + freqtable[0] = 0; - out = 65536.0; - + /* starting at 65535 because it is used for "volume target" register conversion. */ + out = 65535.0; for (c = 0; c < 256; c++) { - attentable[c] = (int)out; + attentable[c] = (int32_t)out; out /= sqrt(1.09018); /*0.375 dB steps*/ } + /* Shortcut: max attenuation is silent, not -96dB. */ + attentable[255]=0; - out = 65536; - - for (c = 0; c < 4096; c++) + /* Note: these two tables have "db" inverted: 0 dB is max volume, 65535 "db" (-96.32dBFS) is silence. + Important: Using 65535 as max output value because this is intended to be used with the volume target register! */ + out = 65535.0; + for (c = 0; c < 0x10000; c++) { - envtable[4095 - c] = (int)out; - out /= 1.002709201; /*0.0235 dB Steps*/ - } - - for (c = 0; c < 4096; c++) - { - int d = (c + 1024) & 4095; - if (d >= 2048) - lfotable[c] = 4096 - ((2048 - d) * 4); - else - lfotable[c] = (d * 4) - 4096; + env_vol_db_to_vol_target[c] = (int32_t)out; + /* calculated from the 65536th root of 65536 */ + out /= 1.00016923970; } + /* Shortcut: max attenuation is silent, not -96dB. */ + env_vol_db_to_vol_target[0x10000-1]=0; + /* One more position to forget about max value being 65536. */ + env_vol_db_to_vol_target[0x10000]=0; - out = 125.0; + for (c = 1; c < 0x10000; c++) + { + out = -680.32142884264* 20.0 * log10(c/65535.0); + env_vol_amplitude_to_db[c] = (int32_t)out; + } + /* Shortcut: max attenuation is silent, not -96dB. */ + env_vol_amplitude_to_db[0]=65535; + /* One more position to forget about max value being 65536. */ + env_vol_amplitude_to_db[0x10000]=0; + + + for (c = 1; c < 0x10000; c++) + { + out = log2((c/0x10000)+1.0) *65536.0; + env_mod_hertz_to_octave[c] = (int32_t)out; + } + /* No hertz change, no octave change. */ + env_mod_hertz_to_octave[0]=0; + /* One more position to forget about max value being 65536. */ + env_mod_hertz_to_octave[0x10000]=65536; + + + /* This formula comes from vince vu/judge dredd's awe32p10 and corresponds to what the freebsd/linux AWE32 driver has. */ + float millis; + for (c=0;c<128;c++) { + if (c==0) { + /* This means never attack. */ + millis = 0; + } + else if (c < 32) { + millis = 11878.0/c; + } else { + millis = 360*exp((c - 32) / (16.0/log(1.0/2.0))); + } + env_attack_to_samples[c] = 44.1*millis; + /* This is an alternate formula with linear increments, but probably incorrect: (256+4096*(0x7F-c)) */ + } + + /* The LFOs use a triangular waveform starting at zero and going 1/-1/1/-1. + This table is stored in signed 16bits precision, with a period of 65536 samples */ + for (c = 0; c < 65536; c++) + { + int d = (c + 16384) & 65535; + if (d >= 32768) + lfotable[c] = 32768 + ((32768 - d)*2); + else + lfotable[c] = (d*2) - 32768; + } + /* The 65536 * 65536 is in order to left-shift the 32bit value to a 64bit value as a 32.32 fixed point. */ + out = 0.01; for (c = 0; c < 256; c++) { -/* filt_w0[c] = (int32_t)((2.0 * 3.142 * (out / 44100.0)) * 0.707 * 256.0);*/ -/* filt_w0[c] = 2.0 * 3.142 * (out / 44100.0);*/ - filt_w0[c] = (int32_t)(2.0 * 3.142 * (out / 44100.0) * 256.0); - out *= 1.016378315; + lfofreqtospeed[c] = (uint64_t)(out *65536.0/44100.0 * 65536.0 * 65536.0); + out += 0.042; } + + /* Filter coefficients tables. Note: Values are multiplied by *16777216 to left shift 24 bits. (i.e. 8.24 fixed point) */ + int qidx; + for (qidx = 0; qidx < 16; qidx++) + { + out = 125.0; /* Start at 125Hz */ + for (c = 0; c < 256; c++) + { +#ifdef FILTER_INITIAL + float w0 = sin(2.0*M_PI*out / 44100.0); + /* The value 102.5f has been selected a bit randomly. Pretends to reach 0.2929 at w0 = 1.0 */ + float q = (qidx / 102.5f) * (1.0 + 1.0 / w0); + /* Limit max value. Else it would be 470. */ + if (q > 200) q=200; + filt_coeffs[qidx][c][0] = (int32_t)(w0 * 16777216.0); + filt_coeffs[qidx][c][1] = 16777216.0; + filt_coeffs[qidx][c][2] = (int32_t)((1.0f / (0.7071f + q)) * 16777216.0); +#elif defined FILTER_MOOG + float w0 = sin(2.0*M_PI*out / 44100.0); + float q_factor = 1.0f - w0; + float p = w0 + 0.8f * w0 * q_factor; + float f = p + p - 1.0f; + float resonance = (1.0-pow(2.0,-qidx*24.0/90.0))*0.8; + float q = resonance * (1.0f + 0.5f * q_factor * (w0 + 5.6f * q_factor * q_factor)); + filt_coeffs[qidx][c][0] = (int32_t)(p * 16777216.0); + filt_coeffs[qidx][c][1] = (int32_t)(f * 16777216.0); + filt_coeffs[qidx][c][2] = (int32_t)(q * 16777216.0); +#elif defined FILTER_CONSTANT + /* *16777216 to left shift 24 bits. */ + float q = (1.0-pow(2.0,-qidx*24.0/90.0))*0.8; + float coef0 = sin(2.0*M_PI*out / 44100.0); + float coef1 = 1.0 - coef0; + float coef2 = q * (1.0 + 1.0 / coef1); + filt_coeffs[qidx][c][0] = (int32_t)(coef0 * 16777216.0); + filt_coeffs[qidx][c][1] = (int32_t)(coef1 * 16777216.0); + filt_coeffs[qidx][c][2] = (int32_t)(coef2 * 16777216.0); +#endif /* FILTER_TYPE */ + /* 42.66 divisions per octave (the doc says quarter seminotes which is 48, but then it would be almost an octave less) */ + out *= 1.016378315; + } + } + + + /* Cubic Resampling ( 4point cubic spline) { */ + double const resdouble = 1.0/(double)CUBIC_RESOLUTION; + for(int i = 0; i < CUBIC_RESOLUTION; ++i) { + double x = (double)i * resdouble; + /* Cubic resolution is made of four table, but I've put them all in one table to optimize memory access. */ + cubic_table[i*4] = (int32_t)((-0.5 * x * x * x + x * x - 0.5 * x) *0x7FFF); + cubic_table[i*4+1] = (int32_t)(( 1.5 * x * x * x - 2.5 * x * x + 1.0) *0x7FFF); + cubic_table[i*4+2] = (int32_t)((-1.5 * x * x * x + 2.0 * x * x + 0.5 * x) *0x7FFF); + cubic_table[i*4+3] = (int32_t)(( 0.5 * x * x * x - 0.5 * x * x) *0x7FFF); + } + /* If this is not set here, AWE card is not detected on Windows with Aweman driver. It's weird that the EMU8k says that this + has to be set by applications, and the AWE driver does not set it. */ emu8k->hwcf1 = 0x59; emu8k->hwcf2 = 0x20; - emu8k->hwcf3 = 0x04; + /* Initial state is muted. 0x04 is unmuted. */ + emu8k->hwcf3 = 0x00; } void emu8k_close(emu8k_t *emu8k) @@ -779,3 +1943,4 @@ void emu8k_close(emu8k_t *emu8k) free(emu8k->rom); free(emu8k->ram); } + diff --git a/src/SOUND/snd_emu8k.h b/src/SOUND/snd_emu8k.h index 6eea70a00..ffd6a2600 100644 --- a/src/SOUND/snd_emu8k.h +++ b/src/SOUND/snd_emu8k.h @@ -1,69 +1,300 @@ +/* All these defines are in samples, not in bytes. */ #define EMU8K_MEM_ADDRESS_MASK 0xFFFFFF #define EMU8K_RAM_MEM_START 0x200000 -#define EMU8K_ROM_MEM_1MB_END 0x80000 +#define EMU8K_FM_MEM_ADDRESS 0xFFFFE0 +#define EMU8K_RAM_POINTERS_MASK 0x3F + +/* + Everything in this file assumes little endian + + used for the increment of oscillator position */ +typedef struct emu8k_mem_internal_t { + union { + uint64_t addr; + struct { + uint16_t fract_lw_address; + uint16_t fract_address; + uint32_t int_address; + }; + }; +} emu8k_mem_internal_t; + +/* used for access to ram pointers from oscillator position. */ +typedef struct emu8k_mem_pointers_t { + union { + uint32_t addr; + struct { + uint16_t lw_address; + uint8_t hb_address; + uint8_t unused_address; + }; + }; +} emu8k_mem_pointers_t; + +/* + * From the Soundfount 2.0 fileformat Spec.: + * + An envelope generates a control signal in six phases. + When key-on occurs, a delay period begins during which the envelope value is zero. + The envelope then rises in a convex curve to a value of one during the attack phase. + " Note that the attack is convex; the curve is nominally such that when applied to a + decibel or semitone parameter, the result is linear in amplitude or Hz respectively" + + When a value of one is reached, the envelope enters a hold phase during which it remains at one. + When the hold phase ends, the envelope enters a decay phase during which its value decreases linearly to a sustain level. + " For the Volume Envelope, the decay phase linearly ramps toward the sustain level, causing a constant dB change for each time unit. " + When the sustain level is reached, the envelope enters sustain phase, during which the envelope stays at the sustain level. + + Whenever a key-off occurs, the envelope immediately enters a release phase during which the value linearly ramps from the current value to zero. + " For the Volume Envelope, the release phase linearly ramps toward zero from the current level, causing a constant dB change for each time unit" + + When zero is reached, the envelope value remains at zero. + + Modulation of pitch and filter cutoff are in octaves, semitones, and cents. + These parameters can be modulated to varying degree, either positively or negatively, by the modulation envelope. + The degree of modulation is specified in cents for the full-scale attack peak. + + The volume envelope operates in dB, with the attack peak providing a full scale output, appropriately scaled by the initial volume. + The zero value, however, is actually zero gain. + The implementation in the EMU8000 provides for 96 dB of amplitude control. + When 96 dB of attenuation is reached in the final gain amplifier, an abrupt jump to zero gain (infinite dB of attenuation) occurs. In a 16-bit system, this jump is inaudible +*/ +/* It seems that the envelopes don't really have a decay/release stage, + but instead they have a volume ramper that can be triggered + automatically (after hold period), or manually (by activating release) + and the "sustain" value is the target of any of both cases. + Some programs like cubic player and AWEAmp use this, and it was + described in the following way in Vince Vu/Judge Dredd's awe32p10.txt: + If the MSB (most significant bit or bit 15) of this register is set, + the Decay/Release will begin immediately, overriding the Delay, Attack, + and Hold. Otherwise the Decay/Release will wait until the Delay, Attack, + and Hold are finished. If you set the MSB of this register, you can use + it as a volume ramper, as on the GUS. The upper byte (except the MSB), + contains the destination volume, and the lower byte contains the ramp time. */ + +/* attack_amount is linear amplitude (added directly to value). ramp_amount_db is linear dB (added directly to value too, but needs conversion to get linear amplitude). + value range is 21bits for both, linear amplitude being 1<<21 = 0dBFS and 0 = -96dBFS (which is shortcut to silence), and db amplutide being 0 = 0dBFS and -(1<<21) = -96dBFS (which is shortcut to silence). This allows to operate db values by simply adding them. */ +typedef struct emu8k_envelope_t { + int state; + int32_t delay_samples, hold_samples, attack_samples; + int32_t value_amp_hz, value_db_oct; + int32_t sustain_value_db_oct; + int32_t attack_amount_amp_hz, ramp_amount_db_oct; +} emu8k_envelope_t; + + + +/* Chorus Params */ +typedef struct { + uint16_t FbkLevReg; /* Feedback Level (0xE600-0xE6FF) */ + uint16_t Delay; /* Delay (0-0x0DA3) [1/44100 sec] */ + uint16_t LfoDepReg; /* LFO Depth (0xBC00-0xBCFF) */ + uint32_t DelayR; /* Right Delay (0-0xFFFFFFFF) [1/256/44100 sec] */ + uint32_t LfoFreq; /* LFO Frequency (0-0xFFFFFFFF) */ +} emu8k_chorus_t; + +typedef struct { + int32_t write; + int32_t feedback; + int32_t delay_samples_central; + int32_t lfodepth_samples; + emu8k_mem_internal_t delay_offset_samples_right; + emu8k_mem_internal_t lfo_inc; + emu8k_mem_internal_t lfo_pos; + + int32_t chorus_left_buffer[SOUNDBUFLEN]; + int32_t chorus_right_buffer[SOUNDBUFLEN]; + +} emu8k_chorus_eng_t; + +typedef struct emu8k_voice_t +{ + union { + uint32_t cpf; + struct { + uint16_t cpf_curr_frac_addr; /* fractional part of the playing cursor. */ + uint16_t cpf_curr_pitch; /* 0x4000 = no shift. Linear increment */ + }; + }; + union { + uint32_t ptrx; + struct { + uint8_t ptrx_pan_aux; + uint8_t ptrx_revb_send; + uint16_t ptrx_pit_target; /* target pitch to which slide at curr_pitch speed. */ + }; + }; + union { + uint32_t cvcf; + struct { + uint16_t cvcf_curr_filt_ctoff; + uint16_t cvcf_curr_volume; + }; + }; + union { + uint32_t vtft; + struct { + uint16_t vtft_filter_target; + uint16_t vtft_vol_target; /* written to by the envelope engine. */ + }; + }; + /* These registers are used at least by the Windows drivers, and seem to be resetting + something, similarly to targets and current, but... of what? + what is curious is that if they are already zero, they are not written to, so it really + looks like they are information about the status of the channel. (lfo position maybe?) */ + uint32_t unknown_data0_4; + uint32_t unknown_data0_5; + union { + uint32_t psst; + struct { + uint16_t psst_lw_address; + uint8_t psst_hw_address; + uint8_t psst_pan; + }; + #define PSST_LOOP_START_MASK 0x00FFFFFF /* In samples, i.e. uint16_t array[BOARD_RAM/2]; */ + }; + union { + uint32_t csl; + struct { + uint16_t csl_lw_address; + uint8_t csl_hw_address; + uint8_t csl_chor_send; + }; + #define CSL_LOOP_END_MASK 0x00FFFFFF /* In samples, i.e. uint16_t array[BOARD_RAM/2]; */ + }; + union { + uint32_t ccca; + struct { + uint16_t ccca_lw_addr; + uint8_t ccca_hb_addr; + uint8_t ccca_qcontrol; + }; + }; + #define CCCA_FILTQ_GET(ccca) (ccca>>28) + #define CCCA_FILTQ_SET(ccca,q) ccca = (ccca&0x0FFFFFFF) | (q<<28) + /* Bit 27 should always be zero */ + #define CCCA_DMA_ACTIVE(ccca) (ccca&0x04000000) + #define CCCA_DMA_WRITE_MODE(ccca) (ccca&0x02000000) + #define CCCA_DMA_WRITE_RIGHT(ccca) (ccca&0x01000000) + + uint16_t envvol; + #define ENVVOL_NODELAY(envol) (envvol&0x8000) + /* Verified with a soundfont bank. 7FFF is the minimum delay time, and 0 is the max delay time */ + #define ENVVOL_TO_EMU_SAMPLES(envvol) (envvol&0x8000) ? 0 : ((0x8000-(envvol&0x7FFF)) <<5) + + uint16_t dcysusv; + #define DCYSUSV_IS_RELEASE(dcysusv) (dcysusv&0x8000) + #define DCYSUSV_GENERATOR_ENGINE_ON(dcysusv) !(dcysusv&0x0080) + #define DCYSUSV_SUSVALUE_GET(dcysusv) ((dcysusv>>8)&0x7F) + /* Inverting the range compared to documentation because the envelope runs from 0dBFS = 0 to -96dBFS = (1 <<21) */ + #define DCYSUSV_SUS_TO_ENV_RANGE(susvalue) (((0x7F-susvalue) << 21)/0x7F) + #define DCYSUSV_DECAYRELEASE_GET(dcysusv) (dcysusv&0x7F) + + uint16_t envval; + #define ENVVAL_NODELAY(enval) (envval&0x8000) + /* Verified with a soundfont bank. 7FFF is the minimum delay time, and 0 is the max delay time */ + #define ENVVAL_TO_EMU_SAMPLES(envval)(envval&0x8000) ? 0 : ((0x8000-(envval&0x7FFF)) <<5) + + uint16_t dcysus; + #define DCYSUS_IS_RELEASE(dcysus) (dcysus&0x8000) + #define DCYSUS_SUSVALUE_GET(dcysus) ((dcysus>>8)&0x7F) + #define DCYSUS_SUS_TO_ENV_RANGE(susvalue) ((susvalue << 21)/0x7F) + #define DCYSUS_DECAYRELEASE_GET(dcysus) (dcysus&0x7F) + + uint16_t atkhldv; + #define ATKHLDV_TRIGGER(atkhldv) !(atkhldv&0x8000) + #define ATKHLDV_HOLD(atkhldv) ((atkhldv>>8)&0x7F) + #define ATKHLDV_HOLD_TO_EMU_SAMPLES(atkhldv) (4096*(0x7F-((atkhldv>>8)&0x7F))) + #define ATKHLDV_ATTACK(atkhldv) (atkhldv&0x7F) + + uint16_t lfo1val, lfo2val; + #define LFOxVAL_NODELAY(lfoxval) (lfoxval&0x8000) + #define LFOxVAL_TO_EMU_SAMPLES(lfoxval) (lfoxval&0x8000) ? 0 : ((0x8000-(lfoxval&0x7FFF)) <<5) + + uint16_t atkhld; + #define ATKHLD_TRIGGER(atkhld) !(atkhld&0x8000) + #define ATKHLD_HOLD(atkhld) ((atkhld>>8)&0x7F) + #define ATKHLD_HOLD_TO_EMU_SAMPLES(atkhld) (4096*(0x7F-((atkhld>>8)&0x7F))) + #define ATKHLD_ATTACK(atkhld) (atkhld&0x7F) + + + uint16_t ip; + #define INTIAL_PITCH_CENTER 0xE000 + #define INTIAL_PITCH_OCTAVE 0x1000 + + union { + uint16_t ifatn; + struct{ + uint8_t ifatn_attenuation; + uint8_t ifatn_init_filter; + }; + }; + union { + uint16_t pefe; + struct { + int8_t pefe_modenv_filter_height; + int8_t pefe_modenv_pitch_height; + }; + }; + union { + uint16_t fmmod; + struct { + int8_t fmmod_lfo1_filt_mod; + int8_t fmmod_lfo1_vibrato; + }; + }; + union { + uint16_t tremfrq; + struct { + uint8_t tremfrq_lfo1_freq; + int8_t tremfrq_lfo1_tremolo; + }; + }; + union { + uint16_t fm2frq2; + struct { + uint8_t fm2frq2_lfo2_freq; + int8_t fm2frq2_lfo2_vibrato; + }; + }; + + int env_engine_on; + + emu8k_mem_internal_t addr, loop_start, loop_end; + + int32_t initial_att; + int32_t initial_filter; + + emu8k_envelope_t vol_envelope; + emu8k_envelope_t mod_envelope; + + int64_t lfo1_speed, lfo2_speed; + emu8k_mem_internal_t lfo1_count, lfo2_count; + int32_t lfo1_delay_samples, lfo2_delay_samples; + int vol_l, vol_r; + + int16_t fixed_modenv_filter_height; + int16_t fixed_modenv_pitch_height; + int16_t fixed_lfo1_filt_mod; + int16_t fixed_lfo1_vibrato; + int16_t fixed_lfo1_tremolo; + int16_t fixed_lfo2_vibrato; + + /* filter internal data. */ + int filterq_idx; + int32_t filt_att; + int64_t filt_buffer[5]; + +} emu8k_voice_t; typedef struct emu8k_t { - struct - { - uint32_t cpf; - uint32_t ptrx; - uint32_t cvcf; - uint32_t vtft; - uint32_t psst; - uint32_t csl; - - uint32_t ccca; + emu8k_voice_t voice[32]; - uint16_t init1, init2, init3, init4; - - uint16_t envvol; - uint16_t dcysusv; - uint16_t envval; - uint16_t dcysus; - uint16_t atkhldv; - uint16_t lfo1val, lfo2val; - uint16_t atkhld; - uint16_t ip; - uint16_t ifatn; - uint16_t pefe; - uint16_t fmmod; - uint16_t tremfrq; - uint16_t fm2frq2; - - int voice_on; - - uint64_t addr; - uint64_t loop_start, loop_end; - - uint16_t pitch; - int attenuation; - int env_state, env_vol; - int env_attack, env_decay, env_sustain, env_release; + uint16_t hwcf1, hwcf2, hwcf3; + uint32_t hwcf4, hwcf5, hwcf6, hwcf7; - int menv_state, menv_vol; - int menv_attack, menv_decay, menv_sustain, menv_release; - - int lfo1_count, lfo2_count; - int8_t lfo1_fmmod, lfo2_fmmod; - int8_t lfo1_trem; - int vol_l, vol_r; - - int8_t fe_height; - - int64_t vlp, vbp, vhp; - int32_t q; - - int filter_offset; - -/* float vlp, vbp, vhp; - float q;*/ - - int cutoff; - } voice[32]; - - uint32_t hwcf1, hwcf2, hwcf3; - uint32_t hwcf4, hwcf5, hwcf6; + uint16_t init1[32], init2[32], init3[32], init4[32]; uint32_t smalr, smarr, smalw, smarw; uint16_t smld_buffer, smrd_buffer; @@ -72,22 +303,32 @@ typedef struct emu8k_t uint16_t c02_read; - uint16_t id; - - int16_t *ram, *rom; - + uint16_t id; + + /* The empty block is used to act as an unallocated memory returning zero. */ + int16_t *ram, *rom, *empty; + + /* RAM pointers are a way to avoid checking ram boundaries on read */ + int16_t *ram_pointers[0x100]; uint32_t ram_end_addr; - + int cur_reg, cur_voice; int timer_count; int16_t out_l, out_r; + emu8k_chorus_eng_t chorus_engine; + int32_t chorus_in_buffer[SOUNDBUFLEN]; + int32_t reverb_in_buffer[SOUNDBUFLEN]; + int32_t reverb_out_buffer[SOUNDBUFLEN * 2]; + int pos; int32_t buffer[SOUNDBUFLEN * 2]; } emu8k_t; + + void emu8k_init(emu8k_t *emu8k, int onboard_ram); void emu8k_close(emu8k_t *emu8k); diff --git a/src/WIN/86Box.rc b/src/WIN/86Box.rc index bea1d7164..991b8bfe5 100644 --- a/src/WIN/86Box.rc +++ b/src/WIN/86Box.rc @@ -703,12 +703,12 @@ BEGIN IDS_2053 "Invalid number of sectors (valid values are between 1 and 63)" IDS_2054 "Invalid number of heads (valid values are between 1 and 16)" IDS_2055 "Invalid number of cylinders (valid values are between 1 and 266305)" - IDS_2056 "Please enter a valid file name" - IDS_2057 "Unable to open the file for write" - IDS_2058 "Attempting to create a HDI image larger than 4 GB" - IDS_2059 "Remember to partition and format the new drive" - IDS_2060 "Unable to open the file for read" - IDS_2061 "HDI or HDX image with a sector size that is not 512 are not supported" + IDS_2056 "Specify the NVR Path" + IDS_2057 "(empty)" + IDS_2058 "(host drive %c:)" + IDS_2059 "Turbo" + IDS_2060 "On" + IDS_2061 "Off" IDS_2062 "86Box was unable to find any ROMs.\nAt least one ROM set is required to use 86Box." IDS_2063 "Configured ROM set not available.\nDefaulting to an available ROM set." END @@ -724,9 +724,8 @@ BEGIN IDS_2070 "Other peripherals" IDS_2071 "Hard disks" IDS_2072 "Removable devices" - IDS_2073 "%i"" floppy drive: %s" - IDS_2074 "Disabled CD-ROM drive" - IDS_2075 "%s CD-ROM drive: %s" + IDS_2073 "Unable to create bitmap file: %s" + IDS_2074 "Use CTRL+ALT+PAGE DOWN to return to windowed mode" IDS_2076 "Host CD/DVD Drive (%c:)" IDS_2077 "Click to capture mouse" IDS_2078 "Press F12-F8 to release mouse" @@ -743,14 +742,12 @@ BEGIN IDS_2085 "H" IDS_2086 "S" IDS_2087 "MB" - IDS_2088 "%i" IDS_2089 "Enabled" IDS_2090 "Mute" IDS_2091 "Type" IDS_2092 "Bus" IDS_2093 "DMA" IDS_2094 "KB" - IDS_2095 "MFM, RLL, or ESDI CD-ROM drives never existed" END STRINGTABLE DISCARDABLE @@ -766,7 +763,6 @@ BEGIN IDS_2104 "Network Type" IDS_2105 "Surround Module" IDS_2106 "MPU-401 Base Address" - IDS_2107 "No PCap devices found" IDS_2108 "On-board RAM" IDS_2109 "Memory Size" IDS_2110 "Display Type" @@ -806,15 +802,15 @@ BEGIN IDS_2136 "Slow VLB/PCI" IDS_2137 "Mid VLB/PCI" IDS_2138 "Fast VLB/PCI" - IDS_2139 "Microsoft 2-button mouse (serial)" - IDS_2140 "Mouse Systems mouse (serial)" - IDS_2141 "2-button mouse (PS/2)" - IDS_2142 "Microsoft Intellimouse (PS/2)" - IDS_2143 "Bus mouse" END STRINGTABLE DISCARDABLE BEGIN + IDS_2139 "PCap failed to set up because it may not be initialized" + IDS_2140 "No PCap devices found" + IDS_2141 "Invalid PCap device" + IDS_2142 "&Notify disk change" + IDS_2143 "Type" IDS_2144 "Standard 2-button joystick(s)" IDS_2145 "Standard 4-button joystick" IDS_2146 "Standard 6-button joystick" @@ -822,85 +818,95 @@ BEGIN IDS_2148 "CH Flightstick Pro" IDS_2149 "Microsoft SideWinder Pad" IDS_2150 "Thrustmaster Flight Control System" - IDS_2151 "Disabled" + IDS_2151 "CD-ROM images (*.ISO;*.CUE)\0*.ISO;*.CUE\0All files (*.*)\0*.*\0" IDS_2152 "None" IDS_2153 "AT Fixed Disk Adapter" IDS_2154 "Internal IDE" IDS_2155 "IRQ %i" - IDS_2156 "MFM (%01i:%01i)" - IDS_2157 "IDE (PIO+DMA) (%01i:%01i)" - IDS_2158 "SCSI (%02i:%02i)" - IDS_2159 "Invalid number of cylinders (valid values are between 1 and 1023)" - IDS_2160 "%" PRIu64 - IDS_2161 "Genius Bus mouse" - IDS_2162 "Amstrad mouse" - IDS_2163 "Attempting to create a spuriously large hard disk image" - IDS_2164 "Invalid number of sectors (valid values are between 1 and 99)" - IDS_2165 "MFM" - IDS_2166 "XT IDE" - IDS_2167 "RLL" - IDS_2168 "IDE (PIO-only)" - IDS_2169 "%01i:%01i" - IDS_2170 "Custom..." - IDS_2171 "%" PRIu64 " MB (CHS: %" PRIu64 ", %" PRIu64 ", %" PRIu64 ")" - IDS_2172 "Hard disk images (*.HDI;*.HDX;*.IMA;*.IMG)\0*.HDI;*.HDX;*.IMA;*.IMG\0All files (*.*)\0*.*\0" - IDS_2173"All floppy images (*.0??;*.12;*.144;*.360;*.720;*.86F;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FDF;*.FLP;*.HDM;*.IMA;*.IMD;*.IMG;*.TD0;*.VFD;*.XDF)\0*.0??;*.12;*.144;*.360;*.720;*.86F;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FDF;*.FLP;*.HDM;*.IMA;*.IMD;*.IMG;*.TD0;*.VFD;*.XDF\0Advanced sector-based images (*.IMD;*.TD0)\0*.IMD;*.TD0\0Basic sector-based images (*.0??;*.12;*.144;*.360;*.720;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FDF;*.FLP;*.HDM;*.IMA;*.IMG;*.VFD;*.XDF)\0*.0??;*.12;*.144;*.360;*.720;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FDF;*.FLP;*.HDM;*.IMA;*.IMG;*.VFD;*.XDF\0Flux images (*.FDI)\0*.FDI\0Surface-based images (*.86F)\0*.86F\0All files (*.*)\0*.*\0" - IDS_2174 "Configuration files (*.CFG)\0*.CFG\0All files (*.*)\0*.*\0" - IDS_2175 "CD-ROM image (*.ISO;*.CUE)\0*.ISO;*.CUE\0All files (*.*)\0*.*\0" - IDS_2176 "Use CTRL+ALT+PAGE DOWN to return to windowed mode" - IDS_2177 "Olivetti M24 mouse" - IDS_2178 "This image exists and will be overwritten.\nAre you sure you want to use it?" - IDS_2179 "Floppy %i (%s): %ws" - IDS_2180 "CD-ROM %i: %ws" - IDS_2181 "MFM hard disk" - IDS_2182 "IDE hard disk (PIO-only)" - IDS_2183 "IDE hard disk (PIO and DMA)" - IDS_2184 "SCSI hard disk" - IDS_2185 "(empty)" - IDS_2186 "(host drive %c:)" - IDS_2187 "Custom (large)..." - IDS_2188 "Type" - IDS_2189 "ATAPI (PIO-only)" - IDS_2190 "ATAPI (PIO and DMA)" - IDS_2191 "ATAPI (PIO-only) (%01i:%01i)" - IDS_2192 "ATAPI (PIO and DMA) (%01i:%01i)" - IDS_2193 "Use CTRL+ALT+PAGE DOWN to return to windowed mode" - IDS_2194 "Unable to create bitmap file: %s" - IDS_2195 "IDE (PIO-only) (%01i:%01i)" - IDS_2196 "Add New Hard Disk" - IDS_2197 "Add Existing Hard Disk" - IDS_2198 "SCSI removable disk %i: %s" - IDS_2199 "USB is not yet supported" - IDS_2200 "Invalid PCap device" - IDS_2201 "&Notify disk change" - IDS_2202 "SCSI (removable)" - IDS_2203 "SCSI (removable) (%02i:%02i)" - IDS_2204 "Pcap Library Not Available" - IDS_2205 "RLL (%01i:%01i)" - IDS_2206 "XT IDE (%01i:%01i)" - IDS_2207 "RLL hard disk" - IDS_2208 "XT IDE hard disk" - IDS_2209 "IDE (PIO and DMA)" - IDS_2210 "SCSI" - IDS_2211 "&New image..." - IDS_2212 "Existing image..." - IDS_2213 "Existing image (&Write-protected)..." - IDS_2214 "E&ject" - IDS_2215 "&Mute" - IDS_2216 "E&mpty" - IDS_2217 "&Reload previous image" - IDS_2218 "&Image..." - IDS_2219 "PCap failed to set up because it may not be initialized" - IDS_2220 "Image (&Write-protected)..." - IDS_2221 "Turbo" - IDS_2222 "On" - IDS_2223 "Off" - IDS_2224 "Logitech 3-button mouse (serial)" - IDS_2225 "Specify the NVR Path" - IDS_2226 "" - IDS_2227 "English (United States)" + IDS_2156 "%" PRIu64 + IDS_2157 "%" PRIu64 " MB (CHS: %" PRIu64 ", %" PRIu64 ", %" PRIu64 ")" + IDS_2158 "Floppy %i (%s): %ws" + IDS_2159"All floppy images (*.0??;*.12;*.144;*.360;*.720;*.86F;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FDF;*.FLP;*.HDM;*.IMA;*.IMD;*.IMG;*.TD0;*.VFD;*.XDF)\0*.0??;*.12;*.144;*.360;*.720;*.86F;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FDF;*.FLP;*.HDM;*.IMA;*.IMD;*.IMG;*.TD0;*.VFD;*.XDF\0Advanced sector-based images (*.IMD;*.TD0)\0*.IMD;*.TD0\0Basic sector-based images (*.0??;*.12;*.144;*.360;*.720;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FDF;*.FLP;*.HDM;*.IMA;*.IMG;*.VFD;*.XDF)\0*.0??;*.12;*.144;*.360;*.720;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FDF;*.FLP;*.HDM;*.IMA;*.IMG;*.VFD;*.XDF\0Flux images (*.FDI)\0*.FDI\0Surface-based images (*.86F)\0*.86F\0All files (*.*)\0*.*\0" + IDS_2160 "Configuration files (*.CFG)\0*.CFG\0All files (*.*)\0*.*\0" + IDS_2161 "&New image..." + IDS_2162 "Existing image..." + IDS_2163 "Existing image (&Write-protected)..." + IDS_2164 "E&ject" + IDS_2165 "&Mute" + IDS_2166 "E&mpty" + IDS_2167 "&Reload previous image" + IDS_2168 "&Image..." + IDS_2169 "Image (&Write-protected)..." + + IDS_3072 "None" + IDS_3073 "[Bus] Bus mouse" + IDS_3074 "[Serial] Mouse Systems mouse" + IDS_3075 "[Serial] Microsoft 2-button mouse" + IDS_3076 "[Serial] Logitech 3-button mouse" + IDS_3077 "[Serial] Microsoft wheel mouse" + IDS_3078 "[PS/2] 2-button mouse" + IDS_3079 "[PS/2] Microsoft Intellimouse" + IDS_3080 "[Proprietary] Amstrad mouse" + IDS_3081 "[Proprietary] Olivetti M24 mouse" + + IDS_4096 "Hard disk (%s)" + IDS_4097 "%01i:%01i" + IDS_4098 "%i" + IDS_4099 "Disabled" + IDS_4100 "Custom..." + IDS_4101 "Custom (large)..." + IDS_4102 "Add New Hard Disk" + IDS_4103 "Add Existing Hard Disk" + IDS_4104 "Attempting to create a HDI image larger than 4 GB" + IDS_4105 "Attempting to create a spuriously large hard disk image" + IDS_4106 "Hard disk images (*.HDI;*.HDX;*.IMA;*.IMG)\0*.HDI;*.HDX;*.IMA;*.IMG\0All files (*.*)\0*.*\0" + IDS_4107 "Unable to open the file for read" + IDS_4108 "Unable to open the file for write" + IDS_4109 "HDI or HDX image with a sector size that is not 512 are not supported" + IDS_4110 "USB is not yet supported" + IDS_4111 "This image exists and will be overwritten.\nAre you sure you want to use it?" + IDS_4112 "Please enter a valid file name" + IDS_4113 "Remember to partition and format the new drive" + IDS_4114 "MFM or ESDI CD-ROM drives never existed" + IDS_4115 "Removable disk %i (SCSI): %ws" + + IDS_4352 "MFM" + IDS_4353 "XT IDE" + IDS_4354 "ESDI" + IDS_4355 "IDE (PIO-only)" + IDS_4356 "IDE (PIO+DMA)" + IDS_4357 "SCSI" + IDS_4358 "SCSI (removable)" + + IDS_4608 "MFM (%01i:%01i)" + IDS_4609 "XT IDE (%01i:%01i)" + IDS_4610 "ESDI (%01i:%01i)" + IDS_4611 "IDE (PIO-only) (%01i:%01i)" + IDS_4612 "IDE (PIO+DMA) (%01i:%01i)" + IDS_4613 "SCSI (%02i:%02i)" + IDS_4614 "SCSI (removable) (%02i:%02i)" + + IDS_5120 "CD-ROM %i (%s): %s" + + IDS_5376 "Disabled" + IDS_5377 "" + IDS_5378 "" + IDS_5379 "" + IDS_5380 "ATAPI (PIO-only)" + IDS_5381 "ATAPI (PIO and DMA)" + IDS_5382 "SCSI" + + IDS_5632 "Disabled" + IDS_5633 "" + IDS_5634 "" + IDS_5635 "" + IDS_5636 "ATAPI (PIO-only) (%01i:%01i)" + IDS_5637 "ATAPI (PIO and DMA) (%01i:%01i)" + IDS_5638 "SCSI (%02i:%02i)" + + IDS_6144 "English (United States)" END -#define IDS_LANG_ENUS IDS_2227 +#define IDS_LANG_ENUS IDS_6144 #ifndef _MAC diff --git a/src/WIN/plat_ui.h b/src/WIN/plat_ui.h index 7bc6d35d9..120a04e55 100644 --- a/src/WIN/plat_ui.h +++ b/src/WIN/plat_ui.h @@ -17,6 +17,10 @@ extern wchar_t *plat_get_string_from_id(int i); #ifndef IDS_2079 #define IDS_2079 2079 #endif + +#ifndef IDS_2139 +#define IDS_2139 2139 +#endif #endif extern void plat_msgbox_fatal(char *string); diff --git a/src/WIN/resource.h b/src/WIN/resource.h index 02fa21a9f..9fa250250 100644 --- a/src/WIN/resource.h +++ b/src/WIN/resource.h @@ -288,11 +288,11 @@ #define IDS_2136 2136 // "Slow VLB/PCI" #define IDS_2137 2137 // "Mid VLB/PCI" #define IDS_2138 2138 // "Fast VLB/PCI" -#define IDS_2139 2139 // "Microsoft 2-button mouse (serial)" -#define IDS_2140 2140 // "Mouse Systems mouse (serial)" -#define IDS_2141 2141 // "2-button mouse (PS/2)" -#define IDS_2142 2142 // "Microsoft Intellimouse (PS/2)" -#define IDS_2143 2143 // "Bus mouse" +#define IDS_2139 2139 +#define IDS_2140 2140 +#define IDS_2141 2141 +#define IDS_2142 2142 +#define IDS_2143 2143 #define IDS_2144 2144 // "Standard 2-button joystick(s)" #define IDS_2145 2145 // "Standard 4-button joystick" #define IDS_2146 2146 // "Standard 6-button joystick" @@ -310,8 +310,8 @@ #define IDS_2158 2158 // "SCSI (%02i:%02i)" #define IDS_2159 2159 // "Invalid number of cylinders.." #define IDS_2160 2160 // "%" PRIu64 -#define IDS_2161 2161 // "Genius Bus mouse" -#define IDS_2162 2162 // "Amstrad mouse" +#define IDS_2161 2161 +#define IDS_2162 2162 #define IDS_2163 2163 // "Attempting to create a spuriously.." #define IDS_2164 2164 // "Invalid number of sectors.." #define IDS_2165 2165 // "MFM" @@ -319,67 +319,86 @@ #define IDS_2167 2167 // "RLL" #define IDS_2168 2168 // "IDE (PIO-only)" #define IDS_2169 2169 // "%01i:%01i" -#define IDS_2170 2170 // "Custom..." -#define IDS_2171 2171 // "%" PRIu64 " MB (CHS: %" .. -#define IDS_2172 2172 // "Hard disk images .." -#define IDS_2173 2173 // "All floppy images .." -#define IDS_2174 2174 // "Configuration files .." -#define IDS_2175 2175 // "CD-ROM image .." -#define IDS_2176 2176 // "Use CTRL+ALT+PAGE DOWN .." -#define IDS_2177 2177 // "Olivetti M24 mouse" -#define IDS_2178 2178 // "This image exists and will.." -#define IDS_2179 2179 // "Floppy %i (%s): %ws" -#define IDS_2180 2180 // "CD-ROM %i: %ws" -#define IDS_2181 2181 // "MFM hard disk" -#define IDS_2182 2182 // "IDE hard disk (PIO-only)" -#define IDS_2183 2183 // "IDE hard disk (PIO and DMA)" -#define IDS_2184 2184 // "SCSI hard disk" -#define IDS_2185 2185 // "(empty)" -#define IDS_2186 2186 // "(host drive %c:)" -#define IDS_2187 2187 // "Custom (large)..." -#define IDS_2188 2188 // "Type" -#define IDS_2189 2189 // "ATAPI (PIO-only)" -#define IDS_2190 2190 // "ATAPI (PIO and DMA)" -#define IDS_2191 2191 // "ATAPI (PIO-only) (%01i:%01i)" -#define IDS_2192 2192 // "ATAPI (PIO and DMA) (%01i:%01i)" -#define IDS_2193 2193 // "Use CTRL+ALT+PAGE DOWN to .." -#define IDS_2194 2194 // "Unable to create bitmap file: %s" -#define IDS_2195 2195 // "IDE (PIO-only) (%01i:%01i)" -#define IDS_2196 2196 // "Add New Hard Disk" -#define IDS_2197 2197 // "Add Existing Hard Disk" -#define IDS_2198 2198 // "SCSI removable disk %i: %s" -#define IDS_2199 2199 // "USB is not yet supported" -#define IDS_2200 2200 // "Invalid PCap device" -#define IDS_2201 2201 // "&Notify disk change" -#define IDS_2202 2202 // "SCSI (removable)" -#define IDS_2203 2203 // "SCSI (removable) (%02i:%02i)" -#define IDS_2204 2204 // "Pcap Library Not Available" -#define IDS_2205 2205 // "RLL (%01i:%01i)" -#define IDS_2206 2206 // "XT IDE (%01i:%01i)" -#define IDS_2207 2207 // "RLL hard disk" -#define IDS_2208 2208 // "XT IDE hard disk" -#define IDS_2209 2209 // "IDE (PIO and DMA)" -#define IDS_2210 2210 // "SCSI" -#define IDS_2211 2211 // "&New image..." -#define IDS_2212 2212 // "Existing image..." -#define IDS_2213 2213 // "Existing image (&Write-.." -#define IDS_2214 2214 // "E&ject" -#define IDS_2215 2215 // "&Mute" -#define IDS_2216 2216 // "E&mpty" -#define IDS_2217 2217 // "&Reload previous image" -#define IDS_2218 2218 // "&Image..." -#define IDS_2219 2219 // "PCap failed to set up .." -#define IDS_2220 2220 // "Image (&Write-protected)..." -#define IDS_2221 2221 // "Turbo" -#define IDS_2222 2222 // "On" -#define IDS_2223 2223 // "Off" -#define IDS_2224 2224 // "Logitech 3-button mouse (serial)" -#define IDS_2225 2225 // "Specify the NVR Path" -#define IDS_2226 2226 // "" -#define IDS_2227 2227 // "English (United States)" -#define IDS_LANG_ENUS IDS_2227 -#define STRINGS_NUM 180 +#define IDS_3072 3072 +#define IDS_3073 3073 +#define IDS_3074 3074 +#define IDS_3075 3075 +#define IDS_3076 3076 +#define IDS_3077 3077 +#define IDS_3078 3078 +#define IDS_3079 3079 +#define IDS_3080 3080 +#define IDS_3081 3081 + +#define IDS_4096 4096 +#define IDS_4097 4097 +#define IDS_4098 4098 +#define IDS_4099 4099 +#define IDS_4100 4100 +#define IDS_4101 4101 +#define IDS_4102 4102 +#define IDS_4103 4103 +#define IDS_4104 4104 +#define IDS_4105 4105 +#define IDS_4106 4106 +#define IDS_4107 4107 +#define IDS_4108 4108 +#define IDS_4109 4109 +#define IDS_4110 4110 +#define IDS_4111 4111 +#define IDS_4112 4112 +#define IDS_4113 4113 +#define IDS_4114 4114 +#define IDS_4115 4115 + +#define IDS_4352 4352 +#define IDS_4353 4353 +#define IDS_4354 4354 +#define IDS_4355 4355 +#define IDS_4356 4356 +#define IDS_4357 4357 +#define IDS_4358 4358 + +#define IDS_4608 4608 +#define IDS_4609 4609 +#define IDS_4610 4610 +#define IDS_4611 4611 +#define IDS_4612 4612 +#define IDS_4613 4613 +#define IDS_4614 4614 + +#define IDS_5120 5120 + +#define IDS_5376 5376 +#define IDS_5377 5377 +#define IDS_5378 5378 +#define IDS_5379 5379 +#define IDS_5380 5380 +#define IDS_5381 5381 +#define IDS_5382 5382 + +#define IDS_5632 5632 +#define IDS_5633 5633 +#define IDS_5634 5634 +#define IDS_5635 5635 +#define IDS_5636 5636 +#define IDS_5637 5637 +#define IDS_5638 5638 + +#define IDS_6144 6144 + +#define IDS_LANG_ENUS IDS_6144 + +#define STRINGS_NUM_2048 122 +#define STRINGS_NUM_3072 10 +#define STRINGS_NUM_4096 20 +#define STRINGS_NUM_4352 7 +#define STRINGS_NUM_4608 7 +#define STRINGS_NUM_5120 1 +#define STRINGS_NUM_5376 7 +#define STRINGS_NUM_5632 7 +#define STRINGS_NUM_6144 1 #define IDM_ABOUT 40001 diff --git a/src/WIN/win.c b/src/WIN/win.c index f368b56f4..1de2af41e 100644 --- a/src/WIN/win.c +++ b/src/WIN/win.c @@ -462,12 +462,12 @@ HMENU create_popup_menu(int part) void create_floppy_submenu(HMENU m, int id) { - AppendMenu(m, MF_STRING, IDM_FLOPPY_IMAGE_NEW | id, win_language_get_string_from_id(2211)); + AppendMenu(m, MF_STRING, IDM_FLOPPY_IMAGE_NEW | id, win_language_get_string_from_id(IDS_2161)); AppendMenu(m, MF_SEPARATOR, 0, 0); - AppendMenu(m, MF_STRING, IDM_FLOPPY_IMAGE_EXISTING | id, win_language_get_string_from_id(2212)); - AppendMenu(m, MF_STRING, IDM_FLOPPY_IMAGE_EXISTING_WP | id, win_language_get_string_from_id(2213)); + AppendMenu(m, MF_STRING, IDM_FLOPPY_IMAGE_EXISTING | id, win_language_get_string_from_id(IDS_2162)); + AppendMenu(m, MF_STRING, IDM_FLOPPY_IMAGE_EXISTING_WP | id, win_language_get_string_from_id(IDS_2163)); AppendMenu(m, MF_SEPARATOR, 0, 0); - AppendMenu(m, MF_STRING, IDM_FLOPPY_EJECT | id, win_language_get_string_from_id(2214)); + AppendMenu(m, MF_STRING, IDM_FLOPPY_EJECT | id, win_language_get_string_from_id(IDS_2164)); } void create_cdrom_submenu(HMENU m, int id) @@ -475,12 +475,12 @@ void create_cdrom_submenu(HMENU m, int id) int i = 0; WCHAR s[64]; - AppendMenu(m, MF_STRING, IDM_CDROM_MUTE | id, win_language_get_string_from_id(2215)); + AppendMenu(m, MF_STRING, IDM_CDROM_MUTE | id, win_language_get_string_from_id(IDS_2165)); AppendMenu(m, MF_SEPARATOR, 0, 0); - AppendMenu(m, MF_STRING, IDM_CDROM_EMPTY | id, win_language_get_string_from_id(2216)); - AppendMenu(m, MF_STRING, IDM_CDROM_RELOAD | id, win_language_get_string_from_id(2217)); + AppendMenu(m, MF_STRING, IDM_CDROM_EMPTY | id, win_language_get_string_from_id(IDS_2166)); + AppendMenu(m, MF_STRING, IDM_CDROM_RELOAD | id, win_language_get_string_from_id(IDS_2167)); AppendMenu(m, MF_SEPARATOR, 0, 0); - AppendMenu(m, MF_STRING, IDM_CDROM_IMAGE | id, win_language_get_string_from_id(2218)); + AppendMenu(m, MF_STRING, IDM_CDROM_IMAGE | id, win_language_get_string_from_id(IDS_2168)); if (host_cdrom_drive_available_num == 0) { @@ -536,13 +536,13 @@ check_menu_items: void create_removable_disk_submenu(HMENU m, int id) { - AppendMenu(m, MF_STRING, IDM_RDISK_EJECT | id, win_language_get_string_from_id(2216)); - AppendMenu(m, MF_STRING, IDM_RDISK_RELOAD | id, win_language_get_string_from_id(2217)); + AppendMenu(m, MF_STRING, IDM_RDISK_EJECT | id, win_language_get_string_from_id(IDS_2166)); + AppendMenu(m, MF_STRING, IDM_RDISK_RELOAD | id, win_language_get_string_from_id(IDS_2167)); AppendMenu(m, MF_SEPARATOR, 0, 0); - AppendMenu(m, MF_STRING, IDM_RDISK_SEND_CHANGE | id, win_language_get_string_from_id(2201)); + AppendMenu(m, MF_STRING, IDM_RDISK_SEND_CHANGE | id, win_language_get_string_from_id(IDS_2142)); AppendMenu(m, MF_SEPARATOR, 0, 0); - AppendMenu(m, MF_STRING, IDM_RDISK_IMAGE | id, win_language_get_string_from_id(2218)); - AppendMenu(m, MF_STRING, IDM_RDISK_IMAGE_WP | id, win_language_get_string_from_id(2220)); + AppendMenu(m, MF_STRING, IDM_RDISK_IMAGE | id, win_language_get_string_from_id(IDS_2168)); + AppendMenu(m, MF_STRING, IDM_RDISK_IMAGE_WP | id, win_language_get_string_from_id(IDS_2169)); } void get_executable_name(wchar_t *s, int size) @@ -789,7 +789,7 @@ void create_floppy_tip(int part) mbstowcs(wtext, fdd_getname(fdd_get_type(drive)), strlen(fdd_getname(fdd_get_type(drive))) + 1); if (wcslen(discfns[drive]) == 0) { - _swprintf(tempTip, win_language_get_string_from_id(2179), drive + 1, wtext, win_language_get_string_from_id(2185)); + _swprintf(tempTip, win_language_get_string_from_id(IDS_2158), drive + 1, wtext, win_language_get_string_from_id(IDS_2057)); } else { @@ -809,27 +809,36 @@ void create_cdrom_tip(int part) WCHAR wtext[512]; WCHAR tempTip[512]; + WCHAR *szText; + int id; + int drive = sb_part_meanings[part] & 0xf; + int bus = cdrom_drives[drive].bus_type; + + id = IDS_4352 + (bus - 1); + + szText = (WCHAR *) win_language_get_string_from_id(id); + if (cdrom_drives[drive].host_drive == 200) { if (wcslen(cdrom_image[drive].image_path) == 0) { - _swprintf(tempTip, win_language_get_string_from_id(2180), drive + 1, win_language_get_string_from_id(2185)); + _swprintf(tempTip, win_language_get_string_from_id(IDS_5120), drive + 1, szText, win_language_get_string_from_id(IDS_2057)); } else { - _swprintf(tempTip, win_language_get_string_from_id(2180), drive + 1, cdrom_image[drive].image_path); + _swprintf(tempTip, win_language_get_string_from_id(IDS_5120), drive + 1, szText, cdrom_image[drive].image_path); } } - else if (cdrom_drives[drive].host_drive < 0x41) + else if ((cdrom_drives[drive].host_drive >= 'A') && (cdrom_drives[drive].host_drive <= 'Z')) { - _swprintf(tempTip, win_language_get_string_from_id(2180), drive + 1, win_language_get_string_from_id(2185)); + _swprintf(wtext, win_language_get_string_from_id(IDS_2058), cdrom_drives[drive].host_drive & ~0x20); + _swprintf(tempTip, win_language_get_string_from_id(IDS_5120), drive + 1, szText, wtext); } else { - _swprintf(wtext, win_language_get_string_from_id(2186), cdrom_drives[drive].host_drive & ~0x20); - _swprintf(tempTip, win_language_get_string_from_id(2180), drive + 1, wtext); + _swprintf(tempTip, win_language_get_string_from_id(IDS_5120), drive + 1, szText, win_language_get_string_from_id(IDS_2057)); } if (sbTips[part] != NULL) @@ -848,11 +857,11 @@ void create_removable_hd_tip(int part) if (wcslen(hdc[drive].fn) == 0) { - _swprintf(tempTip, win_language_get_string_from_id(2198), drive, win_language_get_string_from_id(2185)); + _swprintf(tempTip, win_language_get_string_from_id(IDS_4115), drive, win_language_get_string_from_id(IDS_2057)); } else { - _swprintf(tempTip, win_language_get_string_from_id(2198), drive, hdc[drive].fn); + _swprintf(tempTip, win_language_get_string_from_id(IDS_4115), drive, hdc[drive].fn); } if (sbTips[part] != NULL) @@ -865,41 +874,24 @@ void create_removable_hd_tip(int part) void create_hd_tip(int part) { + WCHAR tempTip[512]; WCHAR *szText; - int id = 2181; + int id; int bus = sb_part_meanings[part] & 0xf; - switch(bus) - { - case HDD_BUS_MFM: - id = 2181; - break; - case HDD_BUS_RLL: - id = 2207; - break; - case HDD_BUS_XTIDE: - id = 2208; - break; - case HDD_BUS_IDE_PIO_ONLY: - id = 2182; - break; - case HDD_BUS_IDE_PIO_AND_DMA: - id = 2183; - break; - case HDD_BUS_SCSI: - id = 2184; - break; - } + id = IDS_4352 + (bus - 1); szText = (WCHAR *) win_language_get_string_from_id(id); + _swprintf(tempTip, win_language_get_string_from_id(IDS_4096), szText); + if (sbTips[part] != NULL) { free(sbTips[part]); } - sbTips[part] = (WCHAR *) malloc((wcslen(szText) << 1) + 2); - wcscpy(sbTips[part], szText); + sbTips[part] = (WCHAR *) malloc((wcslen(tempTip) << 1) + 2); + wcscpy(sbTips[part], tempTip); } void update_tip(int meaning) @@ -1920,7 +1912,7 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM if (video_fullscreen_first) { video_fullscreen_first = 0; - msgbox_info(ghwnd, IDS_2193); + msgbox_info(ghwnd, IDS_2074); } startblit(); @@ -2068,7 +2060,7 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM case IDM_CONFIG_LOAD: pause = 1; - if (!file_dlg_st(hwnd, IDS_2174, "", 0)) + if (!file_dlg_st(hwnd, IDS_2160, "", 0)) { if (msgbox_reset_yn(ghwnd) == IDYES) { @@ -2133,7 +2125,7 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM case IDM_CONFIG_SAVE: pause = 1; - if (!file_dlg_st(hwnd, IDS_2174, "", 1)) + if (!file_dlg_st(hwnd, IDS_2160, "", 1)) { config_save(wopenfilestring); } @@ -2369,7 +2361,7 @@ LRESULT CALLBACK StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPAR break; } - ret = file_dlg_w_st(hwnd, IDS_2173, discfns[id], 0); + ret = file_dlg_w_st(hwnd, IDS_2159, discfns[id], 0); if (!ret) { disc_close(id); @@ -2425,7 +2417,7 @@ LRESULT CALLBACK StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPAR break; } - if (!file_dlg_w_st(hwnd, IDS_2175, cdrom_image[id].image_path, 0)) + if (!file_dlg_w_st(hwnd, IDS_2151, cdrom_image[id].image_path, 0)) { cdrom_drives[id].prev_host_drive = cdrom_drives[id].host_drive; wcscpy(temp_image_path, wopenfilestring); @@ -2514,7 +2506,7 @@ LRESULT CALLBACK StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPAR case IDM_RDISK_IMAGE: case IDM_RDISK_IMAGE_WP: id = item_params & 0x001f; - ret = file_dlg_w_st(hwnd, IDS_2172, hdc[id].fn, id); + ret = file_dlg_w_st(hwnd, IDS_4106, hdc[id].fn, id); if (!ret) { removable_disk_unload(id); diff --git a/src/WIN/win_ddraw_screenshot.cc b/src/WIN/win_ddraw_screenshot.cc index b98a207d1..292c0eb93 100644 --- a/src/WIN/win_ddraw_screenshot.cc +++ b/src/WIN/win_ddraw_screenshot.cc @@ -118,7 +118,7 @@ void SaveBitmap(wchar_t *szFilename,HBITMAP hBitmap) if((fp = _wfopen(szFilename,L"wb"))==NULL) { - _swprintf(szMessage, win_language_get_string_from_id(2194), szFilename); + _swprintf(szMessage, win_language_get_string_from_id(IDS_2073), szFilename); msgbox_error_wstr(ghwnd, szMessage); break; } diff --git a/src/WIN/win_language.c b/src/WIN/win_language.c index 84eabd1b7..e2bf2b24a 100644 --- a/src/WIN/win_language.c +++ b/src/WIN/win_language.c @@ -37,7 +37,20 @@ LCID dwLanguage; uint32_t dwLangID, dwSubLangID; -WCHAR lpResourceString[STRINGS_NUM][512]; +typedef struct +{ + WCHAR lpString[512]; +} resource_string_t; + +resource_string_t *lpResourceString2048; +resource_string_t *lpResourceString3072; +resource_string_t *lpResourceString4096; +resource_string_t *lpResourceString4352; +resource_string_t *lpResourceString4608; +resource_string_t *lpResourceString5120; +resource_string_t *lpResourceString5376; +resource_string_t *lpResourceString5632; +resource_string_t *lpResourceString6144; char openfilestring[260]; WCHAR wopenfilestring[260]; @@ -51,15 +64,65 @@ void win_language_load_common_strings() { int i = 0; - for (i = 0; i < STRINGS_NUM; i++) + lpResourceString2048 = (resource_string_t *) malloc(STRINGS_NUM_2048 * sizeof(resource_string_t)); + lpResourceString3072 = (resource_string_t *) malloc(STRINGS_NUM_3072 * sizeof(resource_string_t)); + lpResourceString4096 = (resource_string_t *) malloc(STRINGS_NUM_4096 * sizeof(resource_string_t)); + lpResourceString4352 = (resource_string_t *) malloc(STRINGS_NUM_4352 * sizeof(resource_string_t)); + lpResourceString4608 = (resource_string_t *) malloc(STRINGS_NUM_4608 * sizeof(resource_string_t)); + lpResourceString5120 = (resource_string_t *) malloc(STRINGS_NUM_5120 * sizeof(resource_string_t)); + lpResourceString5376 = (resource_string_t *) malloc(STRINGS_NUM_5376 * sizeof(resource_string_t)); + lpResourceString5632 = (resource_string_t *) malloc(STRINGS_NUM_5632 * sizeof(resource_string_t)); + lpResourceString6144 = (resource_string_t *) malloc(STRINGS_NUM_6144 * sizeof(resource_string_t)); + + for (i = 0; i < STRINGS_NUM_2048; i++) { - LoadString(hinstance, 2048 + i, lpResourceString[i], 512); + LoadString(hinstance, 2048 + i, lpResourceString2048[i].lpString, 512); + } + + for (i = 0; i < STRINGS_NUM_3072; i++) + { + LoadString(hinstance, 3072 + i, lpResourceString3072[i].lpString, 512); + } + + for (i = 0; i < STRINGS_NUM_4096; i++) + { + LoadString(hinstance, 4096 + i, lpResourceString4096[i].lpString, 512); + } + + for (i = 0; i < STRINGS_NUM_4352; i++) + { + LoadString(hinstance, 4352 + i, lpResourceString4352[i].lpString, 512); + } + + for (i = 0; i < STRINGS_NUM_4608; i++) + { + LoadString(hinstance, 4608 + i, lpResourceString4608[i].lpString, 512); + } + + for (i = 0; i < STRINGS_NUM_5120; i++) + { + LoadString(hinstance, 5120 + i, lpResourceString5120[i].lpString, 512); + } + + for (i = 0; i < STRINGS_NUM_5376; i++) + { + LoadString(hinstance, 5376 + i, lpResourceString5376[i].lpString, 512); + } + + for (i = 0; i < STRINGS_NUM_5632; i++) + { + LoadString(hinstance, 5632 + i, lpResourceString5632[i].lpString, 512); + } + + for (i = 0; i < STRINGS_NUM_6144; i++) + { + LoadString(hinstance, 6144 + i, lpResourceString6144[i].lpString, 512); } } LPTSTR win_language_get_settings_category(int i) { - return lpResourceString[17 + i]; + return lpResourceString2048[17 + i].lpString; } void win_language_update() @@ -81,7 +144,42 @@ void win_language_check() LPTSTR win_language_get_string_from_id(int i) { - return lpResourceString[i - 2048]; + if ((i >= 2048) && (i <= 3071)) + { + return lpResourceString2048[i - 2048].lpString; + } + else if ((i >= 3072) && (i <= 4095)) + { + return lpResourceString3072[i - 3072].lpString; + } + else if ((i >= 4096) && (i <= 4351)) + { + return lpResourceString4096[i - 4096].lpString; + } + else if ((i >= 4352) && (i <= 4607)) + { + return lpResourceString4352[i - 4352].lpString; + } + else if ((i >= 4608) && (i <= 5119)) + { + return lpResourceString4608[i - 4608].lpString; + } + else if ((i >= 5120) && (i <= 5375)) + { + return lpResourceString5120[i - 5120].lpString; + } + else if ((i >= 5376) && (i <= 5631)) + { + return lpResourceString5376[i - 5376].lpString; + } + else if ((i >= 5632) && (i <= 6143)) + { + return lpResourceString5632[i - 5632].lpString; + } + else + { + return lpResourceString6144[i - 6144].lpString; + } } wchar_t *plat_get_string_from_id(int i) @@ -91,37 +189,37 @@ wchar_t *plat_get_string_from_id(int i) LPTSTR win_language_get_string_from_string(char *str) { - return lpResourceString[atoi(str) - 2048]; + return win_language_get_string_from_id(atoi(str)); } int msgbox_reset(HWND hwndParent) { - return MessageBox(hwndParent, lpResourceString[3], lpResourceString[0], MB_YESNOCANCEL | MB_ICONQUESTION); + return MessageBox(hwndParent, lpResourceString2048[3].lpString, lpResourceString2048[0].lpString, MB_YESNOCANCEL | MB_ICONQUESTION); } int msgbox_reset_yn(HWND hwndParent) { - return MessageBox(hwndParent, lpResourceString[3], lpResourceString[0], MB_YESNO | MB_ICONQUESTION); + return MessageBox(hwndParent, lpResourceString2048[3].lpString, lpResourceString2048[0].lpString, MB_YESNO | MB_ICONQUESTION); } int msgbox_question(HWND hwndParent, int i) { - return MessageBox(hwndParent, win_language_get_string_from_id(i), lpResourceString[0], MB_YESNO | MB_ICONQUESTION); + return MessageBox(hwndParent, win_language_get_string_from_id(i), lpResourceString2048[0].lpString, MB_YESNO | MB_ICONQUESTION); } void msgbox_info(HWND hwndParent, int i) { - MessageBox(hwndParent, win_language_get_string_from_id(i), lpResourceString[0], MB_OK | MB_ICONINFORMATION); + MessageBox(hwndParent, win_language_get_string_from_id(i), lpResourceString2048[0].lpString, MB_OK | MB_ICONINFORMATION); } void msgbox_info_wstr(HWND hwndParent, WCHAR *wstr) { - MessageBox(hwndParent, wstr, lpResourceString[0], MB_OK | MB_ICONINFORMATION); + MessageBox(hwndParent, wstr, lpResourceString2048[0].lpString, MB_OK | MB_ICONINFORMATION); } void msgbox_error(HWND hwndParent, int i) { - MessageBox(hwndParent, win_language_get_string_from_id(i), lpResourceString[1], MB_OK | MB_ICONWARNING); + MessageBox(hwndParent, win_language_get_string_from_id(i), lpResourceString2048[1].lpString, MB_OK | MB_ICONWARNING); } void plat_msgbox_error(int i) @@ -131,12 +229,12 @@ void plat_msgbox_error(int i) void msgbox_error_wstr(HWND hwndParent, WCHAR *wstr) { - MessageBox(hwndParent, wstr, lpResourceString[1], MB_OK | MB_ICONWARNING); + MessageBox(hwndParent, wstr, lpResourceString2048[1].lpString, MB_OK | MB_ICONWARNING); } void msgbox_critical(HWND hwndParent, int i) { - MessageBox(hwndParent, win_language_get_string_from_id(i), lpResourceString[2], MB_OK | MB_ICONERROR); + MessageBox(hwndParent, win_language_get_string_from_id(i), lpResourceString2048[2].lpString, MB_OK | MB_ICONERROR); } void msgbox_fatal(HWND hwndParent, char *string) @@ -146,7 +244,7 @@ void msgbox_fatal(HWND hwndParent, char *string) mbstowcs(lptsTemp, string, strlen(string) + 1); - MessageBox(hwndParent, lptsTemp, lpResourceString[2], MB_OK | MB_ICONERROR); + MessageBox(hwndParent, lptsTemp, lpResourceString2048[2].lpString, MB_OK | MB_ICONERROR); free(lptsTemp); } diff --git a/src/WIN/win_settings.c b/src/WIN/win_settings.c index eb2866f7c..32c7016b4 100644 --- a/src/WIN/win_settings.c +++ b/src/WIN/win_settings.c @@ -624,7 +624,7 @@ static BOOL CALLBACK win_settings_machine_proc(HWND hdlg, UINT message, WPARAM w deviceconfig_open(hdlg, (void *)model_getdevice(temp_model)); break; case IDC_BUTTON_NVR_PATH: - p = BrowseFolder(temp_nvr_path, win_language_get_string_from_id(IDS_2225)); + p = BrowseFolder(temp_nvr_path, win_language_get_string_from_id(IDS_2056)); if (wcscmp(p, L"")) { memset(temp_nvr_path, 0, sizeof(temp_nvr_path)); @@ -900,40 +900,7 @@ static BOOL CALLBACK win_settings_input_proc(HWND hdlg, UINT message, WPARAM wPa if (mouse_valid(type, temp_model)) { - switch(c) - { - case MOUSE_TYPE_NONE: - str_id = IDS_2151; - break; - case MOUSE_TYPE_SERIAL: - default: - str_id = IDS_2139; - break; - case MOUSE_TYPE_PS2: - str_id = IDS_2141; - break; - case MOUSE_TYPE_PS2_MS: - str_id = IDS_2142; - break; - case MOUSE_TYPE_BUS: - str_id = IDS_2143; - break; - case MOUSE_TYPE_AMSTRAD: - str_id = IDS_2162; - break; - case MOUSE_TYPE_OLIM24: - str_id = IDS_2177; - break; - case MOUSE_TYPE_MSYSTEMS: - str_id = IDS_2140; - break; - case MOUSE_TYPE_LOGITECH: - str_id = IDS_2224; - break; - case MOUSE_TYPE_GENIUS: - str_id = IDS_2161; - break; - } + str_id = IDS_3072 + c; SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(str_id)); @@ -1498,7 +1465,7 @@ static BOOL CALLBACK win_settings_peripherals_proc(HWND hdlg, UINT message, WPAR recalc_hdd_list(hdlg, temp_model, 0); h=GetDlgItem(hdlg, IDC_COMBO_IDE_TER); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2151)); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(IDS_5376)); for (c = 0; c < 11; c++) { @@ -1516,7 +1483,7 @@ static BOOL CALLBACK win_settings_peripherals_proc(HWND hdlg, UINT message, WPAR } h=GetDlgItem(hdlg, IDC_COMBO_IDE_QUA); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(IDS_2151)); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(IDS_5376)); for (c = 0; c < 11; c++) { @@ -1921,41 +1888,36 @@ static void add_locations(HWND hdlg) lptsTemp = (LPTSTR) malloc(512); h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); - for (i = 0; i < 4; i++) + for (i = 0; i < 7; i++) { - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2165 + i)); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(IDS_4352 + i)); } - for (i = 0; i < 2; i++) - { - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2209 + i)); - } - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2202)); h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); for (i = 0; i < 8; i++) { - wsprintf(lptsTemp, win_language_get_string_from_id(2169), i >> 1, i & 1); + wsprintf(lptsTemp, win_language_get_string_from_id(IDS_4097), i >> 1, i & 1); SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); } h = GetDlgItem(hdlg, IDC_COMBO_HD_ID); for (i = 0; i < 16; i++) { - wsprintf(lptsTemp, win_language_get_string_from_id(2088), i); + wsprintf(lptsTemp, win_language_get_string_from_id(IDS_4098), i); SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); } h = GetDlgItem(hdlg, IDC_COMBO_HD_LUN); for (i = 0; i < 8; i++) { - wsprintf(lptsTemp, win_language_get_string_from_id(2088), i); + wsprintf(lptsTemp, win_language_get_string_from_id(IDS_4098), i); SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); } h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL_IDE); for (i = 0; i < 8; i++) { - wsprintf(lptsTemp, win_language_get_string_from_id(2169), i >> 1, i & 1); + wsprintf(lptsTemp, win_language_get_string_from_id(IDS_4097), i >> 1, i & 1); SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); } @@ -2010,16 +1972,6 @@ static void recalc_location_controls(HWND hdlg, int is_add_dlg) EnableWindow(h, TRUE); SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdc.mfm_channel : temp_hdc[hdlv_current_sel].mfm_channel, 0); break; - case HDD_BUS_RLL: /* RLL */ - h = GetDlgItem(hdlg, IDT_1722); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - - h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdc.rll_channel : temp_hdc[hdlv_current_sel].rll_channel, 0); - break; case HDD_BUS_XTIDE: /* XT IDE */ h = GetDlgItem(hdlg, IDT_1722); ShowWindow(h, SW_SHOW); @@ -2030,6 +1982,16 @@ static void recalc_location_controls(HWND hdlg, int is_add_dlg) EnableWindow(h, TRUE); SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdc.xtide_channel : temp_hdc[hdlv_current_sel].xtide_channel, 0); break; + case HDD_BUS_RLL: /* RLL */ + h = GetDlgItem(hdlg, IDT_1722); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + + h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdc.rll_channel : temp_hdc[hdlv_current_sel].rll_channel, 0); + break; case HDD_BUS_IDE_PIO_ONLY: /* IDE (PIO-only) */ case HDD_BUS_IDE_PIO_AND_DMA: /* IDE (PIO and DMA) */ h = GetDlgItem(hdlg, IDT_1722); @@ -2197,25 +2159,25 @@ static void win_settings_hard_disks_update_item(HWND hwndList, int i, int column switch(temp_hdc[i].bus) { case HDD_BUS_MFM: - wsprintf(szText, win_language_get_string_from_id(2156), temp_hdc[i].mfm_channel >> 1, temp_hdc[i].mfm_channel & 1); - break; - case HDD_BUS_RLL: - wsprintf(szText, win_language_get_string_from_id(2205), temp_hdc[i].rll_channel >> 1, temp_hdc[i].rll_channel & 1); + wsprintf(szText, win_language_get_string_from_id(IDS_4608), temp_hdc[i].mfm_channel >> 1, temp_hdc[i].mfm_channel & 1); break; case HDD_BUS_XTIDE: - wsprintf(szText, win_language_get_string_from_id(2206), temp_hdc[i].xtide_channel >> 1, temp_hdc[i].xtide_channel & 1); + wsprintf(szText, win_language_get_string_from_id(IDS_4609), temp_hdc[i].xtide_channel >> 1, temp_hdc[i].xtide_channel & 1); + break; + case HDD_BUS_RLL: + wsprintf(szText, win_language_get_string_from_id(IDS_4610), temp_hdc[i].rll_channel >> 1, temp_hdc[i].rll_channel & 1); break; case HDD_BUS_IDE_PIO_ONLY: - wsprintf(szText, win_language_get_string_from_id(2195), temp_hdc[i].ide_channel >> 1, temp_hdc[i].ide_channel & 1); + wsprintf(szText, win_language_get_string_from_id(IDS_4611), temp_hdc[i].ide_channel >> 1, temp_hdc[i].ide_channel & 1); break; case HDD_BUS_IDE_PIO_AND_DMA: - wsprintf(szText, win_language_get_string_from_id(2157), temp_hdc[i].ide_channel >> 1, temp_hdc[i].ide_channel & 1); + wsprintf(szText, win_language_get_string_from_id(IDS_4612), temp_hdc[i].ide_channel >> 1, temp_hdc[i].ide_channel & 1); break; case HDD_BUS_SCSI: - wsprintf(szText, win_language_get_string_from_id(2158), temp_hdc[i].scsi_id, temp_hdc[i].scsi_lun); + wsprintf(szText, win_language_get_string_from_id(IDS_4613), temp_hdc[i].scsi_id, temp_hdc[i].scsi_lun); break; case HDD_BUS_SCSI_REMOVABLE: - wsprintf(szText, win_language_get_string_from_id(2203), temp_hdc[i].scsi_id, temp_hdc[i].scsi_lun); + wsprintf(szText, win_language_get_string_from_id(IDS_4614), temp_hdc[i].scsi_id, temp_hdc[i].scsi_lun); break; } lvI.pszText = szText; @@ -2228,25 +2190,25 @@ static void win_settings_hard_disks_update_item(HWND hwndList, int i, int column } else if (column == 2) { - wsprintf(szText, win_language_get_string_from_id(2088), temp_hdc[i].tracks); + wsprintf(szText, win_language_get_string_from_id(IDS_4098), temp_hdc[i].tracks); lvI.pszText = szText; lvI.iImage = 0; } else if (column == 3) { - wsprintf(szText, win_language_get_string_from_id(2088), temp_hdc[i].hpc); + wsprintf(szText, win_language_get_string_from_id(IDS_4098), temp_hdc[i].hpc); lvI.pszText = szText; lvI.iImage = 0; } else if (column == 4) { - wsprintf(szText, win_language_get_string_from_id(2088), temp_hdc[i].spt); + wsprintf(szText, win_language_get_string_from_id(IDS_4098), temp_hdc[i].spt); lvI.pszText = szText; lvI.iImage = 0; } else if (column == 5) { - wsprintf(szText, win_language_get_string_from_id(2088), (temp_hdc[i].tracks * temp_hdc[i].hpc * temp_hdc[i].spt) >> 11); + wsprintf(szText, win_language_get_string_from_id(IDS_4098), (temp_hdc[i].tracks * temp_hdc[i].hpc * temp_hdc[i].spt) >> 11); lvI.pszText = szText; lvI.iImage = 0; } @@ -2281,25 +2243,25 @@ static BOOL win_settings_hard_disks_recalc_list(HWND hwndList) switch(temp_hdc[i].bus) { case HDD_BUS_MFM: - wsprintf(szText, win_language_get_string_from_id(2156), temp_hdc[i].mfm_channel >> 1, temp_hdc[i].mfm_channel & 1); - break; - case HDD_BUS_RLL: - wsprintf(szText, win_language_get_string_from_id(2205), temp_hdc[i].rll_channel >> 1, temp_hdc[i].rll_channel & 1); + wsprintf(szText, win_language_get_string_from_id(IDS_4608), temp_hdc[i].mfm_channel >> 1, temp_hdc[i].mfm_channel & 1); break; case HDD_BUS_XTIDE: - wsprintf(szText, win_language_get_string_from_id(2206), temp_hdc[i].xtide_channel >> 1, temp_hdc[i].xtide_channel & 1); + wsprintf(szText, win_language_get_string_from_id(IDS_4609), temp_hdc[i].xtide_channel >> 1, temp_hdc[i].xtide_channel & 1); + break; + case HDD_BUS_RLL: + wsprintf(szText, win_language_get_string_from_id(IDS_4610), temp_hdc[i].rll_channel >> 1, temp_hdc[i].rll_channel & 1); break; case HDD_BUS_IDE_PIO_ONLY: - wsprintf(szText, win_language_get_string_from_id(2195), temp_hdc[i].ide_channel >> 1, temp_hdc[i].ide_channel & 1); + wsprintf(szText, win_language_get_string_from_id(IDS_4611), temp_hdc[i].ide_channel >> 1, temp_hdc[i].ide_channel & 1); break; case HDD_BUS_IDE_PIO_AND_DMA: - wsprintf(szText, win_language_get_string_from_id(2157), temp_hdc[i].ide_channel >> 1, temp_hdc[i].ide_channel & 1); + wsprintf(szText, win_language_get_string_from_id(IDS_4612), temp_hdc[i].ide_channel >> 1, temp_hdc[i].ide_channel & 1); break; case HDD_BUS_SCSI: - wsprintf(szText, win_language_get_string_from_id(2158), temp_hdc[i].scsi_id, temp_hdc[i].scsi_lun); + wsprintf(szText, win_language_get_string_from_id(IDS_4613), temp_hdc[i].scsi_id, temp_hdc[i].scsi_lun); break; case HDD_BUS_SCSI_REMOVABLE: - wsprintf(szText, win_language_get_string_from_id(2203), temp_hdc[i].scsi_id, temp_hdc[i].scsi_lun); + wsprintf(szText, win_language_get_string_from_id(IDS_4614), temp_hdc[i].scsi_id, temp_hdc[i].scsi_lun); break; } lvI.pszText = szText; @@ -2322,7 +2284,7 @@ static BOOL win_settings_hard_disks_recalc_list(HWND hwndList) } lvI.iSubItem = 2; - wsprintf(szText, win_language_get_string_from_id(2088), temp_hdc[i].tracks); + wsprintf(szText, win_language_get_string_from_id(IDS_4098), temp_hdc[i].tracks); lvI.pszText = szText; lvI.iItem = j; lvI.iImage = 0; @@ -2333,7 +2295,7 @@ static BOOL win_settings_hard_disks_recalc_list(HWND hwndList) } lvI.iSubItem = 3; - wsprintf(szText, win_language_get_string_from_id(2088), temp_hdc[i].hpc); + wsprintf(szText, win_language_get_string_from_id(IDS_4098), temp_hdc[i].hpc); lvI.pszText = szText; lvI.iItem = j; lvI.iImage = 0; @@ -2344,7 +2306,7 @@ static BOOL win_settings_hard_disks_recalc_list(HWND hwndList) } lvI.iSubItem = 4; - wsprintf(szText, win_language_get_string_from_id(2088), temp_hdc[i].spt); + wsprintf(szText, win_language_get_string_from_id(IDS_4098), temp_hdc[i].spt); lvI.pszText = szText; lvI.iItem = j; lvI.iImage = 0; @@ -2355,7 +2317,7 @@ static BOOL win_settings_hard_disks_recalc_list(HWND hwndList) } lvI.iSubItem = 5; - wsprintf(szText, win_language_get_string_from_id(2088), (temp_hdc[i].tracks * temp_hdc[i].hpc * temp_hdc[i].spt) >> 11); + wsprintf(szText, win_language_get_string_from_id(IDS_4098), (temp_hdc[i].tracks * temp_hdc[i].hpc * temp_hdc[i].spt) >> 11); lvI.pszText = szText; lvI.iItem = j; lvI.iImage = 0; @@ -2454,7 +2416,7 @@ static void set_edit_box_contents(HWND hdlg, int id, uint64_t val) WCHAR szText[256]; h = GetDlgItem(hdlg, id); - wsprintf(szText, win_language_get_string_from_id(2160), val); + wsprintf(szText, win_language_get_string_from_id(IDS_2156), val); SendMessage(h, WM_SETTEXT, (WPARAM) wcslen(szText), (LPARAM) szText); } @@ -2488,15 +2450,15 @@ static int hdconf_initialize_hdt_combo(HWND hdlg) { temp_size = hdt[i][0] * hdt[i][1] * hdt[i][2]; size_mb = temp_size >> 11; - wsprintf(szText, win_language_get_string_from_id(2171), size_mb, hdt[i][0], hdt[i][1], hdt[i][2]); + wsprintf(szText, win_language_get_string_from_id(IDS_2157), size_mb, hdt[i][0], hdt[i][1], hdt[i][2]); SendMessage(h, CB_ADDSTRING, 0, (LPARAM) szText); if ((tracks == hdt[i][0]) && (hpc == hdt[i][1]) && (spt == hdt[i][2])) { selection = i; } } - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2170)); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2187)); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(IDS_4100)); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(IDS_4101)); SendMessage(h, CB_SETCURSEL, selection, 0); return selection; } @@ -2555,7 +2517,7 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W hdc_ptr = &(temp_hdc[next_free_id]); } - SetWindowText(hdlg, win_language_get_string_from_id((existing & 1) ? 2197 : 2196)); + SetWindowText(hdlg, win_language_get_string_from_id((existing & 1) ? IDS_4103 : IDS_4102)); no_update = 1; spt = (existing & 1) ? 0 : 17; @@ -2656,7 +2618,7 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W if ((wcslen(hd_file_name) == 0) && (hdc_ptr->bus != HDD_BUS_SCSI_REMOVABLE)) { hdc_ptr->bus = HDD_BUS_DISABLED; - msgbox_error(hwndParentDialog, IDS_2056); + msgbox_error(hwndParentDialog, IDS_4112); return TRUE; } else if ((wcslen(hd_file_name) == 0) && (hdc_ptr->bus == HDD_BUS_SCSI_REMOVABLE)) @@ -2728,7 +2690,7 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W if (size >= 0x100000000ll) { fclose(f); - msgbox_error(hwndParentDialog, IDS_2058); + msgbox_error(hwndParentDialog, IDS_4104); return TRUE; } @@ -2751,7 +2713,7 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W if (size > 0xffffffffffffffffll) { fclose(f); - msgbox_error(hwndParentDialog, IDS_2163); + msgbox_error(hwndParentDialog, IDS_4105); return TRUE; } @@ -2791,7 +2753,7 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W } fclose(f); - msgbox_info(hwndParentDialog, IDS_2059); + msgbox_info(hwndParentDialog, IDS_4113); } hd_add_ok_common: @@ -2809,7 +2771,7 @@ hd_add_ok_common: return TRUE; case IDC_CFILE: - if (!file_dlg_w(hdlg, win_language_get_string_from_id(2172), L"", !(existing & 1))) + if (!file_dlg_w(hdlg, win_language_get_string_from_id(IDS_4106), L"", !(existing & 1))) { if (!(existing & 1)) { @@ -2817,7 +2779,7 @@ hd_add_ok_common: if (f != NULL) { fclose(f); - if (msgbox_question(ghwnd, IDS_2178) != IDYES) + if (msgbox_question(ghwnd, IDS_4111) != IDYES) { return FALSE; } @@ -2828,7 +2790,7 @@ hd_add_ok_common: if (f == NULL) { hdd_add_file_open_error: - msgbox_error(hwndParentDialog, (existing & 1) ? 2060 : 2057); + msgbox_error(hwndParentDialog, (existing & 1) ? IDS_4107 : IDS_4108); return TRUE; } if (existing & 1) @@ -2839,7 +2801,7 @@ hdd_add_file_open_error: fread(§or_size, 1, 4, f); if (sector_size != 512) { - msgbox_error(hwndParentDialog, IDS_2061); + msgbox_error(hwndParentDialog, IDS_4109); fclose(f); return TRUE; } @@ -3471,42 +3433,12 @@ int cdlv_current_sel; static int combo_id_to_string_id(int combo_id) { - switch (combo_id) - { - case CDROM_BUS_DISABLED: /* Disabled */ - default: - return 2151; - break; - case CDROM_BUS_ATAPI_PIO_ONLY: /* Atapi (PIO-only) */ - return 2189; - break; - case CDROM_BUS_ATAPI_PIO_AND_DMA: /* Atapi (PIA and DMA) */ - return 2190; - break; - case CDROM_BUS_SCSI: /* SCSI */ - return 2210; - break; - } + return IDS_5376 + combo_id; } static int combo_id_to_format_string_id(int combo_id) { - switch (combo_id) - { - case CDROM_BUS_DISABLED: /* Disabled */ - default: - return 2151; - break; - case CDROM_BUS_ATAPI_PIO_ONLY: /* Atapi (PIO-only) */ - return 2191; - break; - case CDROM_BUS_ATAPI_PIO_AND_DMA: /* Atapi (PIA and DMA) */ - return 2192; - break; - case CDROM_BUS_SCSI: /* SCSI */ - return 2158; - break; - } + return IDS_5632 + combo_id; } static BOOL win_settings_floppy_drives_image_list_init(HWND hwndList) @@ -3583,7 +3515,7 @@ static BOOL win_settings_floppy_drives_recalc_list(HWND hwndList) } else { - lvI.pszText = win_language_get_string_from_id(2151); + lvI.pszText = win_language_get_string_from_id(IDS_5376); } lvI.iItem = i; lvI.iImage = temp_fdd_types[i]; @@ -3592,7 +3524,7 @@ static BOOL win_settings_floppy_drives_recalc_list(HWND hwndList) return FALSE; lvI.iSubItem = 1; - lvI.pszText = win_language_get_string_from_id(temp_fdd_turbo[i] ? 2222 : 2223); + lvI.pszText = win_language_get_string_from_id(temp_fdd_turbo[i] ? IDS_2060 : IDS_2061); lvI.iItem = i; lvI.iImage = 0; @@ -3659,7 +3591,7 @@ static BOOL win_settings_floppy_drives_init_columns(HWND hwndList) lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; lvc.iSubItem = 0; - lvc.pszText = win_language_get_string_from_id(2188); + lvc.pszText = win_language_get_string_from_id(IDS_2143); lvc.cx = 292; lvc.fmt = LVCFMT_LEFT; @@ -3670,7 +3602,7 @@ static BOOL win_settings_floppy_drives_init_columns(HWND hwndList) } lvc.iSubItem = 1; - lvc.pszText = win_language_get_string_from_id(2221); + lvc.pszText = win_language_get_string_from_id(IDS_2059); lvc.cx = 100; lvc.fmt = LVCFMT_LEFT; @@ -3761,7 +3693,7 @@ static void win_settings_floppy_drives_update_item(HWND hwndList, int i) } else { - lvI.pszText = win_language_get_string_from_id(2151); + lvI.pszText = win_language_get_string_from_id(IDS_5376); } lvI.iImage = temp_fdd_types[i]; @@ -3771,7 +3703,7 @@ static void win_settings_floppy_drives_update_item(HWND hwndList, int i) } lvI.iSubItem = 1; - lvI.pszText = win_language_get_string_from_id(temp_fdd_turbo[i] ? 2222 : 2223); + lvI.pszText = win_language_get_string_from_id(temp_fdd_turbo[i] ? IDS_2060 : IDS_2061); lvI.iItem = i; lvI.iImage = 0; @@ -3953,7 +3885,7 @@ static BOOL CALLBACK win_settings_removable_devices_proc(HWND hdlg, UINT message { if (i == 0) { - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2151)); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(IDS_5376)); } else { diff --git a/src/config.c b/src/config.c index 2ebc6d3da..d7e62004f 100644 --- a/src/config.c +++ b/src/config.c @@ -1058,11 +1058,11 @@ static void loadconfig_network(void) { if ((network_ndev == 1) && strcmp(network_pcap, "none")) { - msgbox_error(ghwnd, IDS_2107); + msgbox_error(ghwnd, IDS_2140); } else if (network_dev_to_id(p) == -1) { - msgbox_error(ghwnd, IDS_2200); + msgbox_error(ghwnd, IDS_2141); } strcpy(network_pcap, "none"); @@ -1220,14 +1220,14 @@ static int config_string_to_bus(char *str, int cdrom) if (!strcmp(str, "usb")) { - msgbox_error(ghwnd, IDS_2199); + msgbox_error(ghwnd, IDS_4110); return 0; } return 0; no_mfm_cdrom: - msgbox_error(ghwnd, IDS_2095); + msgbox_error(ghwnd, IDS_4114); return 0; } diff --git a/src/mouse.c b/src/mouse.c index 9169a4fa9..123b88d35 100644 --- a/src/mouse.c +++ b/src/mouse.c @@ -35,16 +35,17 @@ static mouse_t mouse_none = { static mouse_t *mouse_list[] = { &mouse_none, - &mouse_serial_microsoft, /* 1 Microsoft Serial Mouse */ - &mouse_ps2_2_button, /* 2 PS/2 Mouse 2-button */ - &mouse_intellimouse, /* 3 PS/2 Intellimouse 3-button */ - &mouse_bus, /* 4 Logitech Bus Mouse 2-button */ - &mouse_amstrad, /* 5 Amstrad PC System Mouse */ - &mouse_olim24, /* 6 Olivetti M24 System Mouse */ - &mouse_msystems, /* 7 Mouse Systems */ - &mouse_serial_logitech, /* 1 Logitech 3-button Serial Mouse */ + &mouse_bus, /* 1 Logitech Bus Mouse 2-button */ + &mouse_msystems, /* 2 Mouse Systems */ + &mouse_serial_microsoft, /* 3 Microsoft Serial Mouse */ + &mouse_serial_logitech, /* 4 Logitech 3-button Serial Mouse */ + &mouse_serial_mswheel, /* 5 Microsoft Serial Wheel Mouse */ + &mouse_ps2_2_button, /* 6 PS/2 Mouse 2-button */ + &mouse_intellimouse, /* 7 PS/2 Intellimouse 3-button */ + &mouse_amstrad, /* 8 Amstrad PC System Mouse */ + &mouse_olim24, /* 9 Olivetti M24 System Mouse */ #if 0 - &mouse_genius, /* 8 Genius Bus Mouse */ + &mouse_genius, /* 10 Genius Bus Mouse */ #endif NULL }; diff --git a/src/mouse.h b/src/mouse.h index 21e1ff983..8eb2655cf 100644 --- a/src/mouse.h +++ b/src/mouse.h @@ -20,16 +20,19 @@ # define EMU_MOUSE_H -#define MOUSE_TYPE_NONE 0 -#define MOUSE_TYPE_SERIAL 1 /* Serial Mouse */ -#define MOUSE_TYPE_PS2 2 /* IBM PS/2 series Bus Mouse */ -#define MOUSE_TYPE_PS2_MS 3 /* Microsoft Intellimouse PS/2 */ -#define MOUSE_TYPE_BUS 4 /* Logitech/ATI Bus Mouse */ -#define MOUSE_TYPE_AMSTRAD 5 /* Amstrad PC system mouse */ -#define MOUSE_TYPE_OLIM24 6 /* Olivetti M24 system mouse */ -#define MOUSE_TYPE_MSYSTEMS 7 /* Mouse Systems mouse */ -#define MOUSE_TYPE_LOGITECH 8 /* Logitech Serial Mouse */ -#define MOUSE_TYPE_GENIUS 9 /* Genius Bus Mouse */ +#define MOUSE_TYPE_NONE 0 +#if 0 +#define MOUSE_TYPE_GENIUS 10 /* Genius Bus Mouse */ +#endif +#define MOUSE_TYPE_BUS 1 /* Logitech/ATI Bus Mouse */ +#define MOUSE_TYPE_MSYSTEMS 2 /* Mouse Systems mouse */ +#define MOUSE_TYPE_SERIAL 3 /* Serial Mouse */ +#define MOUSE_TYPE_LOGITECH 4 /* Logitech Serial Mouse */ +#define MOUSE_TYPE_MSWHEEL 5 /* Serial Wheel Mouse */ +#define MOUSE_TYPE_PS2 6 /* IBM PS/2 series Bus Mouse */ +#define MOUSE_TYPE_PS2_MS 7 /* Microsoft Intellimouse PS/2 */ +#define MOUSE_TYPE_AMSTRAD 8 /* Amstrad PC system mouse */ +#define MOUSE_TYPE_OLIM24 9 /* Olivetti M24 system mouse */ #define MOUSE_TYPE_MASK 0x0f #define MOUSE_TYPE_3BUTTON (1<<7) /* device has 3+ buttons */ diff --git a/src/mouse_serial.c b/src/mouse_serial.c index d50b71d2e..fa7e709c6 100644 --- a/src/mouse_serial.c +++ b/src/mouse_serial.c @@ -273,9 +273,18 @@ uint8_t mouse_serial_poll(int x, int y, int z, int b, void *p) serial_write_fifo(mouse->serial, mousedat[0]); serial_write_fifo(mouse->serial, mousedat[1]); serial_write_fifo(mouse->serial, mousedat[2]); - if ((b&0x04) && mouse->type) + if (mouse->type == 2) { - serial_write_fifo(mouse->serial, 0x20); + if (b&0x04) + { + serial_write_fifo(mouse->serial, 0x20); + } + } + else if (mouse->type == 3) + { + mousedat[3] = z & 0xf; + if (b&4) mousedat[3] |= 0x10; + serial_write_fifo(mouse->serial, mousedat[3]); } } @@ -339,13 +348,23 @@ void mousecallback(void *p) if (mouse->mousepos == -1) { mouse->mousepos = 0; - if (mouse->type < 2) + switch(mouse->type) { - serial_write_fifo(mouse->serial, 'M'); - if (mouse->type == 1) - { + case 0: + serial_write_fifo(mouse->serial, 'H'); + break; + case 1: + default: + serial_write_fifo(mouse->serial, 'M'); + break; + case 2: + serial_write_fifo(mouse->serial, 'M'); serial_write_fifo(mouse->serial, '3'); - } + break; + case 3: + serial_write_fifo(mouse->serial, 'M'); + serial_write_fifo(mouse->serial, 'Z'); + break; } } } @@ -365,21 +384,26 @@ void *mouse_serial_common_init(int type) return mouse; } -void *mouse_serial_init() +void *mouse_serial_msystems_init() { return mouse_serial_common_init(0); } -void *mouse_serial_logitech_init() +void *mouse_serial_init() { return mouse_serial_common_init(1); } -void *mouse_serial_msystems_init() +void *mouse_serial_logitech_init() { return mouse_serial_common_init(2); } +void *mouse_serial_mswheel_init() +{ + return mouse_serial_common_init(3); +} + void mouse_serial_close(void *p) { mouse_serial_t *mouse = (mouse_serial_t *)p; @@ -389,6 +413,16 @@ void mouse_serial_close(void *p) serial1.rcr_callback = NULL; } +mouse_t mouse_msystems = +{ + "Mouse Systems Mouse (serial)", + "mssystems", + MOUSE_TYPE_MSYSTEMS | MOUSE_TYPE_3BUTTON, + mouse_serial_msystems_init, + mouse_serial_close, + mouse_serial_msystems_poll +}; + mouse_t mouse_serial_microsoft = { "Microsoft 2-button mouse (serial)", @@ -403,20 +437,20 @@ mouse_t mouse_serial_logitech = { "Logitech 3-button mouse (serial)", "lserial", - MOUSE_TYPE_SERIAL | MOUSE_TYPE_3BUTTON, + MOUSE_TYPE_LOGITECH | MOUSE_TYPE_3BUTTON, mouse_serial_logitech_init, mouse_serial_close, mouse_serial_poll }; -mouse_t mouse_msystems = +mouse_t mouse_serial_mswheel = { - "Mouse Systems Mouse (serial)", + "Microsoft wheel mouse (serial)", "mssystems", - MOUSE_TYPE_MSYSTEMS | MOUSE_TYPE_3BUTTON, - mouse_serial_msystems_init, + MOUSE_TYPE_MSWHEEL | MOUSE_TYPE_3BUTTON, + mouse_serial_mswheel_init, mouse_serial_close, - mouse_serial_msystems_poll + mouse_serial_poll }; diff --git a/src/mouse_serial.h b/src/mouse_serial.h index 27626c08c..f6c5a45d1 100644 --- a/src/mouse_serial.h +++ b/src/mouse_serial.h @@ -21,9 +21,10 @@ #define SERMOUSE_PORT 1 /* attach to Serial1 */ +extern mouse_t mouse_msystems; extern mouse_t mouse_serial_microsoft; extern mouse_t mouse_serial_logitech; -extern mouse_t mouse_msystems; +extern mouse_t mouse_serial_mswheel; #endif /*MOUSE_SERIAL_H*/