Applied the latest mainline PCem commits.
This commit is contained in:
@@ -42,6 +42,11 @@ static int pair_timings[4][4] =
|
||||
#define CYCLES_RMW (2 << 0)
|
||||
#define CYCLES_BRANCH (3 << 0)
|
||||
|
||||
/*Instruction has immediate data. Can only be used with PAIR_U/PAIR_V/PAIR_UV*/
|
||||
#define CYCLES_HASIMM (3 << 2)
|
||||
#define CYCLES_IMM8 (1 << 2)
|
||||
#define CYCLES_IMM1632 (2 << 2)
|
||||
|
||||
#define CYCLES_MASK ((1 << 7) - 1)
|
||||
|
||||
/*Instruction is MMX shift or pack/unpack instruction*/
|
||||
@@ -62,6 +67,8 @@ static int pair_timings[4][4] =
|
||||
/*Instruction is FXCH and only pairs in V pipe with FX pairable instruction*/
|
||||
#define PAIR_FXCH (6 << 29)
|
||||
|
||||
#define PAIR_FPU (4 << 29)
|
||||
|
||||
#define PAIR_MASK (7 << 29)
|
||||
|
||||
/*Instruction has input dependency on register in REG field*/
|
||||
@@ -296,38 +303,38 @@ static uint32_t opcode_timings_mod3[256] =
|
||||
/* ADD ADD ADD ADD*/
|
||||
/*00*/ PAIR_UV | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_UV | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_UV | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_UV | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG,
|
||||
/* ADD ADD PUSH ES POP ES*/
|
||||
PAIR_UV | CYCLES_REG | SRCDEP_EAX | SRCDEP_RM | DSTDEP_EAX, PAIR_UV | CYCLES_REG | SRCDEP_EAX | SRCDEP_RM | DSTDEP_EAX, PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(3),
|
||||
PAIR_UV | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, PAIR_UV | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(3),
|
||||
/* OR OR OR OR*/
|
||||
PAIR_UV | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_UV | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_UV | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_UV | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG,
|
||||
/* OR OR PUSH CS */
|
||||
PAIR_UV | CYCLES_REG | SRCDEP_EAX | SRCDEP_RM | DSTDEP_EAX, PAIR_UV | CYCLES_REG | SRCDEP_EAX | SRCDEP_RM | DSTDEP_EAX, PAIR_NP | CYCLES(1), INVALID,
|
||||
PAIR_UV | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, PAIR_UV | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, PAIR_NP | CYCLES(1), INVALID,
|
||||
|
||||
/* ADC ADC ADC ADC*/
|
||||
/*10*/ PAIR_U | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_U | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_U | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_U | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG,
|
||||
/* ADC ADC PUSH SS POP SS*/
|
||||
PAIR_U | CYCLES_REG | SRCDEP_EAX | SRCDEP_RM | DSTDEP_EAX, PAIR_U | CYCLES_REG | SRCDEP_EAX | SRCDEP_RM | DSTDEP_EAX, PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(3),
|
||||
PAIR_U | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, PAIR_U | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(3),
|
||||
/* SBB SBB SBB SBB*/
|
||||
PAIR_U | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_U | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_U | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_U | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG,
|
||||
/* SBB SBB PUSH DS POP DS*/
|
||||
PAIR_U | CYCLES_REG | SRCDEP_EAX | SRCDEP_RM | DSTDEP_EAX, PAIR_U | CYCLES_REG | SRCDEP_EAX | SRCDEP_RM | DSTDEP_EAX, PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(3),
|
||||
PAIR_U | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, PAIR_U | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(3),
|
||||
|
||||
/* AND AND AND AND*/
|
||||
/*20*/ PAIR_UV | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_UV | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_UV | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_UV | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG,
|
||||
/* AND AND DAA*/
|
||||
PAIR_UV | CYCLES_REG | SRCDEP_EAX | SRCDEP_RM | DSTDEP_EAX, PAIR_UV | CYCLES_REG | SRCDEP_EAX | SRCDEP_RM | DSTDEP_EAX, INVALID, PAIR_NP | CYCLES(3),
|
||||
PAIR_UV | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, PAIR_UV | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, INVALID, PAIR_NP | CYCLES(3),
|
||||
/* SUB SUB SUB SUB*/
|
||||
PAIR_UV | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_UV | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_UV | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_UV | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG,
|
||||
/* SUB SUB DAS*/
|
||||
PAIR_UV | CYCLES_REG | SRCDEP_EAX | SRCDEP_RM | DSTDEP_EAX, PAIR_UV | CYCLES_REG | SRCDEP_EAX | SRCDEP_RM | DSTDEP_EAX, INVALID, PAIR_NP | CYCLES(3),
|
||||
PAIR_UV | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, PAIR_UV | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, INVALID, PAIR_NP | CYCLES(3),
|
||||
|
||||
/* XOR XOR XOR XOR*/
|
||||
/*30*/ PAIR_UV | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_UV | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_UV | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_UV | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG,
|
||||
/* XOR XOR AAA*/
|
||||
PAIR_UV | CYCLES_REG | SRCDEP_EAX | SRCDEP_RM | DSTDEP_EAX, PAIR_UV | CYCLES_REG | SRCDEP_EAX | SRCDEP_RM | DSTDEP_EAX, INVALID, PAIR_NP | CYCLES(3),
|
||||
PAIR_UV | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, PAIR_UV | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, INVALID, PAIR_NP | CYCLES(3),
|
||||
/* CMP CMP CMP CMP*/
|
||||
PAIR_UV | CYCLES_REG | SRCDEP_REG | SRCDEP_RM, PAIR_UV | CYCLES_REG | SRCDEP_REG | SRCDEP_RM, PAIR_UV | CYCLES_REG | SRCDEP_REG | SRCDEP_RM, PAIR_UV | CYCLES_REG | SRCDEP_RM | SRCDEP_REG,
|
||||
/* CMP CMP AAS*/
|
||||
PAIR_UV | CYCLES_REG | SRCDEP_EAX | SRCDEP_RM, PAIR_UV | CYCLES_REG | SRCDEP_EAX, INVALID, PAIR_NP | CYCLES(3),
|
||||
PAIR_UV | CYCLES_REG | SRCDEP_EAX, PAIR_UV | CYCLES_REG | SRCDEP_EAX, INVALID, PAIR_NP | CYCLES(3),
|
||||
|
||||
/* INC EAX INC ECX INC EDX INC EBX*/
|
||||
/*40*/ PAIR_UV | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, PAIR_UV | CYCLES_REG | SRCDEP_ECX | DSTDEP_ECX, PAIR_UV | CYCLES_REG | SRCDEP_EDX | DSTDEP_EDX, PAIR_UV | CYCLES_REG | SRCDEP_EBX | DSTDEP_EBX,
|
||||
@@ -810,14 +817,20 @@ static uint32_t opcode_timings_df_mod3[8] =
|
||||
PAIR_NP | CYCLES(2), INVALID, INVALID, INVALID
|
||||
};
|
||||
|
||||
static uint32_t opcode_timings_81[8] =
|
||||
{
|
||||
PAIR_UV | CYCLES_RMW | SRCDEP_REG | CYCLES_IMM1632, PAIR_UV | CYCLES_RMW | SRCDEP_REG | CYCLES_IMM1632, PAIR_UV | CYCLES_RMW | SRCDEP_REG | CYCLES_IMM1632, PAIR_UV | CYCLES_RMW | SRCDEP_REG | CYCLES_IMM1632,
|
||||
PAIR_UV | CYCLES_RMW | SRCDEP_REG | CYCLES_IMM1632, PAIR_UV | CYCLES_RMW | SRCDEP_REG | CYCLES_IMM1632, PAIR_UV | CYCLES_RMW | SRCDEP_REG | CYCLES_IMM1632, PAIR_UV | CYCLES_RM | SRCDEP_REG | CYCLES_IMM1632
|
||||
};
|
||||
static uint32_t opcode_timings_8x[8] =
|
||||
{
|
||||
PAIR_UV | CYCLES_RMW | SRCDEP_REG, PAIR_UV | CYCLES_RMW | SRCDEP_REG, PAIR_UV | CYCLES_RMW | SRCDEP_REG, PAIR_UV | CYCLES_RMW | SRCDEP_REG,
|
||||
PAIR_UV | CYCLES_RMW | SRCDEP_REG, PAIR_UV | CYCLES_RMW | SRCDEP_REG, PAIR_UV | CYCLES_RMW | SRCDEP_REG, PAIR_UV | CYCLES_RM | SRCDEP_REG
|
||||
PAIR_UV | CYCLES_RMW | SRCDEP_REG | CYCLES_IMM8, PAIR_UV | CYCLES_RMW | SRCDEP_REG | CYCLES_IMM8, PAIR_UV | CYCLES_RMW | SRCDEP_REG | CYCLES_IMM8, PAIR_UV | CYCLES_RMW | SRCDEP_REG | CYCLES_IMM8,
|
||||
PAIR_UV | CYCLES_RMW | SRCDEP_REG | CYCLES_IMM8, PAIR_UV | CYCLES_RMW | SRCDEP_REG | CYCLES_IMM8, PAIR_UV | CYCLES_RMW | SRCDEP_REG | CYCLES_IMM8, PAIR_UV | CYCLES_RM | SRCDEP_REG | CYCLES_IMM8
|
||||
};
|
||||
|
||||
static int decode_delay;
|
||||
static uint8_t last_prefix;
|
||||
static int prefixes;
|
||||
|
||||
static inline int COUNT(uint32_t c, int op_32)
|
||||
{
|
||||
@@ -831,6 +844,10 @@ static inline int COUNT(uint32_t c, int op_32)
|
||||
return c & 0xffff;
|
||||
if ((c & PAIR_MASK) == PAIR_FX)
|
||||
return c & 0xffff;
|
||||
if ((c & PAIR_MASK) == PAIR_FXCH)
|
||||
return c & 0xffff;
|
||||
if ((c & PAIR_UV) && !(c & PAIR_FPU))
|
||||
c &= 3;
|
||||
switch (c & CYCLES_MASK)
|
||||
{
|
||||
case CYCLES_REG:
|
||||
@@ -848,6 +865,80 @@ static inline int COUNT(uint32_t c, int op_32)
|
||||
return c;
|
||||
}
|
||||
|
||||
static inline int codegen_timing_has_displacement(uint32_t fetchdat, int op_32)
|
||||
{
|
||||
if (op_32 & 0x200)
|
||||
{
|
||||
if ((fetchdat & 7) == 4 && (fetchdat & 0xc0) != 0xc0)
|
||||
{
|
||||
/*Has SIB*/
|
||||
if ((fetchdat & 0xc0) == 0x40 || (fetchdat & 0xc0) == 0x80 || (fetchdat & 0x700) == 0x500)
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((fetchdat & 0xc0) == 0x40 || (fetchdat & 0xc0) == 0x80 || (fetchdat & 0xc7) == 0x05)
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((fetchdat & 0xc0) == 0x40 || (fetchdat & 0xc0) == 0x80 || (fetchdat & 0xc7) == 0x06)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*The instruction is only of interest here if it's longer than 7 bytes, as that's the
|
||||
limit on Pentium MMX parallel decoding*/
|
||||
static inline int codegen_timing_instr_length(uint32_t timing, uint32_t fetchdat, int op_32)
|
||||
{
|
||||
int len = prefixes;
|
||||
if ((timing & CYCLES_MASK) == CYCLES_RM || (timing & CYCLES_MASK) == CYCLES_RMW)
|
||||
{
|
||||
len += 2; /*Opcode + ModR/M*/
|
||||
if ((timing & CYCLES_HASIMM) == CYCLES_IMM8)
|
||||
len++;
|
||||
if ((timing & CYCLES_HASIMM) == CYCLES_IMM1632)
|
||||
len += (op_32 & 0x100) ? 4 : 2;
|
||||
|
||||
if (op_32 & 0x200)
|
||||
{
|
||||
if ((fetchdat & 7) == 4 && (fetchdat & 0xc0) != 0xc0)
|
||||
{
|
||||
/* Has SIB*/
|
||||
len++;
|
||||
if ((fetchdat & 0xc0) == 0x40)
|
||||
len++;
|
||||
else if ((fetchdat & 0xc0) == 0x80)
|
||||
len += 4;
|
||||
else if ((fetchdat & 0x700) == 0x500)
|
||||
len += 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((fetchdat & 0xc0) == 0x40)
|
||||
len++;
|
||||
else if ((fetchdat & 0xc0) == 0x80)
|
||||
len += 4;
|
||||
else if ((fetchdat & 0xc7) == 0x05)
|
||||
len += 4;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((fetchdat & 0xc0) == 0x40)
|
||||
len++;
|
||||
else if ((fetchdat & 0xc0) == 0x80)
|
||||
len += 2;
|
||||
else if ((fetchdat & 0xc7) == 0x06)
|
||||
len += 2;
|
||||
}
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
void codegen_timing_pentium_block_start()
|
||||
{
|
||||
u_pipe_full = decode_delay = 0;
|
||||
@@ -856,10 +947,12 @@ void codegen_timing_pentium_block_start()
|
||||
void codegen_timing_pentium_start()
|
||||
{
|
||||
last_prefix = 0;
|
||||
prefixes = 0;
|
||||
}
|
||||
|
||||
void codegen_timing_pentium_prefix(uint8_t prefix, uint32_t fetchdat)
|
||||
{
|
||||
prefixes++;
|
||||
if (cpu_hasMMX && prefix == 0x0f)
|
||||
{
|
||||
/*On Pentium MMX 0fh prefix is 'free'*/
|
||||
@@ -933,11 +1026,16 @@ void codegen_timing_pentium_opcode(uint8_t opcode, uint32_t fetchdat, int op_32)
|
||||
default:
|
||||
switch (opcode)
|
||||
{
|
||||
case 0x80: case 0x81: case 0x82: case 0x83:
|
||||
case 0x80: case 0x82: case 0x83:
|
||||
timings = mod3 ? opcode_timings_mod3 : opcode_timings_8x;
|
||||
if (!mod3)
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
case 0x81:
|
||||
timings = mod3 ? opcode_timings_mod3 : opcode_timings_81;
|
||||
if (!mod3)
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
|
||||
case 0xc0: case 0xc1: case 0xd0: case 0xd1: case 0xd2: case 0xd3:
|
||||
timings = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift;
|
||||
@@ -980,23 +1078,38 @@ void codegen_timing_pentium_opcode(uint8_t opcode, uint32_t fetchdat, int op_32)
|
||||
|
||||
if ((timings[opcode] & PAIR_V) && !(u_pipe_regmask & regmask) && !decode_delay)
|
||||
{
|
||||
int t1 = u_pipe_timings[u_pipe_opcode] & CYCLES_MASK;
|
||||
int t2 = timings[opcode] & CYCLES_MASK;
|
||||
int t_pair;
|
||||
int has_displacement;
|
||||
|
||||
if (t1 < 0 || t2 < 0 || t1 > CYCLES_BRANCH || t2 > CYCLES_BRANCH)
|
||||
fatal("Pair out of range\n");
|
||||
if (timings[opcode] & CYCLES_HASIMM)
|
||||
has_displacement = codegen_timing_has_displacement(fetchdat, op_32);
|
||||
else
|
||||
has_displacement = 0;
|
||||
|
||||
if (!has_displacement && (!cpu_hasMMX || codegen_timing_instr_length(timings[opcode], fetchdat, op_32) <= 7))
|
||||
{
|
||||
int t1 = u_pipe_timings[u_pipe_opcode] & CYCLES_MASK;
|
||||
int t2 = timings[opcode] & CYCLES_MASK;
|
||||
int t_pair;
|
||||
|
||||
t_pair = pair_timings[t1][t2];
|
||||
if (t_pair < 1)
|
||||
fatal("Illegal pair timings : t1=%i t2=%i u_opcode=%02x v_opcode=%02x\n", t1, t2, u_pipe_opcode, opcode);
|
||||
if (!(u_pipe_timings[u_pipe_opcode] & PAIR_FPU))
|
||||
t1 &= 3;
|
||||
if (!(timings[opcode] & PAIR_FPU))
|
||||
t2 &= 3;
|
||||
|
||||
if (t1 < 0 || t2 < 0 || t1 > CYCLES_BRANCH || t2 > CYCLES_BRANCH)
|
||||
fatal("Pair out of range\n");
|
||||
|
||||
t_pair = pair_timings[t1][t2];
|
||||
if (t_pair < 1)
|
||||
fatal("Illegal pair timings : t1=%i t2=%i u_opcode=%02x v_opcode=%02x\n", t1, t2, u_pipe_opcode, opcode);
|
||||
|
||||
codegen_block_cycles += t_pair;
|
||||
decode_delay = (-t_pair) + 1;
|
||||
codegen_block_cycles += t_pair;
|
||||
decode_delay = (-t_pair) + 1;
|
||||
|
||||
/*Instruction can pair with previous*/
|
||||
u_pipe_full = 0;
|
||||
return;
|
||||
/*Instruction can pair with previous*/
|
||||
u_pipe_full = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
nopair:
|
||||
/*Instruction can not pair with previous*/
|
||||
@@ -1008,13 +1121,23 @@ nopair:
|
||||
|
||||
if ((timings[opcode] & PAIR_U) && !decode_delay)
|
||||
{
|
||||
/*Instruction might pair with next*/
|
||||
u_pipe_full = 1;
|
||||
u_pipe_opcode = opcode;
|
||||
u_pipe_timings = timings;
|
||||
u_pipe_op_32 = op_32;
|
||||
u_pipe_regmask = get_dstdep_mask(timings[opcode], fetchdat, bit8);
|
||||
return;
|
||||
int has_displacement;
|
||||
|
||||
if (timings[opcode] & CYCLES_HASIMM)
|
||||
has_displacement = codegen_timing_has_displacement(fetchdat, op_32);
|
||||
else
|
||||
has_displacement = 0;
|
||||
|
||||
if ((!has_displacement || cpu_hasMMX) && (!cpu_hasMMX || codegen_timing_instr_length(timings[opcode], fetchdat, op_32) <= 7))
|
||||
{
|
||||
/*Instruction might pair with next*/
|
||||
u_pipe_full = 1;
|
||||
u_pipe_opcode = opcode;
|
||||
u_pipe_timings = timings;
|
||||
u_pipe_op_32 = op_32;
|
||||
u_pipe_regmask = get_dstdep_mask(timings[opcode], fetchdat, bit8);
|
||||
return;
|
||||
}
|
||||
}
|
||||
/*Instruction can not pair and must run now*/
|
||||
|
||||
|
||||
@@ -2,14 +2,14 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "../ibm.h"
|
||||
|
||||
#include "../device.h"
|
||||
#include "../dma.h"
|
||||
#include "../io.h"
|
||||
#include "../pic.h"
|
||||
#include "../dma.h"
|
||||
#include "../timer.h"
|
||||
#include "../device.h"
|
||||
#include "sound.h"
|
||||
#include "snd_gus.h"
|
||||
|
||||
#include "../timer.h"
|
||||
|
||||
typedef struct gus_t
|
||||
{
|
||||
@@ -235,7 +235,7 @@ void writegus(uint16_t addr, uint8_t val, void *p)
|
||||
|
||||
case 0xA: /*Current addr high*/
|
||||
gus->cur[gus->voice]=(gus->cur[gus->voice]&0x1F00FFFF)|(val<<16);
|
||||
gus->curx[gus->voice]=(gus->curx[gus->voice]&0xF807F00)|((val<<7)<<8);
|
||||
gus->curx[gus->voice]=(gus->curx[gus->voice]&0xF807F00)|((val<<7)<<8);
|
||||
break;
|
||||
case 0xB: /*Current addr low*/
|
||||
gus->cur[gus->voice]=(gus->cur[gus->voice]&0x1FFFFF00)|val;
|
||||
@@ -257,10 +257,6 @@ gus->curx[gus->voice]=(gus->curx[gus->voice]&0xF807F00)|((val<<7)<<8);
|
||||
switch (gus->global)
|
||||
{
|
||||
case 0: /*Voice control*/
|
||||
if (!(val&1) && gus->ctrl[gus->voice]&1)
|
||||
{
|
||||
}
|
||||
|
||||
gus->ctrl[gus->voice] = val & 0x7f;
|
||||
|
||||
old = gus->waveirqs[gus->voice];
|
||||
@@ -307,7 +303,7 @@ gus->curx[gus->voice]=(gus->curx[gus->voice]&0xF807F00)|((val<<7)<<8);
|
||||
break;
|
||||
case 0xB: /*Current addr low*/
|
||||
gus->cur[gus->voice]=(gus->cur[gus->voice]&0x1FFF00FF)|(val<<8);
|
||||
gus->curx[gus->voice]=(gus->curx[gus->voice]&0xFFF8000)|((val&0x7F)<<8);
|
||||
gus->curx[gus->voice]=(gus->curx[gus->voice]&0xFFF8000)|((val&0x7F)<<8);
|
||||
break;
|
||||
case 0xC: /*Pan*/
|
||||
gus->pan_l[gus->voice] = 15 - (val & 0xf);
|
||||
@@ -341,13 +337,27 @@ gus->curx[gus->voice]=(gus->curx[gus->voice]&0xFFF8000)|((val&0x7F)<<8);
|
||||
while (c<65536)
|
||||
{
|
||||
int dma_result;
|
||||
d = gus->ram[gus->dmaaddr];
|
||||
if (val & 0x80) d ^= 0x80;
|
||||
dma_result = dma_channel_write(gus->dma, d);
|
||||
if (dma_result == DMA_NODATA)
|
||||
break;
|
||||
if (val & 0x04)
|
||||
{
|
||||
uint32_t gus_addr = (gus->dmaaddr & 0xc0000) | ((gus->dmaaddr & 0x1ffff) << 1);
|
||||
d = gus->ram[gus_addr] | (gus->ram[gus_addr + 1] << 8);
|
||||
if (val & 0x80)
|
||||
d ^= 0x8080;
|
||||
dma_result = dma_channel_write(gus->dma, d);
|
||||
if (dma_result == DMA_NODATA)
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
d = gus->ram[gus->dmaaddr];
|
||||
if (val & 0x80)
|
||||
d ^= 0x80;
|
||||
dma_result = dma_channel_write(gus->dma, d);
|
||||
if (dma_result == DMA_NODATA)
|
||||
break;
|
||||
}
|
||||
gus->dmaaddr++;
|
||||
gus->dmaaddr&=0xFFFFF;
|
||||
gus->dmaaddr &= 0xFFFFF;
|
||||
c++;
|
||||
if (dma_result & DMA_OVER)
|
||||
break;
|
||||
@@ -363,10 +373,22 @@ gus->curx[gus->voice]=(gus->curx[gus->voice]&0xFFF8000)|((val&0x7F)<<8);
|
||||
d = dma_channel_read(gus->dma);
|
||||
if (d == DMA_NODATA)
|
||||
break;
|
||||
if (val&0x80) d^=0x80;
|
||||
gus->ram[gus->dmaaddr]=d;
|
||||
if (val & 0x04)
|
||||
{
|
||||
uint32_t gus_addr = (gus->dmaaddr & 0xc0000) | ((gus->dmaaddr & 0x1ffff) << 1);
|
||||
if (val & 0x80)
|
||||
d ^= 0x8080;
|
||||
gus->ram[gus_addr] = d & 0xff;
|
||||
gus->ram[gus_addr +1] = (d >> 8) & 0xff;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (val & 0x80)
|
||||
d ^= 0x80;
|
||||
gus->ram[gus->dmaaddr] = d;
|
||||
}
|
||||
gus->dmaaddr++;
|
||||
gus->dmaaddr&=0xFFFFF;
|
||||
gus->dmaaddr &= 0xFFFFF;
|
||||
c++;
|
||||
if (d & DMA_OVER)
|
||||
break;
|
||||
|
||||
@@ -705,11 +705,12 @@ int dma_channel_write(int channel, uint16_t val)
|
||||
dma16.cc[channel] = dma16.cb[channel] + 1;
|
||||
dma16.ac[channel] = dma16.ab[channel];
|
||||
}
|
||||
else
|
||||
dma16.m |= (1 << channel);
|
||||
dma16.stat |= (1 << channel);
|
||||
}
|
||||
|
||||
if (dma.m & (1 << channel))
|
||||
if (dma16.m & (1 << channel))
|
||||
return DMA_OVER;
|
||||
}
|
||||
return 0;
|
||||
|
||||
Reference in New Issue
Block a user