move.asm



;
;
;       FILE NAME  MOVE.ASM
;
;------------------  MOVE RELATED ROUTINES ---------------------------------
;
;
;             SynPet Personal Electronic Technologies
;             7225 Franklin Road, Boise, ID  83709
;
;             Created:  9/5/89 - LRE
;             Edit:     12/31/89 - LRE Started adding follow wall stuff.
;                       Separate .ASM  WALLFOL.ASM.
;             Edit:     2/6/90   - LRE Split off MOVDEFS.ASM and
;                       MOVCNTRL.ASN.
;
;
;---------------------------------------------------------------------------

; FILE CONTENTS IN ORDER OF APEARANCE:
;
; INIT_MOVE
;  Int handlers split off into MOVCNTRL.ASM 2/6/90
; RIGHT_MOTOR_OPTO_INT_HANDLER
; LEFT_MOTOR_OPTO_INT_HANDLER
; RIGHT_MOTOR_PWM_INT_HANDLER
; LEFT_MOTOR_PWM_INT_HANDLER
;
; START_RIGHT_MOTOR
; START_LEFT_MOTOR
; STOP_RIGHT_MOTOR
; STOP_LEFT_MOTOR
; CALC_PIVOT_COUNT
; CALC_DEGREES_ROTATED
; CALC_DISTANCE_COUNTS
; CALC_DICTANCE_MOVED
; MOVE_MAIN
; SETUP_N_START_ROTATE
; CONTINUE_ROTATE
; START_SL_MOVE
; CONTINUE_SL_MOVE
; PAUSE_R_N_M_MOVE
; R_N_M_PAUSED
 
; TWO MORE FILES ARE INCLUDED WHEN ASSEMBLING THIS FILE TO COMPLETE
; THE MOVE ROBOT ROUTINES. THE INCLUDE FILES ARE:
;
; ARCMOVES.ASM
; MOVUTILS.ASM
;
; SEE THE INCLUDE FILES FOR OTHER MOVE ROUTINES.


 .chip   16003
 .incld  GLOBDEFS
 .incld  MOVEDEFS

 

 .sect  DATA,ram8

;---------------- MODULE PRIVATE VARIABLES --------------------------------

 ; NOTE: These varibles are also used in MOVCNTRL.ASM

 .public left_on_sl_control
left_on_sl_control:        .DSB  1 ;
 .public right_on_sl_control
right_on_sl_control:       .DSB  1 ;
 .public left_on_control
left_on_control:           .DSB  1 ;
 .public right_on_control  
right_on_control:          .DSB  1 ;
 .public right_motor_on
right_motor_on:            .DSB  1 ;
 .public right_motor_direction
right_motor_direction:     .DSB  1 ;
 .public right_move_tic
right_move_tic:            .DSB  1 ;
 .public left_motor_on
left_motor_on:             .DSB  1 ;
 .public left_motor_direction
left_motor_direction:      .DSB  1 ;
 .public left_move_tic
left_move_tic:             .DSB  1 ;
waiting_for_move_tx:       .DSB  1 ;
degrees_hi:                .DSB  1 ;
degrees_lo:                .DSB  1 ;
 .public ft_hi
ft_hi:                     .DSB  1 ;
 .public ft_lo
ft_lo:                     .DSB  1 ;
radius:                    .DSB  1 ;
move_cancel_byte:          .DSB  1 ;
degrees_moved_hi:          .DSB  1 ;
degrees_moved_lo:          .DSB  1 ;
distance_moved_hi:         .DSB  1 ;
distance_moved_lo:         .DSB  1 ;
 .public arc_abort_data_lo
arc_abort_data_lo:         .DSB  1 ;
 .public arc_abort_data_hi
arc_abort_data_hi:         .DSB  1 ;
move_paused_state:         .DSB  1 ;
right_motor_stall_limit:   .DSB  1 ;
left_motor_stall_limit:    .DSB  1 ;
 .public speed
speed:                     .DSB  1 ;
 .public stay_on
stay_on:                   .DSB  1 ;
 .public control_motor
control_motor:             .DSB  1 ;
 .public outside_cnt_ext
outside_cnt_ext:           .DSB  1 ;
 .public inside_cnt_ext
inside_cnt_ext:            .DSB  1 ;
 .public adjusted_outside_cnt_ext
adjusted_outside_cnt_ext:  .DSB  1 ;
 .public arc_direction
arc_direction:             .DSB  1 ;
 .public fwd_or_rev_arc
fwd_or_rev_arc:            .DSB  1 ;
move_cancel_found:         .DSB  1 ;
move_jobs_in_q_copy:       .DSB  1 ;
 .public last_ramp_tic
last_ramp_tic:             .DSB  1 ;
 .public last_left_ramp_tic
last_left_ramp_tic:        .DSB  1 ;
 .public last_right_ramp_tic
last_right_ramp_tic:       .DSB  1 ;
 .public both_motors_on
both_motors_on:            .DSB  1 ;
temp_left_ext:             .DSB  1 ;
temp_right_ext:            .DSB  1 ;
 .public left_stop_flag
left_stop_flag:            .DSB  1 ;
 .public right_stop_flag
right_stop_flag:           .DSB  1 ;
 .public left_control_state
left_control_state:        .DSB  1 ;
 .public right_control_state
right_control_state:       .DSB  1 ;
 .public rotate_flag 
rotate_flag:               .DSB  1 ;
 .public stop_flag
stop_flag:                 .DSB  1 ;
 .public left_ramp_delta_lo
left_ramp_delta_lo:        .DSB  1 ;
 .public left_ramp_delta_hi
left_ramp_delta_hi:        .DSB  1 ;
 .public right_ramp_delta_lo
right_ramp_delta_lo:       .DSB  1 ;
 .public right_ramp_delta_hi
right_ramp_delta_hi:       .DSB  1 ;
 .public move_process_buff 
move_process_buff:         .DSB  MAX_MSG_LENGTH ;
move_msg_loop_cnt:         .DSB  1 ;
move_error_msg_code:       .DSB  1 ;
move_error_msg_job_number: .DSB  1 ;
 .public left_move_complete
left_move_complete:        .DSB  1 ;
 .public right_move_complete
right_move_complete:       .DSB  1 ;
paused_stay_on:            .DSB  1 ;
paused_right_cnts_to_move_lo: .DSB 1 ;
paused_right_cnts_to_move_hi: .DSB 1 ;
paused_left_cnts_to_move_lo: .DSB 1 ;
paused_left_cnts_to_move_hi: .DSB 1 ;
 .public left_stopping
left_stopping:               .DSB 1 ;
 .public right_stopping
right_stopping:              .DSB 1 ;
; .public right_noise_lo
; .public right_noise_hi
; .public left_noise_lo
; .public left_noise_hi
; .public reset_cnt
 .public right_speed_too_hi
 .public right_speed_too_lo
 .public left_speed_too_hi
 .public left_speed_too_lo
 .public right_iret_error
 .public left_iret_error
 .public right_t0_ff
 .public left_t0_ff
 .public right_long_noise
 .public left_long_noise
 .public right_wd_hits
 .public left_wd_hits
 .public right_too_fast_cnt
 .public left_too_fast_cnt
 .public right_slowing
 .public left_slowing
 .public speed_slow_down_limit
 .public right_dec_cnt
 .public left_dec_cnt
 .public right_timer_stop
 .public left_timer_stop

