diff options
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 |
commit | d767819bb1127010d36af2deb097a3b4b1f821d1 (patch) | |
tree | c53fe3d62b6c9e2d2cbac56ef60e7e46f9652602 | |
parent | e11446603e5b0baa336e5fae26bec4ad1a63130b (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.c | 188 |
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; } |