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 */
old_pattern, /* old coil pattern */
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) */
INT16 step_pos, /* step position 0 - max_steps */
max_steps; /* maximum step position */
@ -47,7 +50,7 @@ typedef struct _stepper
} stepper;
static stepper step[MAX_STEPPERS];
/* step table, use active coils as row, phase as column*/
static const int StarpointStepTab[8][16] =
{// 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
@ -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
};
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)*/
/* step table, use active coils as row, phase as column*/
const stepper_interface starpoint_interface_48step =
{
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_patt);
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].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].step_pos);
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].pattern = 0x00;
step[which].old_pattern = 0x00;
step[which].phase = 0x00;
step[which].old_phase = 0x00;
update_optic(which);
}
@ -225,33 +210,145 @@ int stepper_update(int which, UINT8 pattern)
{
int changed = 0;
if ( step[which].pattern != pattern )
{ /* pattern changed */
int steps,
pos;
if ( step[which].pattern )
{
step[which].old_pattern = step[which].pattern;
}
step[which].phase = (step[which].step_pos % 8);
step[which].pattern = pattern;
/* This code probably makes more sense if you visualise what is being emulated, namely
a spinning drum with two electromagnets inside. Essentially, the CPU
activates a pair of windings on these magnets leads as necessary to attract and repel the drum to pull it round and
display as appropriate. To attempt to visualise the rotation effect, take a look at the compass rose below, the numbers
indicate the phase information as used
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 )
{
default:
case STARPOINT_48STEP_REEL : /* STARPOINT RMxxx */
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;
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;
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);
#endif
if ((step[which].type == BARCREST_48STEP_REEL) || (step[which].type == MPU3_48STEP_REEL))
{
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;
pos = 0;
@ -269,7 +366,7 @@ int stepper_update(int which, UINT8 pattern)
}
else
{
logerror("step[which].max_steps == 0\n");
logerror("step[%x].max_steps == 0\n",which);
}
if (pos != step[which].step_pos)
@ -279,6 +376,7 @@ int stepper_update(int which, UINT8 pattern)
step[which].step_pos = pos;
update_optic(which);
}
return changed;
}