; right_noise_lo:              .DSB   1 ;
; right_noise_hi:              .DSB   1 ;
; left_noise_lo:               .DSB   1 ;
; left_noise_hi:               .DSB   1 ;
; reset_cnt:                   .DSB   1 ;
right_speed_too_hi:          .DSB   1 ;
right_speed_too_lo:          .DSB   1 ;
left_speed_too_hi:           .DSB   1 ;
left_speed_too_lo:           .DSB   1 ;
right_iret_error:            .DSB   1 ;
left_iret_error:             .DSB   1 ;
right_t0_ff:                 .DSB   1 ;
left_t0_ff:                  .DSB   1 ;
right_long_noise:            .DSB   1 ;
left_long_noise:             .DSB   1 ;
right_wd_hits:               .DSB   1 ;
left_wd_hits:                .DSB   1 ;
right_too_fast_cnt:          .DSB   1 ;
left_too_fast_cnt:           .DSB   1 ;
right_slowing:               .DSB   1 ;
left_slowing:                .DSB   1 ;
speed_slow_down_limit:       .DSB   1 ;
right_dec_cnt:               .DSB   1 ;
left_dec_cnt:                .DSB   1 ;
right_timer_stop:            .DSB   1 ;
left_timer_stop:             .DSB   1 ;
 .public right_tilt_cnt
right_tilt_cnt:              .DSB   1 ;
 .public left_tilt_cnt
left_tilt_cnt:               .DSB   1 ;

;--------------- END OF MODULE PRIVATE VARIABLES --------------------------

;-------------------- EXTERNAL GLOBAL VARIABLES ---------------------------

 .extrn    job_zero_out_q
 .extrn    job_zero_in_q
 .extrn    job_in_q_btm_ptrs
 .extrn    job_state
 .extrn    buffer_full_errors
 .extrn    msg_too_long_errors
 .extrn    jobs_in_q
 .extrn    total_jobs_in_qs
 .extrn    job_out_q_top_ptrs
 .extrn    job_out_q_btm_ptrs
 .extrn    msgs_to_send
 .extrn    total_msgs_to_send
 .extrn    right_motor_stall_cnt
 .extrn    right_motor_cnts_moved_ext
 .extrn    right_motor_cnts_to_move_ext
 .extrn    left_motor_stall_cnt 
 .extrn    left_motor_cnts_moved_ext
 .extrn    left_motor_cnts_to_move_ext
 .extrn    asleep
 .extrn    tilt_enable
 .extrn    sonar_disable 
 .extrn    sonar_disable_mask
 .extrn    sonar_on_off 
 .extrn    cancel_in_q
 .extrn    continue_in_q
 .extrn    cancel_all
 .extrn    pause_job
 .extrn    job_paused
 .extrn    ramp_tic
 .extrn    left_t0_tic
 .extrn    right_t0_tic
 .extrn    left_t0_tic_pend
 .extrn    right_t0_tic_pend
 .extrn    sonar_status
 .extrn    sonar_1_min_limit_lo
 .extrn    sonar_1_min_limit_hi
 .extrn    sonar_2_min_limit_lo
 .extrn    sonar_2_min_limit_hi
 .extrn    sonar_3_min_limit_lo
 .extrn    sonar_3_min_limit_hi
 .extrn    sonar_4_min_limit_lo
 .extrn    sonar_4_min_limit_hi
 .extrn    sonar_1_max_limit_lo
 .extrn    sonar_1_max_limit_hi
 .extrn    sonar_2_max_limit_lo
 .extrn    sonar_2_max_limit_hi
 .extrn    sonar_3_max_limit_lo
 .extrn    sonar_3_max_limit_hi
 .extrn    sonar_4_max_limit_lo
 .extrn    sonar_4_max_limit_hi
 .extrn    move_reply_process_buff
 .extrn    intrn_reply_ids
 .extrn    on_remote_control

;----------------- END OF EXTERNAL GLOBAL VARIABLES -----------------------

 .endsect


;----------------  START OF MODULE CODE -----------------------------------

 .sect      HIMEM,rom8  
 ; .sect      LOMEM,rom8
 ; .sect      CODE,rom8
 .public    MOVE_MAIN  
 .public    INIT_MOVE
 .extrn     FOLLOW_WALL
 .public    MOVE_MSG_LENGTH_ERROR
 .public    SND_ARC_ABORT_MSG
 .public    SND_SUCCESS_MSG
 .public    STOP_RIGHT_MOTOR
 .public    STOP_LEFT_MOTOR
 .extrn     RIGHT_MOTOR_OPTO_INT_HANDLER
 .extrn     LEFT_MOTOR_OPTO_INT_HANDLER

;--------------- START OF MOVE INITIALIZATION FUNCTION ---------------------

INIT_MOVE:

       ; Irq 3 & irq 4 are initially set zero.  Interrupt on falling edge.
       ; Set to rising edge for limited noise rejection stuff.
    SBIT   3,IRCD.B ;
  .ifdef   OLD_INTS
    SBIT   4,IRCD.B ;
  .else  
    SBIT   2,IRCD.B ;
  .endif
    LD     IRPD.B,#RIGHT_MOTOR_CLR_PEND_MASK ;
    LD     IRPD.B,#LEFT_MOTOR_CLR_PEND_MASK ;
    SBIT   LEFT_MOTOR_DIRECTION_BIT,DIRB_HI.B ; Make pins outputs.
    SBIT   RIGHT_MOTOR_DIRECTION_BIT,DIRB_HI.B ;
            ; Don't care which direction set right now.
    RBIT   LEFT_MOTOR_TOGGLE_BIT,PORTP_LO.B ; Turn off left motor.
    RBIT   LEFT_MOTOR_PIN_BIT,PORTP_LO.B ;
    RBIT   RIGHT_MOTOR_TOGGLE_BIT,PORTP_LO.B ; Turn off right motor.
    RBIT   RIGHT_MOTOR_PIN_BIT,PORTP_LO.B ;

      ; Load the default sonar limits.
    LD     sonar_1_min_limit_lo.B,#DEF_SON_1_MIN_LIM_LO ;
    LD     sonar_1_min_limit_hi.B,#DEF_SON_1_MIN_LIM_HI ;
    LD     sonar_2_min_limit_lo.B,#DEF_SON_2_MIN_LIM_LO ;
    LD     sonar_2_min_limit_hi.B,#DEF_SON_2_MIN_LIM_HI ;
    LD     sonar_3_min_limit_lo.B,#DEF_SON_3_MIN_LIM_LO ;
    LD     sonar_3_min_limit_hi.B,#DEF_SON_3_MIN_LIM_HI ;
    LD     sonar_4_min_limit_lo.B,#DEF_SON_4_MIN_LIM_LO ;
    LD     sonar_4_min_limit_hi.B,#DEF_SON_4_MIN_LIM_HI ;
    LD     sonar_1_max_limit_lo.B,#DEF_SON_1_MAX_LIM_LO ;
    LD     sonar_1_max_limit_hi.B,#DEF_SON_1_MAX_LIM_HI ;
    LD     sonar_2_max_limit_lo.B,#DEF_SON_2_MAX_LIM_LO ;
    LD     sonar_2_max_limit_hi.B,#DEF_SON_2_MAX_LIM_HI ;
    LD     sonar_3_max_limit_lo.B,#DEF_SON_3_MAX_LIM_LO ;
    LD     sonar_3_max_limit_hi.B,#DEF_SON_3_MAX_LIM_HI ;
    LD     sonar_4_max_limit_lo.B,#DEF_SON_4_MAX_LIM_LO ;
    LD     sonar_4_max_limit_hi.B,#DEF_SON_4_MAX_LIM_HI ;
    LD     sonar_disable_mask.B,#0FFH ;

    RET ;

