started converting steppers to simulate actual behavior in a more logical way, rather than using hardcoded tables [J. Wallace]

This commit is contained in:
Angelo Salese 2012-01-06 17:40:31 +00:00
parent e11446603e
commit d767819bb1

View File

@ -34,7 +34,10 @@ typedef struct _stepper
UINT8 pattern, /* coil pattern */ UINT8 pattern, /* coil pattern */
old_pattern, /* old coil pattern */ old_pattern, /* old coil pattern */
phase, /* motor phase */ phase, /* motor phase */
type, /* reel type */ old_phase, /* old phase */
type, /* reel type */
stator1[2],
stator2[2],
reverse; /* Does reel spin backwards (construction of unit, not wiring) */ reverse; /* Does reel spin backwards (construction of unit, not wiring) */
INT16 step_pos, /* step position 0 - max_steps */ INT16 step_pos, /* step position 0 - max_steps */
max_steps; /* maximum step position */ max_steps; /* maximum step position */
@ -47,7 +50,7 @@ typedef struct _stepper
} stepper; } stepper;
static stepper step[MAX_STEPPERS]; static stepper step[MAX_STEPPERS];
/* step table, use active coils as row, phase as column*/
static const int StarpointStepTab[8][16] = static const int StarpointStepTab[8][16] =
{// 0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111 Phase {// 0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111 Phase
{ 0, 2, 0, 0, 2, 1, 3, 0, -2, -1, -1, 0, 0, 0, 0, 0 },// 0 { 0, 2, 0, 0, 2, 1, 3, 0, -2, -1, -1, 0, 0, 0, 0, 0 },// 0
@ -60,33 +63,8 @@ static const int StarpointStepTab[8][16] =
{ 0, 1, -3, 0, 3, 2, 2, 0, -1, -2, -2, 0, 0, 0, 0, 0 },// 7 { 0, 1, -3, 0, 3, 2, 2, 0, -1, -2, -2, 0, 0, 0, 0, 0 },// 7
}; };
static const int MPU3StepTab[8][4] =
{// 00 01 10 11 Phase
{ 2, 0, 0, -2, },// 0
{ 0, 0, 0, 0, },// 1
{ 0, -2, 2, 0, },// 2
{ 0, 0, 0, 0, },// 3
{-2, 0, 0, 2, },// 4
{ 0, 0, 0, 0, },// 5
{ 0, 2, -2, 0, },// 6
{ 0, 0, 0, 0, },// 7
};
static const int BarcrestStepTab[8][16] =
{// 0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111 Phase
{ 0, 1, 3, 2, -3, 0, 0, 0, -1, 0, 0, 0, -2, 0, 0, 0 },// 0
{ 0, 0, 2, 1, 0, 0, 3, 0, -2, -1, 0, 0, -3, 0, 0, 0 },// 1
{ 0, -1, 1, 0, 3, 0, 2, 0, -3, -2, 0, 0, 0, 0, 0, 0 },// 2
{ 0, -2, 0, -1, 2, 0, 1, 0, 0, -3, 0, 0, 3, 0, 0, 0 },// 3
{ 0, -3, -1, -2, 1, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0 },// 4
{ 0, 0, -2, -3, 0, 0, -1, 0, 2, 3, 0, 0, 1, 0, 0, 0 },// 5
{ 0, 3, -3, 0, -1, 0, -2, 0, 0, 2, 0, 0, 0, 0, 0, 0 },// 6
{ 0, 2, 0, 3, -2, 0, -3, 0, 0, 1, 0, 0, -1, 0, 0, 0 },// 7
};
/* useful interfaces (Starpoint is a very common setup)*/ /* useful interfaces (Starpoint is a very common setup)*/
/* step table, use active coils as row, phase as column*/
const stepper_interface starpoint_interface_48step = const stepper_interface starpoint_interface_48step =
{ {
STARPOINT_48STEP_REEL, STARPOINT_48STEP_REEL,
@ -140,7 +118,12 @@ void stepper_config(running_machine &machine, int which, const stepper_interface
state_save_register_item(machine, "stepper", NULL, which, step[which].index_end); state_save_register_item(machine, "stepper", NULL, which, step[which].index_end);
state_save_register_item(machine, "stepper", NULL, which, step[which].index_patt); state_save_register_item(machine, "stepper", NULL, which, step[which].index_patt);
state_save_register_item(machine, "stepper", NULL, which, step[which].phase); state_save_register_item(machine, "stepper", NULL, which, step[which].phase);
state_save_register_item(machine, "stepper", NULL, which, step[which].old_phase);
state_save_register_item(machine, "stepper", NULL, which, step[which].pattern); state_save_register_item(machine, "stepper", NULL, which, step[which].pattern);
state_save_register_item(machine, "stepper", NULL, which, step[which].stator1[0]);
state_save_register_item(machine, "stepper", NULL, which, step[which].stator1[1]);
state_save_register_item(machine, "stepper", NULL, which, step[which].stator2[0]);
state_save_register_item(machine, "stepper", NULL, which, step[which].stator2[1]);
state_save_register_item(machine, "stepper", NULL, which, step[which].old_pattern); state_save_register_item(machine, "stepper", NULL, which, step[which].old_pattern);
state_save_register_item(machine, "stepper", NULL, which, step[which].step_pos); state_save_register_item(machine, "stepper", NULL, which, step[which].step_pos);
state_save_register_item(machine, "stepper", NULL, which, step[which].max_steps); state_save_register_item(machine, "stepper", NULL, which, step[which].max_steps);
@ -201,6 +184,8 @@ void stepper_reset_position(int which)
step[which].step_pos = 0; step[which].step_pos = 0;
step[which].pattern = 0x00; step[which].pattern = 0x00;
step[which].old_pattern = 0x00; step[which].old_pattern = 0x00;
step[which].phase = 0x00;
step[which].old_phase = 0x00;
update_optic(which); update_optic(which);
} }
@ -225,33 +210,145 @@ int stepper_update(int which, UINT8 pattern)
{ {
int changed = 0; int changed = 0;
if ( step[which].pattern != pattern ) /* This code probably makes more sense if you visualise what is being emulated, namely
{ /* pattern changed */ a spinning drum with two electromagnets inside. Essentially, the CPU
int steps, activates a pair of windings on these magnets leads as necessary to attract and repel the drum to pull it round and
pos; display as appropriate. To attempt to visualise the rotation effect, take a look at the compass rose below, the numbers
if ( step[which].pattern ) indicate the phase information as used
{
step[which].old_pattern = step[which].pattern;
}
step[which].phase = (step[which].step_pos % 8);
step[which].pattern = pattern;
7
N
1 W E 5
S
3
For sake of accuracy, we're representing all possible phases of the motor, effectively moving the motor one half step at a time, so a 48 step motor becomes
96 half steps. This is necessary because of some programs running the wiring in series with a distinct delay between the pair being completed. This causes
a small movement that may trigger the optic.
*/
{
int pos,steps=0;
switch ( step[which].type ) switch ( step[which].type )
{ {
default: default:
case STARPOINT_48STEP_REEL : /* STARPOINT RMxxx */ case STARPOINT_48STEP_REEL : /* STARPOINT RMxxx */
case STARPOINT_144STEPS_DICE : /* STARPOINT 1DCU DICE mechanism */ case STARPOINT_144STEPS_DICE : /* STARPOINT 1DCU DICE mechanism */
steps = StarpointStepTab[step[which].phase][pattern];//[(step[which].old_pattern << 4) | pattern];// if ( step[which].pattern != pattern )
{
//NOTE: Eventually we will convert Starpoint to the Stator method below, at which point the table can be removed
steps = StarpointStepTab[(step[which].step_pos % 8)][pattern];
step[which].pattern = pattern;
}
break; break;
case BARCREST_48STEP_REEL : /* Barcrest reel units have different windings */ case BARCREST_48STEP_REEL : /* Barcrest reel units have different windings */
steps = BarcrestStepTab[step[which].phase][pattern]; {
logerror("step%x pattern %x\n",which,pattern);
step[which].stator1[0] = (BIT(pattern,0)? 1 : 0);//orange
step[which].stator1[1] = (BIT(pattern,2)? 1 : 0);//yellow
step[which].stator2[0] = (BIT(pattern,1)? 1 : 0);//brown
step[which].stator2[1] = (BIT(pattern,3)? 1 : 0);//black
if (step[which].stator1[0] && !step[which].stator1[1] && !step[which].stator2[0] && !step[which].stator2[1])
{
step[which].phase = 7;
}
if (step[which].stator1[0] && !step[which].stator1[1] && step[which].stator2[0] && !step[which].stator2[1])
{
step[which].phase = 6;
}
if (step[which].stator1[0] && !step[which].stator1[1] && !step[which].stator2[0] && !step[which].stator2[1])
{
step[which].phase = 5;
}
if (step[which].stator1[0] && !step[which].stator1[1] && step[which].stator2[0] && !step[which].stator2[1])
{
step[which].phase = 4;
}
if (!step[which].stator1[0] && !step[which].stator1[1] && !step[which].stator2[0] && step[which].stator2[1])
{
step[which].phase = 3;
}
if (!step[which].stator1[0] && step[which].stator1[1] && !step[which].stator2[0] && step[which].stator2[1])
{
step[which].phase = 2;
}
if (!step[which].stator1[0] && !step[which].stator1[1] && !step[which].stator2[0] && step[which].stator2[1])
{
step[which].phase = 1;
}
if (step[which].stator1[0] && !step[which].stator1[1] && !step[which].stator2[0] && step[which].stator2[1])
{
step[which].phase = 0;
}
if (step[which].stator1[0] && step[which].stator1[1] && !step[which].stator2[0] && !step[which].stator2[1])
{
if ((step[which].old_phase ==6)||(step[which].old_phase == 0)) // if the previous pattern had the drum in the northern quadrant, it will point north now
{
step[which].phase = 7;
}
else //otherwise it will line up due south
{
step[which].phase = 3;
}
}
if (!step[which].stator1[0] && !step[which].stator1[1] && step[which].stator2[0] && step[which].stator2[1])
{
if ((step[which].old_phase ==6)||(step[which].old_phase == 4)) // if the previous pattern had the drum in the eastern quadrant, it will point east now
{
step[which].phase = 5;
}
else //otherwise it will line up due west
{
step[which].phase = 1;
}
}
}
break; break;
case MPU3_48STEP_REEL : /* Same unit as above, but different interface (2 active lines, not 4)*/ case MPU3_48STEP_REEL : /* Same unit as above, but different interface (2 active lines, not 4)*/
steps = MPU3StepTab[step[which].phase][pattern]; //TODO - set up stators using manual, this seems to be correct based on the previous behaviour
switch (pattern)
{
case 0x00 :
step[which].phase = 6;
break;
case 0x01 :
step[which].phase = 4;
break;
case 0x03 :
step[which].phase = 2;
break;
case 0x02 :
step[which].phase = 0;
break;
}
break;
} }
#if 0 /* Assists with new index generation */
if ( which ==1 )logerror("which %d Steps %d Phase %d Pattern Old %02X New %02X\n",which,steps,(step[which].phase),step[which].old_pattern,step[which].pattern); if ((step[which].type == BARCREST_48STEP_REEL) || (step[which].type == MPU3_48STEP_REEL))
#endif {
steps = step[which].old_phase - step[which].phase;
if (steps < -4)
{
steps = steps +8;
}
if (steps > 4)
{
steps = steps -8;
}
}
step[which].old_phase = step[which].phase;
step[which].old_pattern = step[which].pattern;
int max = step[which].max_steps; int max = step[which].max_steps;
pos = 0; pos = 0;
@ -269,7 +366,7 @@ int stepper_update(int which, UINT8 pattern)
} }
else else
{ {
logerror("step[which].max_steps == 0\n"); logerror("step[%x].max_steps == 0\n",which);
} }
if (pos != step[which].step_pos) if (pos != step[which].step_pos)
@ -279,6 +376,7 @@ int stepper_update(int which, UINT8 pattern)
step[which].step_pos = pos; step[which].step_pos = pos;
update_optic(which); update_optic(which);
} }
return changed; return changed;
} }