        LDA     MOT_PW+1        GET MOTOR WORKING PULSE WIDTH
        BEQ     DR4             DONT MESS WITH JOB IF LOCKED OUT

        CMPA    T2HOC           COMPARE TO WHEEL TIMER MSB
        BHI     DR5             IF MSB LOWER THAN PW, MOTOR OFF

DR4     LDA     0,X             GET NEXT STATUS
        BLE     DRAW            CONTINUE IF $FF OR $00
        RTS

DR5     LDD     #$0EFF          FOLLOWING TURNS MOTOR OFF
        JSR     PSG+2           WITH OUT WRECKING X
        LDB     REQ6            GET CURRENT SETTING
        ANDB    #.NOT.PLUG      SELECT INPUT
        LDA     #ENABLE         ADDRESS OF ENABLE BITS
        JSR     OUTPUT          WRITE TO PSG
        CLR     MOT_PW+1        LOCK-OUT DR5 ONCE
        BRA     DR4             CHECK NEXT VECTOR STATUS FOR END
 **************
**
** CKMOTOR
**
** CHECK THE MOTOR TIMER AND SEE IF TIME TO FINIS
**
**************

CKMOTOR

        LDA     MOT_PW+1
        BNE     CKMOT2
        RTS
CKMOT2
        CMPA    T2HOC
        BHI     CKMOT4
        RTS
CKMOT4
        LDD     #$0EFF
        JSR     PSG+2
        LDB     REQ6            GET CURRENT SETTING
        ANDB    #.NOT.PLUG      SELECT INPUT
        LDA     #ENABLE         ADDRESS OF ENABLE BITS
        JSR     OUTPUT          WRITE TO PSG
        CLR     MOT_PW+1
        RTS
 ***********************
** MOTOR
***********************
*                               (C) JOHN ROSS 1983
MOTOR   CLR     SR              BEAM OFF
        LDA     IFR             GET INTERRUPT FLAGS FROM PIA
        BITA    #$20            CHECK T2 TIME-OUT FLAG
        BNE     MOT_2           TIMER OVER SO MOTOR IS SLOW
        LDA     MOT_PW+2        MOTOR IS FAST SO  MINIMUM POWER
        STA     MOT_PW+1        IS USED IN THE NEXT ROTATION
        DEC     SMPLCN          ONE 'MOTOR OFF' ROTATION
        BGT     MOT_66          CHECK FRAME TIME ALLOWANCE
        BRA     MOT_3           IF SMPLCN=0=DONE, CHECK STATISTICS

MOT_2   LDA     MOT_PW          POWER PULSE WIDTH IN RELATION TO A
*                               DECREMENTING T2 TIMER
        STA     MOT_PW+1        PULSE WIDTH  FOR NEXT ROTATION
        INC     ONROTS          ONE 'MOTOR ON' ROTATION
        DEC     SMPLCN          ONE ROTATION.
MOT_66  BGT     MOT_65          CHECK FRAME TIME ALLOWANCE
MOT_3   LDB     #$08            1/4 STATISTIC SAMPLE TOTAL COUNT
        STB     SMPLCN          RESET SAMPLE COUNTER
        LDB     ONROTS          NUMBER OF ON ROTATIONS JUST NOW
        ADDB    ONROTS+1        ON ROTATIONS FROM LAST 1/2 SAMPLE
        TFR     B,A             SETUP TO CHANGE ON PWR BY ROT ERROR
        SUBA    #$0D            OPTIMUM NO. OF ONROTS SET HERE----.
        NEGA                    A HAS -ONROTS ERROR FROM OPTIMUM  |
        CMPB    #$0D            OPTIMUM NO. OF ONROT3 SET HERE TOO|
        BEQ     MOT_6           NO ADJUSTMENT TO ON PW
        BPL     MOT_53          GROW ON PW IF TOO MANY ON ROTATIONS
        ADDA    MOT_PW          SHRINK ON PW IF TOO FEW ONROTS
        BCS     MOT_6           UNTILL IT WOULD ROLL OVER
        STA     MOT_PW          SAVE IF NOT ROLLED OVER
        BRA     MOT_6           THEN ADJUST OFF POWER PULSE WIDTH

MOT_53  ADDA    MOT_PW          GROW ON POWER PW IF TOO MUCH ONROT
        BCC     MOT_6           UNTILL IT WOULD ROLL OVER
        STA     MOT_PW          SAVE IF NOT ROLLED OVER
MOT_6   ADDB    ONROTS+2        ADD T-2 ONROTS TO T-1 AND T-0
        ADDB    ONROTS+3        ADD T-3 ONROTS TO T-0, 1, AND 2
        SUBB    #$18            SET OPTMM NO_ OF ONROTS IN $20 HERE
        BEQ     MOT_64          PROPAGATE ONROTS IF OPTIMUM
        TFR     B,A             A HAS ERROR MSB
        CLRB                    SETUP B FOR DIVIDE SHIFTING. A MSB,
        NEGA                    WHICH IS USED IN NEGATIVE FEEDBACK
        ASRA                    AT A RATIO OF 1/2 (OR 1/4 OK TOO)
        RORB                    DOUBLE PRECISION FOR NOW, MAKE LSB.
        TSTA                    RECOVER SIGN OF ERROR
        BMI     MOT_62          GROW OFF ROT PWR IF TOO MANY ONROTS
        ADDD    MOT_PW+2        SHRINK OFF PWR IF TOO FEW ONROTS
        BCS     MOT_64          UNTILL IT ROLLS OVER
        STD     MOT_PW+2        SAVE NEW SMALLER IF NOT ROLLED OVER
        BRA     MOT_64          PROPAGATE ONROTS COUNTERS

MOT_62  ADDD    MOT_PW+2        GROW OFF ROT PWR IF TOO FEW OFFROTS
        BCC     MOT_64          UNTILL IT ROLLS OVER,THEN PROPAGATE
        STD     MOT_PW+2        SAVE NEW LARGER IF NOT ROLLED OVER
MOT_64  LDA     MOT_PW+2        GET OFF ROTATION POWER
        SUBA    #$1A            SET ON/OFF POWER DISTANCE HERE
        SUBA    MOT_PW          DISTANCE FROM ROTATION POWER
        BHI     MOT_61          OFF PWR OK IF >THAT
        LDA     MOT_PW          GET ON PWR
        ADDA    #$1A            OFFSET BY ON/OFF DISTANCE
        STA     MOT_PW+2        SAVE AS NEW OFF POWER
MOT_61  LDD     ONROTS+1            GET T-1, T-2
        STD     ONROTS+2             SAVE AS T-2, T-3
        LDA     ONROTS          GET T-0
        STA     ONROTS+1        SAVE AS T-1
        CLR     ONROTS          CLR T-0 FOR NEXT ON ROTATION COUNT
MOT_65  NOP                     XMSEC (WHEEL ROT TIME) NOT ADJUSTED
*                               IN THIS VERSION---
MOT_9   LDD     #$0EFF          FOLLOWING TURNS THE MOTOR OFF
        JSR     PSGX            BUT MAKES THE PORT IN OUTPUT MODE
        LDB     REQ6            FIND OUT CURRENT SETTING
        ORB     #PLUG           SELECT OUTPUT
        LDA     #ENABLE         ADDRESS FOR ENABLES
        JSR     OUTPUT          SEND IT OUT TO PSG
        JSR     ZEROIT          ZERO THE BEAM POSITION
        LDS     #STACK          CLEAN-UP THE STACK
        JMP     SCENE