;----------------- END OF MOVE INITIALIZATION FUNCTION  ---------------------



;----------- START OF SUBROUTINE TO START RIGHT MOTOR -------------------

START_RIGHT_MOTOR:

    SBIT   RIGHT_MOTOR_DIRECTION_BIT,PORT_B_HI.B ; Assume forward.
    IFEQ   right_motor_direction,#REV ; Actually reverse?
    RBIT   RIGHT_MOTOR_DIRECTION_BIT,PORT_B_HI.B ; Yes - set reverse.
    LD     speed_slow_down_limit,#SPEED_SLOW_DOWN_MISMATCH_LIMIT ;
    LD     right_dec_cnt,#0 ;
    LD     right_timer_stop,#0 ;
    LD     right_too_fast_cnt,#0 ;
    LD     right_move_tic,#0 ;
    LD     right_tilt_cnt,#0 ;
    LD     right_move_complete,#0 ;
    LD     right_stopping,#0 ;
    LD     right_stop_flag,#0 ;
    LD     right_motor_on,#0FFH ; Show motor running.
    LD     right_motor_stall_cnt.B,#0 ;
    LD     ramp_tic.B,#0 ; Just starting.
    LD     last_ramp_tic,#0 ;
    LD     last_right_ramp_tic,#0 ;
    LD     right_on_control,#0 ;
    LD     right_t0_tic.B,#2 ; Will force a load of capture.
    LD     right_t0_tic_pend.B,#0 ;
    LD     BP_right_speed.W,#0FFFFH ;
    LD     A,BP_right_set_pt.W ;
    ADD    A,#1000 ;
    LD     RIGHT_MOTOR_TIMER_REG.W,#A ; 
    LD     RIGHT_MOTOR_PWM_LOAD_REG.W,#A ;
    RBIT   RIGHT_MOTOR_TOGGLE_BIT,PORTP_LO.B ;
    SBIT   RIGHT_MOTOR_PIN_BIT,PORTP_LO.B ; Set on to start.
    SBIT   RIGHT_MOTOR_ACK_BIT,PWMODE_LO.B ; Clr any pending.
    SBIT   RIGHT_MOTOR_PWM_INT_EN_BIT,PWMODE_LO.B ; Enable pwm int.
    RBIT   RIGHT_MOTOR_PWM_STP_BIT,PWMODE_LO.B ; & Start the timer.
    RET     ; Right hand motor is started.


;----------- END OF SUBROUTINE TO START RIGHT MOTOR -------------------


;----------- START OF SUBROUTINE TO START LEFT MOTOR -------------------

START_LEFT_MOTOR:

    SBIT   LEFT_MOTOR_DIRECTION_BIT,PORT_B_HI.B ; Assume forward.
    IFEQ   left_motor_direction,#REV ; Actually reverse?
    RBIT   LEFT_MOTOR_DIRECTION_BIT,PORT_B_HI.B ; Yes - set reverse.
    LD     speed_slow_down_limit,#SPEED_SLOW_DOWN_MISMATCH_LIMIT ;
    LD     left_dec_cnt,#0 ;
    LD     left_timer_stop,#0 ;
    LD     left_too_fast_cnt,#0 ;
    LD     left_move_tic,#0 ;
    LD     left_tilt_cnt,#0 ;
    LD     left_move_complete,#0 ;
    LD     left_stopping,#0 ;
    LD     left_stop_flag,#0 ;
    LD     left_motor_on,#0FFH ; Show motor running.
    LD     left_motor_stall_cnt.B,#0 ;
    LD     ramp_tic.B,#0 ; Just starting.
    LD     last_ramp_tic,#0 ;
    LD     last_left_ramp_tic,#0 ;
    LD     left_on_control,#0 ;
    LD     left_t0_tic.B,#2 ; Will force a load of capture.
    LD     left_t0_tic_pend.B,#0 ;
    LD     BP_left_speed.W,#0FFFFH ;
    LD     A,BP_left_set_pt.W ;
    ADD    A,#1000 ;
    LD     LEFT_MOTOR_TIMER_REG.W,#A ; 
    LD     LEFT_MOTOR_PWM_LOAD_REG.W,#A ;
    RBIT   LEFT_MOTOR_TOGGLE_BIT,PORTP_LO.B ;
    SBIT   LEFT_MOTOR_PIN_BIT,PORTP_LO.B ; Set on to start.
    SBIT   LEFT_MOTOR_ACK_BIT,PWMODE_LO.B ; Clr any pending.
    SBIT   LEFT_MOTOR_PWM_INT_EN_BIT,PWMODE_LO.B ; Enable pwm int.
    RBIT   LEFT_MOTOR_PWM_STP_BIT,PWMODE_LO.B ; & Start the timer.
    RET     ; Right hand motor is started.


;----------- END OF SUBROUTINE TO START LEFT MOTOR -------------------


;------------ START OF SUBROUTINE TO STOP RIGHT MOTOR -----------------

STOP_RIGHT_MOTOR: 

    RBIT   RIGHT_MOTOR_PWM_INT_EN_BIT,PWMODE_LO.B ; Disable the pwm int.
    SBIT   RIGHT_MOTOR_PWM_STP_BIT,PWMODE_LO.B ; & stop the timer.
    NOP     ; Delay for any pending.
    NOP     ;
    SBIT   RIGHT_MOTOR_ACK_BIT,PWMODE_LO.B ; & clear any pending.
    RBIT   RIGHT_MOTOR_TOGGLE_BIT,PORTP_LO.B ; Make pin latched output.
    RBIT   RIGHT_MOTOR_PIN_BIT,PORTP_LO.B ; Turns off motor.
    LD     right_motor_on,#0 ; Show motor is stopped.
    LD     both_motors_on,#0 ;
    LD     right_on_control,#0 ;
    RET     ; Motor is turned off.

;------------ END OF SUBROUTINE TO STOP RIGHT MOTOR -----------------


;------------ START OF SUBROUTINE TO STOP LEFT MOTOR -----------------

