mirror of
https://github.com/holub/mame
synced 2025-07-04 17:38:08 +03:00
started converting steppers to simulate actual behavior in a more logical way, rather than using hardcoded tables [J. Wallace]
This commit is contained in:
parent
e11446603e
commit
d767819bb1
@ -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;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user