summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Angelo Salese <angelosa@users.noreply.github.com>2012-01-06 17:40:31 +0000
committer Angelo Salese <angelosa@users.noreply.github.com>2012-01-06 17:40:31 +0000
commitd767819bb1127010d36af2deb097a3b4b1f821d1 (patch)
treec53fe3d62b6c9e2d2cbac56ef60e7e46f9652602
parente11446603e5b0baa336e5fae26bec4ad1a63130b (diff)
started converting steppers to simulate actual behavior in a more logical way, rather than using hardcoded tables [J. Wallace]
-rw-r--r--src/mame/machine/steppers.c188
1 files changed, 143 insertions, 45 deletions
diff --git a/src/mame/machine/steppers.c b/src/mame/machine/steppers.c
index cc6897fa20c..ee080751d86 100644
--- a/src/mame/machine/steppers.c
+++ b/src/mame/machine/steppers.c
@@ -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 ((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;
+ }
}
- #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
+ 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;
}