STOP_LEFT_MOTOR: 

    RBIT   LEFT_MOTOR_PWM_INT_EN_BIT,PWMODE_LO.B ; Disable the pwm int.
    SBIT   LEFT_MOTOR_PWM_STP_BIT,PWMODE_LO.B ; & stop the timer.
    NOP     ; Delay for any pending.
    NOP     ;
    SBIT   LEFT_MOTOR_ACK_BIT,PWMODE_LO.B ; & clear any pending.
    RBIT   LEFT_MOTOR_TOGGLE_BIT,PORTP_LO.B ; Make pin latched output.
    RBIT   LEFT_MOTOR_PIN_BIT,PORTP_LO.B ; Turns off motor.
    LD     left_motor_on,#0 ; Show motor is stopped.
    LD     both_motors_on,#0 ;
    LD     left_on_control,#0 ;
    RET     ; Motor is turned off.

;------------ END OF SUBROUTINE TO STOP LEFT MOTOR -----------------


;------ START OF SUBROUTINE TO CALC PIVOT COUNT FOR OPTION ZERO --------

CALC_PIVOT_COUNT:
          ; Enter with degrees to pivot in A.  Sets up all variables
          ; ready to start motors turning.
    LD     stay_on,#0 ;
    IFBIT  7,A_REG_HI.B ; Negative degrees?
    JMP    ROTATE_RIGHT ; Yes - go clockwise.
          ; Otherwise fall thru to left (CCW) ;
    LD     right_motor_direction,#FWD ; Right motor forward.
    LD     left_motor_direction,#REV  ; Left motor reverse.
    JMP    PIVOT_COUNT_CALC ;
 ROTATE_RIGHT:
    LD     right_motor_direction,#REV ; Right motor reverse.
    LD     left_motor_direction,#FWD  ; Left motor forward.
    COMP   A  ; Turn degrees positive.
    INC    A  ; Two's complement.
 PIVOT_COUNT_CALC:
        ; Counts to turn = degrees*(PIVOT_CNT_CALC_MULT/1000)
    MULT   A,#PIVOT_CNT_CALC_MULT ;
    DIVD   A,#1000  ;
    PUSH   X   ; This assembler does funny things with X, so want
    POP    B   ; remainder in B for round off.
    IFGT   B,#500 ; Round up?
    INC    A  ; Yes.
    PUSH   A  ;
    SHR    A  ;
    COMP   A  ;
    INC    A  ;
    LD     BP_right_motor_slow_down.W,A ;
    LD     BP_left_motor_slow_down.W,A ;
    POP    A  ;
    COMP   A  ; Make negative for interrupt routine.
    INC    A  ;
    LD     BP_right_motor_cnts_to_move.W,A ; Set the count down.
    LD     BP_left_motor_cnts_to_move.W,A ;
    LD     BP_right_motor_cnts_moved.W,#0 ; Haven't moved yet.
    LD     BP_left_motor_cnts_moved.W,#0 ; Haven't moved yet.

    RET      ; Ready to start up motors.

;----- END OF SUBROUTINE TO SET UP PIVOT FOR OPTION ZERO -----------------

;-------- START OF SUBROUTINE TO CALCULATE DEGREES ROTATED --------------- 

CALC_DEGREES_ROTATED:

    LD     A,BP_right_motor_cnts_moved.W ; Assume both turned same.
               ; Can only rotate 360 degrees max so don't need 24 bit ext.
    MULT   A,#1000 ; Inverse of calc counts.
    DIVD   A,#PIVOT_CNT_CALC_MULT ;
    PUSH   X ;
    POP    B ;
    IFGT   B,#DEG_PIVOTED_RND_OFF ;
    INC    A ;
    IFBIT  7,degrees_hi ; Commanded negative?
    JMP    NEGATE_DEGREES_ROTATED ;
 LD_DEGREES_ROTATED:
    LD     degrees_moved_hi,A_REG_HI.B ;
    LD     degrees_moved_lo,A_REG_LO.B ;
    RET      ; All done.
 NEGATE_DEGREES_ROTATED:
    COMP   A ;
    INC    A ;
    JMP    LD_DEGREES_ROTATED ;

;--------- END OF SUBROUTINE TO CALCULATE DEGREES ROTATED --------------- 
  
;------- START OF SUBROUTINE TO CALC COUNTS FOR A GIVEN DISTANCE ---------

CALC_DISTANCE_COUNTS:
            ; Enter with tenths of feet to move in A.
            ; Moves DIST_CALC_DIVISOR/10000 ft per opto interrupt.
            ; Moves DIST_CALC_DIVISOR/1000 tenths of a foot per opto int.
            ; Mult by 10,000 is max for 16 * 16 bit multiply.
            ; i.e. 100,000 is to big & don't want to get too tricky here.
            ; (tenths of feet) * 10,000 / DISTANCE_CALC_DIVISOR = counts to move.
    IFBIT  7,A_REG_HI.B ; Negative value?
    JMP    MAKE_POSITIVE ;
    IFEQ   A,#07FFF ; Run forever distance?
    JMP    TURN_ON_INDEFINITE ;
    LD     stay_on,#0 ;
    JMP    DO_DIST_CNT_CALC ;
 MAKE_POSITIVE:
    COMP   A   ; Make positive.
    INC    A   ; Two's comp.
    IFGT   A,#100 ; Not going to move more than 10 feet backwards.
    LD     A,#100 ; Just override any over 10 feet.
 DO_DIST_CNT_CALC:
    IFGT   A,#DIST_CALC_MAX_DIST_CHK ; Going to keep cnts to move in one word.
    LD     A,#DIST_CALC_MAX_DIST_CHK ;
    MULT   A,#10000 ; 
    PUSH   A   ; Save lo word of result.
    PUSH   X   ; Need hi word of result in A & this assemble won't
    POP    A   ; do a LD  A,X.
          ; Can't use regular DIVD 'cause result might not fit into
          ; 16 bit result.
    DIV    A,#DIST_CALC_DIVISOR ; Divide hi word. 
    LD     B,A ; Result is 24 bit cnt extension - save. X has remainder.
    POP    A   ; Lo word of distance * 100,000 into A. 
    DIVD   A,#DIST_CALC_DIVISOR ; 16 bit counts to move in A.
    PUSH   B  ;
    PUSH   X  ; Get remainder into B for round off.
    POP    B  ; 
    IFGT   B,#DIST_CALC_RND_OFF ;
    ADD    A,#1 ;
    POP    B  ;
    IFC         ; Carry on round off?
    INC    B  ;
    COMP   A  ; Make negative for interrupt routine.
    XOR    B,#-1 ;
    INC    A  ;
    IFGT   A,#0 ;
    RET      ;
    INC    B ;
    RET       ; All done. A has lo word of cnts to move.
              ; B has 24 bit extension byte.

 TURN_ON_INDEFINITE:
    LD     stay_on,#0FFH ;
    RET      ;


;-------- END OF SUBROUTINE TO CALC COUNTS FOR A GIVEN DISTANCE ---------

;----- START OF SUBROUTINE TO CALC DISTANCE MOVED FOR GIVEN COUNTS ------

CALC_DISTANCE_MOVED:
           ; Enter with B = lo word of counts moved.
           ; & with A = zero extended count extension.
           ; Inverse of calc counts.
    MULT   A,#DIST_CALC_DIVISOR ; Multiply extension.
    PUSH   A ; Save result - won't be over 16 bits.
    LD     A,B ; Now do lo word.
    MULT   A,#DIST_CALC_DIVISOR ;
    POP    B ; Double precision stuff.
    PUSH   A ;
    PUSH   X ;
    POP    A ;
    ADD    A,B ;
    PUSH   A ;
    POP    X ;
    POP    A ;
    DIVD   A,#10000 ; Finally have feet in A.
    PUSH   X ;
    POP    B ;
    IFGT   B,#5000 ;
    INC    A ;
    IFBIT  7,ft_hi ; Negative command?
    JMP    NEGATE_DISTANCE_MOVED ;
 LD_DISTANCE_MOVED:
    LD     distance_moved_hi,A_REG_HI.B ;
    LD     distance_moved_lo,A_REG_LO.B ;
    RET      ; All done.

 NEGATE_DISTANCE_MOVED:
    COMP   A ;
    INC    A ;
    JMP    LD_DISTANCE_MOVED ;

;------  END OF SUBROUTINE TO CALC DISTANCE MOVED FOR GIVEN COUNTS ------
 
;--------------  START OF MOVE MAIN ROUTINE ------------------------------

MOVE_MAIN:

    IFGT   waiting_for_move_tx,#0 ; Waiting to send last msg??
    JMP    TRY_MOVE_TX_AGAIN ;
    IFGT   buffer_full_errors + 0.B,#0 ; Command didn't make it?
    JSR    SND_MOVE_BUFFER_FULL_ERROR ; If so tell 'em.
    IFGT   msg_too_long_errors + 0.B,#0 ;
    JSR    MOVE_MSG_TOO_LONG_ERROR ;
    IFEQ   jobs_in_q + 0.B,#0 ;
    RET     ;
    IFGT   job_state + 0.B,#0 ; Job already running?
    JMP    MOVE_ROBOT ; Yes - go continue.
            ; Else load parameters.
    LD     X,#move_process_buff ;
    LD     A,job_in_q_btm_ptrs + 0.B ; Pointer to count byte in q.
    LD     B,A ;
    LD     A,job_zero_in_q[B].B ; Get the count byte.
    LD     move_msg_loop_cnt,A ;
    DECSZ  move_msg_loop_cnt ;
    NOP     ;
    X      A,[X+].B ;
 MOVE_NXT_BYTE:
    INC    B ; To get command byte.
    AND    B,#JOB_IN_Q_ROLLOVER ;
    LD     A,job_zero_in_q[B].B ; Get the next byte. 
    X      A,[X+].B ; & store it.
    DECSZ  move_msg_loop_cnt ;
    JMP    MOVE_NXT_BYTE ;
    LD     A,job_zero_in_q[B].B ;
    LD     move_cancel_byte,A ;
    AND    A,#07 ; Do speed so we don't have to do again.
    LD     speed,A ;
    INC    B ;
    AND    B,#JOB_IN_Q_ROLLOVER ;
    LD     job_in_q_btm_ptrs + 0.B,B ; Save for next.
    LD     pause_job + 0.B,#0 ;
    IFGT   move_process_buff + 1,#03 ;
    JMP    SND_NOT_IMPLEMENTED_ERROR ;
    IFBIT  CANCEL_BIT,move_cancel_byte ;
    DECSZ  cancel_in_q + 0.B ;
    NOP     ;
    IFBIT  INTERNAL_REQUEST_BIT,move_cancel_byte ; Going to adjust count if
    DECSZ  move_process_buff + 0 ; internal msg for length checks.
            ; Will never be zero, so next will always execute.
    IFGT   on_remote_control.B,#0 ;
    JSR    CHK_FOR_REMOTE_INTERNAL ; Won't come back if not internal.
    IFEQ   move_process_buff + 1,#0  ; Rotate & move command?
    JMP    SET_ROTATE_AND_MOVE_PARAMS ;
    IFEQ   move_process_buff + 1,#1  ; Distance arc command?
    JMP    SET_DISTANCE_ARC_PARAMS ;
    IFEQ   move_process_buff + 1,#3 ; Wall follow?
    JMP    MOVE_ROBOT ;
         ; Fall thru means must be degree arc command.
    LD     degrees_lo,move_process_buff + 2 ;
    LD     degrees_hi,move_process_buff + 3 ;
    LD     radius,move_process_buff + 4 ;
    JMP    MOVE_ROBOT ;
SET_DISTANCE_ARC_PARAMS:
    LD     ft_lo,move_process_buff + 2 ;
    LD     ft_hi,move_process_buff + 3 ;
    LD     radius,move_process_buff + 4 ;
    JMP    MOVE_ROBOT ;
SET_ROTATE_AND_MOVE_PARAMS:
    LD     degrees_lo,move_process_buff + 2 ;
    LD     degrees_hi,move_process_buff + 3 ;
    LD     ft_lo,move_process_buff + 4 ;
    LD     ft_hi,move_process_buff + 5 ;


MOVE_ROBOT:
    IFEQ   move_process_buff + 1,#0 ; Rotate & move?
    JMP    ROTATE_AND_MOVE ;
    IFEQ   move_process_buff + 1,#3 ; Wall follow?
    JMP    TST_INT_TIME ; FOLLOW_WALL ;
          ; Else must be an arc move.
    LD     A,job_state + 0.B ; Where are we?
    JID    ; Jump according to state.
    .PT    DO_SETUP_ARC,DO_ARC_CONTINUE,DO_ARC_PAUSED
    .PT    DO_WAIT_FOR_ARC_PAUSE_STOP,DO_WAIT_FOR_ARC_COLLISION_STOP

  DO_SETUP_ARC:
    IFEQ   move_process_buff + 0,#6 ;
    JMP    SETUP_ARC ;
    JMP    MOVE_MSG_LENGTH_ERROR ;
  DO_ARC_CONTINUE:
    JMP    ARC_CONTINUE ;
  DO_ARC_PAUSED:
    JMP    ARC_PAUSED ;
  DO_WAIT_FOR_ARC_PAUSE_STOP:
    JMP    WAIT_FOR_ARC_PAUSE_STOP ;
  DO_WAIT_FOR_ARC_COLLISION_STOP:
    JMP    WAIT_FOR_ARC_COLLISION_STOP ;

 ROTATE_AND_MOVE:
    LD     A,job_state + 0.B ; Where are we?
    JID     ; Jump according to state.
    .PT    DO_SETUP_N_START_ROTATE,DO_CONTINUE_ROTATE,DO_START_SL_MOVE
    .PT    DO_CONTINUE_SL_MOVE,DO_R_N_M_PAUSED,DO_WAIT_FOR_PAUSE_STOP
    .PT    DO_WAIT_FOR_ROT_COLLISION_STOP,DO_WAIT_FOR_SL_COLLISION_STOP

 DO_SETUP_N_START_ROTATE:
    IFEQ   move_process_buff + 0,#7 ;
    JMP    SETUP_N_START_ROTATE ;
    JMP    MOVE_MSG_LENGTH_ERROR ;
 DO_CONTINUE_ROTATE:
    JMP    CONTINUE_ROTATE ;
 DO_START_SL_MOVE:
    JMP    START_SL_MOVE ;
 DO_CONTINUE_SL_MOVE:
    JMP    CONTINUE_SL_MOVE ;
 DO_R_N_M_PAUSED:
    JMP    R_N_M_PAUSED ;
 DO_WAIT_FOR_PAUSE_STOP:
    JMP    WAIT_FOR_PAUSE_STOP ;
 DO_WAIT_FOR_ROT_COLLISION_STOP:  
    JMP    WAIT_FOR_ROT_COLLISION_STOP ;
 DO_WAIT_FOR_SL_COLLISION_STOP:
    JMP    WAIT_FOR_SL_COLLISION_STOP ;

;-------------- START OF CHECK FOR REMOTE INTERNAL ----------------------

CHK_FOR_REMOTE_INTERNAL:
    IFBIT  INTERNAL_REQUEST_BIT,move_cancel_byte  ;
    RET      ;
    POP    X ; Get rid of return address.
    JMP    REJECTED_WHILE_REMOTE ;

;------------- END OF CHECK FOR REMOTE INTERNAL --------------------------


;---------- START OF MOVE 0 SETUP & STARTING ROTATION --------------------

 .public SETUP_N_START_ROTATE
SETUP_N_START_ROTATE:

    LD     stay_on,#0 ;
    LD     degrees_moved_lo,#0 ; These will already be set if we
    LD     degrees_moved_hi,#0 ; have to abort with no movement.
    LD     distance_moved_lo,#0 ;
    LD     distance_moved_hi,#0 ;
    LD     rotate_flag,#0 ;
    LD     stop_flag,#0 ;
    LD     left_on_sl_control,#0 ;
    LD     right_on_sl_control,#0FFH ;
    IFEQ   speed,#0  ; Speed zero? 
    JMP    R_N_M_ZERO_MOVE ; Yes - go abort zero move.
    IFEQ   tilt_enable.B,#0 ;
    JMP    CHK_MOVE_ZERO_STARTUP_SONAR ;
    IFBIT  TILT_BIT,DIGITAL_STATUS_PORT.B ; Tilted?
    JMP    CHK_MOVE_ZERO_STARTUP_SONAR ;
    JMP    MOVE_ZERO_STARTUP_TILT_ABORT ;
 CHK_MOVE_ZERO_STARTUP_SONAR:
    IFEQ   sonar_on_off.B,#0FFH ; Sonar turned on?
    JMP    PAST_STRT_ROT_SONAR_CHK ;
    IFEQ   sonar_disable.B,#0FFH ; Sonar enabled?
    JMP    PAST_STRT_ROT_SONAR_CHK ;
    JSR    CHK_SONAR  ;
    IFBIT  7,A_REG_LO.B ; Drop off detected?
 ;  IFGT   A,#0  ; Collision?
    JMP    MOVE_ZERO_STARTUP_COLLISION_ABORT ;
 PAST_STRT_ROT_SONAR_CHK:
    LD     right_motor_stall_limit,#R_N_M_STALL_LIMIT ;
    LD     left_motor_stall_limit,#R_N_M_STALL_LIMIT ;
    IFGT   degrees_lo,#0 ; Chk for no rotate.
    JMP    WILL_ROTATE ;
    IFGT   degrees_hi,#0 ; 
    JMP    WILL_ROTATE ;
    JMP    SETUP_SL_MOVE ;
 WILL_ROTATE:
    LD     rotate_flag,#0FFH ;
    LD     A_REG_LO.B,degrees_lo ; Get degrees to turn.
    LD     A_REG_HI.B,degrees_hi ;
    JSR    CALC_PIVOT_COUNT  ; Go setup move.
    LD     A,speed ;
    DEC    A ;
    PUSH   A ;
    MULT   A,#CONTROL_SPEED_STEP ;
    LD     B,#MIN_CONTROL_SPEED_TIME ;
    SC      ;
    SUBC   B,A ;
    LD     BP_right_ramped_set_pt.W,B ;
    LD     BP_left_ramped_set_pt.W,B ;
    POP    A ;
    MULT   A,#ROT_SLOW_DOWN_MULTIPLIER ;
    COMP   A ;
    LD     B,A ;
    LD     A,BP_right_motor_cnts_to_move.W ;
    SHR    A  ;
    SBIT   7,A_REG_HI.B ;
    IFGT   A,B ; 
    LD     B,A ; 
    LD     BP_right_motor_slow_down.W,B ;
    LD     BP_left_motor_slow_down.W,B ;
    LD     BP_left_set_pt.W,#MIN_CONTROL_SPEED_TIME ;
    LD     BP_right_set_pt.W,#MIN_CONTROL_SPEED_TIME ;
    LD     A,#RAMP_STEP_DELTA ;
    LD     right_ramp_delta_lo,A_REG_LO.B ;
    LD     right_ramp_delta_hi,A_REG_HI.B ;
    LD     left_ramp_delta_lo,A_REG_LO.B ;
    LD     left_ramp_delta_hi,A_REG_HI.B ;
    LD     left_control_state,#RAMP_STATE ;
    LD     right_control_state,#RAMP_STATE ;
    JSR    START_RIGHT_MOTOR ; Crank up the move.
    JSR    START_LEFT_MOTOR ;
    LD     both_motors_on,#0FFH ;
 DONE_WITH_SETUP_N_START_ROTATE:
    LD     job_state + 0.B,#1 ; Will go to continue rotate next time.
    RET      ; Setup & running.

;----------- END OF MOVE 0 SETUP & STARTING ROTATION --------------------



;--------- START OF CONTINUE ROTATE ON MOVE ZERO COMMAND ----------------

 .public CONTINUE_ROTATE
CONTINUE_ROTATE:

           ; Chk for control & errors.
    IFEQ   right_motor_on,#0FFH ; Still running?
    JMP    CHK_ROTATE_PAUSE ;
    IFEQ   left_motor_on,#0FFH ; Chk both.
    JMP    CHK_ROTATE_PAUSE ;
          ; Fall thru means done with rotate.
    LD     rotate_flag,#0 ;
    LD     job_state + 0.B,#2 ;
    RET     ; Done with rotate.
 CHK_ROTATE_PAUSE:
    IFGT   pause_job + 0.B,#0 ; Pause commanded?
    JMP    PAUSE_R_N_M_MOVE ;
    IFEQ   tilt_enable.B,#0 ;
    JMP    CHK_ROTATE_SONAR ;
    IFGT   left_tilt_cnt,#7 ;
    JMP    MOVE_ZERO_ROTATE_TILT_ABORT ;
    IFGT   right_tilt_cnt,#7 ;
    JMP    MOVE_ZERO_ROTATE_TILT_ABORT ;
 ;  IFBIT  TILT_BIT,DIGITAL_STATUS_PORT.B ; Tilted?
 ;  JMP    CHK_ROTATE_SONAR ;
 ;  JMP    MOVE_ZERO_ROTATE_TILT_ABORT ;
 CHK_ROTATE_SONAR:
    IFEQ   sonar_on_off.B,#0FFH ; Sonar turned on?
    JMP    PAST_ROT_SONAR_CHK ;
    IFEQ   sonar_disable.B,#0FFH ; Sonar enabled?
    JMP    PAST_ROT_SONAR_CHK ;
    JSR    CHK_SONAR  ;
    IFBIT  7,A_REG_LO.B ; Drop off detected?
 ;  IFGT   A,#0  ; Collision?
    JMP    MOVE_ZERO_ROTATE_COLLISION_ABORT ;
 PAST_ROT_SONAR_CHK:
    IFGT   cancel_in_q + 0.B,#0 ; Cancel received?
    JMP    CANCEL_MOVE_ROBOT ;
    IFGT   cancel_all + 0.B,#0  ; Cancel everything?
    JMP    CANCEL_ALL_MOVE_ROBOT ;
    IFEQ   right_motor_on,#0 ;
    JMP    CHK_ROT_LEFT_STALL ;
    IFGT   right_motor_stall_cnt.B,right_motor_stall_limit ; Stalled?
    JMP    ROT_STALL_ABORT ;
 CHK_ROT_LEFT_STALL:
    IFEQ   left_motor_on,#0 ;
    RET      ; 
    IFGT   left_motor_stall_cnt.B,left_motor_stall_limit ;
    JMP    ROT_STALL_ABORT ;
    RET     ;

;---------- END OF CONTINUE ROTATE ON MOVE ZERO COMMAND ----------------


;------------  START OF START STRAIGHT LINE MOVE  -----------------------

 .public START_SL_MOVE
START_SL_MOVE:

    LD     A,degrees_hi ; Successful, so we moved all the way, right?
    LD     degrees_moved_hi,A ;
    LD     A,degrees_lo ;
    LD     degrees_moved_lo,A ;
          ; Set up S/L move.
 SETUP_SL_MOVE:
    LD     A_REG_LO.B,ft_lo ;
    LD     A_REG_HI.B,ft_hi ;
    IFGT   A,#0 ; All done?
    JMP    WILL_DO_SL_MOVE ;
    LD     job_state + 0.B,#0 ;
    JMP    DONE_WITH_R_N_M ;
 WILL_DO_SL_MOVE:
 ;  JSR    CLR_COMPARE ;
    IFBIT  7,A_REG_HI.B ; Reverse direction?
    JMP    SL_REVERSE ;
    LD     right_motor_direction,#FWD ; Fall thru is forward.
    LD     left_motor_direction,#FWD  ; Both motors. 
    JMP    CALC_SL_DISTANCE ;
  SL_REVERSE:
    LD     right_motor_direction,#REV ; Set reverse.
    LD     left_motor_direction,#REV  ; Both motors. 
  CALC_SL_DISTANCE:
    JSR    CALC_DISTANCE_COUNTS ;
    LD     BP_right_motor_cnts_to_move.W,A ;
    LD     BP_left_motor_cnts_to_move.W,A ;
    LD     BP_right_motor_cnts_moved.W,#0 ;
    LD     BP_left_motor_cnts_moved.W,#0 ;
    LD     A,speed ;
    DEC    A ;
    PUSH   A ;
    MULT   A,#CONTROL_SPEED_STEP ;
    LD     B,#MIN_CONTROL_SPEED_TIME ;
    SC      ;
    SUBC   B,A ;
    LD     BP_right_ramped_set_pt.W,B ;
    LD     BP_left_ramped_set_pt.W,B ;
    POP    A ;
    MULT   A,#SL_SLOW_DOWN_MULTIPLIER ;
    COMP   A ;
    LD     B,A ;
    LD     A,BP_right_motor_cnts_to_move.W ;
    SHR    A  ;
    SBIT   7,A_REG_HI.B ;
    IFGT   A,B ; 
    LD     B,A ; 
    LD     BP_right_motor_slow_down.W,B ;
    LD     BP_left_motor_slow_down.W,B ;
    LD     A,#RAMP_STEP_DELTA ;
    LD     right_ramp_delta_lo,A_REG_LO.B ;
    LD     right_ramp_delta_hi,A_REG_HI.B ;
    LD     left_ramp_delta_lo,A_REG_LO.B ;
    LD     left_ramp_delta_hi,A_REG_HI.B ;
    IFGT   continue_in_q + 0.B,#0 ;
    JMP    NO_RAMP_SL_SETUP ;
    LD     BP_left_set_pt.W,#MIN_CONTROL_SPEED_TIME ;
    LD     BP_right_set_pt.W,#MIN_CONTROL_SPEED_TIME ;
    LD     left_control_state,#RAMP_STATE ;
    LD     right_control_state,#RAMP_STATE ;
    JMP    START_SL_MOTORS ;
 NO_RAMP_SL_SETUP:
    LD     BP_left_set_pt.W,BP_left_ramped_set_pt.W ;
    LD     BP_right_set_pt.W,BP_right_ramped_set_pt.W ;
    IFGT   speed,#BANG_PWM_TRANSITION_SPEED ;
    LD     left_control_state,#RUNNING_STATE ;
    LD     right_control_state,#RUNNING_STATE ;
 START_SL_MOTORS:
    JSR    START_RIGHT_MOTOR ;
    JSR    START_LEFT_MOTOR ;
    LD     both_motors_on,#0FFH ;
 DONE_WITH_START_SL_MOVE:
    LD     job_state + 0.B,#3 ;
    RET     ;


;------------- START OF CONTINUE STRAIGHT LINE MOVE ---------------------

 .public CONTINUE_SL_MOVE
CONTINUE_SL_MOVE:
        
           ; Chk for control & errors.
    IFEQ   right_motor_on,#0FFH ; Still running?
    JMP    CHK_SL_PAUSE ; 
    IFEQ   left_motor_on,#0FFH ; Chk both.
    JMP    CHK_SL_PAUSE ;
          ; Fall thru means done with move.
    LD     job_state + 0.B,#0 ;
    JMP    DONE_WITH_R_N_M ; All done successfully.
 CHK_SL_PAUSE:
    IFGT   pause_job + 0.B,#0 ; Pause commanded?
    JMP    PAUSE_R_N_M_MOVE ;
    IFEQ   tilt_enable.B,#0 ;
    JMP    CHK_SL_SONAR ;
    IFGT   left_tilt_cnt,#7 ;
    JMP    MOVE_ZERO_SL_TILT_ABORT ;
    IFGT   right_tilt_cnt,#7 ;
    JMP    MOVE_ZERO_SL_TILT_ABORT ;
 ;  IFBIT  TILT_BIT,DIGITAL_STATUS_PORT.B ; Tilted?
 ;  JMP    CHK_SL_SONAR ;
 ;  JMP    MOVE_ZERO_SL_TILT_ABORT ;
 CHK_SL_SONAR:
    IFEQ   sonar_on_off.B,#0FFH ; Sonar turned on?
    JMP    PAST_SL_SONAR_CHK ;
    IFEQ   sonar_disable.B,#0FFH ; Sonar enabled?
    JMP    PAST_SL_SONAR_CHK ;
    JSR    CHK_SONAR  ;
    IFGT   A,#0  ; Collision?
    JMP    MOVE_ZERO_SL_COLLISION_ABORT ;
 PAST_SL_SONAR_CHK:
    IFGT   cancel_in_q + 0.B,#0 ; Cancel received?
    JMP    CANCEL_MOVE_ROBOT ;
    IFGT   cancel_all + 0.B,#0  ; Cancel everything?
    JMP    CANCEL_ALL_MOVE_ROBOT ;
    IFEQ   right_motor_on,#0 ;
    JMP    CHK_SL_LEFT_STALL ;
    IFGT   right_motor_stall_cnt.B,right_motor_stall_limit ; Stalled?
    JMP    SL_STALL_ABORT ;
 CHK_SL_LEFT_STALL:
    IFEQ   left_motor_on,#0 ;
    RET     ; 
    IFGT   left_motor_stall_cnt.B,left_motor_stall_limit ;
    JMP    SL_STALL_ABORT ;
    RET     ;

;-------------- END OF CONTINUE STRAIGHT LINE MOVE ---------------------


;-------------- START OF ROTATE & MOVE PAUSE ROUTINES -------------------

PAUSE_R_N_M_MOVE:
    LD     stop_flag,#0FFH ;
    LD     paused_stay_on,stay_on ;
    LD     move_paused_state,job_state + 0.B ;
    LD     job_state +0.B,#5 ;
    RET     ;

WAIT_FOR_PAUSE_STOP:
    IFGT   right_t0_tic.B,#10 ;
    JSR    STOP_RIGHT_MOTOR ;
    IFGT   left_t0_tic.B,#10 ;
    JSR    STOP_LEFT_MOTOR ;
    IFGT   right_motor_on,#0 ;
    RET     ;
    IFGT   left_motor_on,#0 ;
    RET     ;
    IFEQ   move_paused_state,#1 ;
    JSR    CALC_DEGREES_ROTATED ;
    IFEQ   move_paused_state,#3 ;
    JMP    SET_PAUSE_MSG_DISTANCE ;
    JMP    CONTINUE_PAUSING_R_N_M ;
 SET_PAUSE_MSG_DISTANCE:
    LD     B.W,BP_right_motor_cnts_moved.W ;
    LD     A,#0 ;
    JSR    CALC_DISTANCE_MOVED  ;
 CONTINUE_PAUSING_R_N_M:
    LD     job_state + 0.B,#4  ;
    LD     job_paused + 0.B,#0FFH ;
    LD     move_reply_process_buff + 2.B,#JOB_PAUSED ;
    IFGT   on_remote_control.B,#0 ;
    RET     ;
    JMP    SND_R_N_M_ABORT_MSG_W_O_STATE_RESET  ;


R_N_M_PAUSED:
    IFGT   cancel_in_q + 0.B,#0 ; Cancel received?
    JMP    CANCEL_MOVE_ROBOT ;
    IFGT   cancel_all + 0.B,#0  ; Cancel everything?
    JMP    CANCEL_ALL_MOVE_ROBOT ;
    IFGT   pause_job + 0.B,#0  ; Still paused?
    RET      ; Yes - go back.
         ; Else start back up.
    LD     stay_on,paused_stay_on ;
    LD     stop_flag,#0 ;
    LD     job_paused + 0.B,#0 ;
    LD     BP_left_set_pt.W,#MIN_CONTROL_SPEED_TIME ;
    LD     BP_right_set_pt.W,#MIN_CONTROL_SPEED_TIME ;
    LD     A,#RAMP_STEP_DELTA ;
    LD     right_ramp_delta_lo,A_REG_LO.B ;
    LD     right_ramp_delta_hi,A_REG_HI.B ;
    LD     left_ramp_delta_lo,A_REG_LO.B ;
    LD     left_ramp_delta_hi,A_REG_HI.B ;
    LD     left_control_state,#RAMP_STATE ;
    LD     right_control_state,#RAMP_STATE ;
 ;  SBIT   LEFT_MOTOR_TOGGLE_BIT,PORTP_LO.B ;
 ;  SBIT   RIGHT_MOTOR_TOGGLE_BIT,PORTP_LO.B ;
    IFEQ   right_move_complete,#0 ;
    JSR    START_RIGHT_MOTOR ;
    IFEQ   left_move_complete,#0 ;
    JSR    START_LEFT_MOTOR ;
    LD     both_motors_on,#0FFH ;
    LD     job_state + 0.B,move_paused_state ;
    LD     move_reply_process_buff + 2.B,#JOB_RESUMED ;
    IFGT   on_remote_control.B,#0 ;
    RET     ;
    JMP    SND_R_N_M_ABORT_MSG_W_O_STATE_RESET ; Info should still 
                                               ; be all right.

;--------------- END OF ROTATE & MOVE PAUSE ROUTINES -------------------


 .incld   ARCMOVES
 .incld   MOVUTILS


 .extrn   head_stall_tic
 .extrn   DO_CONVERSION ;
 TST_INT_TIME:
    SBIT   2,T0CON.B ;
    LD     stay_on,#0FFH ;
    LD     left_control_state,#1 ;
    LD     right_control_state,#1 ;
    JSR    START_RIGHT_MOTOR ;
    JSR    START_LEFT_MOTOR ;
    LD     X_REG.W,#1000  ;
    LD     BP_temp_reg.W,I4CR.W ;
    LD     head_stall_tic.B,#0 ;
  TIME_LOOP:
    JSR    RIGHT_MOTOR_OPTO_INT_HANDLER ;
    JSR    RIGHT_MOTOR_OPTO_INT_HANDLER ;
 ;  JSR    DO_CONVERSION ;
    DECSZ  X_REG.W ;
    JMP    TIME_LOOP ;
    LD     A,I4CR.W ;
    LD     B,head_stall_tic.B ;
    RBIT   2,T0CON.B ;
    SC       ;
    SUBC   A,BP_temp_reg.W ;
    SUBC   B,#0 ;
    PUSH   A ;
    PUSH   B ;
    JSR    STOP_RIGHT_MOTOR ;
    JSR    STOP_LEFT_MOTOR ;
    JSR    ONE_LESS_MOVE_JOB ;
    POP    B ;
    POP    A ;
    LD     move_reply_process_buff + 0.B,#5 ;
    LD     move_reply_process_buff + 1.B,move_process_buff + 1 ;
    LD     move_reply_process_buff + 2.B,B_REG_LO.B ;
    LD     move_reply_process_buff + 3.B,A_REG_HI.B ;
    LD     move_reply_process_buff + 4.B,A_REG_LO.B ;
    JMP    SND_MOVE_REPLY_MSG ;

 .endsect
 .end