Menu

Assembly programming

mkstevo
2017-09-01
2017-09-03
  • mkstevo

    mkstevo - 2017-09-01

    Sorry for posting this in the GCB forum. I'm not a very good BASIC programmer, but I'm a much, much worse Assembly language programmer. I readily admit to not having a clue. Unfortunately I'd like to modify a program for which I only have the .ASM source, I presume it was written in Assembly language by someone cleverer than me.

    The idea seems to be that after a 'timeout' period, a fault is raised. An input (PORTB,5) provides indication of a Hopper fault. Once a fault has been raised the PIC enters a loop that is only cleared on power off/on.

    I want to modify this such that if the 'Hopper' fault is cleared, so is the fault condition, but if the fault was raised by the 'timeout' condition, remain in the loop forever.

    Here is a portion of the original code:

                 BTFSC     PORTB,5   ;CHECK FAULT I/P FROM HOPPER
                 GOTO      FAULT
    ;
    DRIVE        DECFSZ    COUNT,1   ;DECREMENT TIME LIMIT PERIOD.
                 GOTO      MOTOR     ;CONTINUE TO APPLY POWER.
                 DECFSZ    MULT,1    ;DECREMENT TIME LIMIT MULTIPLIER.
                 GOTO      PRESET    
                 GOTO      FAULT     ;IF MULTIPLIER REACHES ZERO THEN = FAULT.
    ;
    ; Other code here
    ;
    FAULT         BSF       PORTA,1     ;SWITCH MOTOR DRIVE OFF. = HIGH.
                  BSF       PORTA,2     ;SET ALARM O/P HIGH TO INDICATE FAULT.
                  CLRWDT
                  GOTO      FAULT       ;WAIT FOR ATTENDANT TO RESET MACHINE
    ;
    ;
    END
    

    And here is my modified code for the FAULT routine:

    FAULT         BSF       PORTA,1     ;SWITCH MOTOR DRIVE OFF. = HIGH.
                  BSF       PORTA,2     ;SET ALARM O/P HIGH TO INDICATE FAULT.
                  CLRWDT
                  MOVF      MULT,F      ;If Sent From Hopper Check Still Exists
                  BTFSC     STATUS,Z    ;MULT=0, timeout. MULT>0, Hopper Fault.
                  GOTO      FAULT       ;WAIT FOR ATTENDANT TO RESET MACHINE
                  BTFSC     PORTB,5     ;CHECK FAULT I/P FROM HOPPER
                  GOTO      FAULT       ;If Hopper Fault Present, GOTO FAULT
                  RETLW     0           ;Otherwise, Return.
    ;
    ;
    END
    

    Have I understood the flow of the program correctly in that the BTFSC PORTB,5 tests the status of PORTB5 and if set executes GOTO FAULT, otherwise executes the following line with the label DRIVE? That DECFSZ MULT,1 instruction decrements MULT by the parameter '1' and then if not set to zero executes the next instruction (GOTO PRESET) whereas if MULT is zero, skips GOTO PRESET and executes GOTO FAULT instead?

    Assuming I have understood that much, would my modifications to the FAULT routine do as I expect?
    I have attempted to test MULT to see if it is zero (which I would assume indicates a motor timeout condition has occurred) with the MOVF MULT,F and BTFSC STATUS,Z statements which if zero should loop around continuously, if this is not zero, I then re-test PORTB,5 to see if it is still set and either loop around again, or if the error has cleared, execute the RETURN.

     

    Last edit: mkstevo 2017-09-01
    • joe rocci

      joe rocci - 2017-09-01

      Unless you’re trying to implement this logic in GCB, it would seem that this question should go to one of the many PIC programming forums where hard-core ASM programmers hang out. Although a solution might kindly be suggested here, it’s of little value to the general GCB community.

      From: mkstevo
      Sent: Friday, September 01, 2017 10:34 AM
      To: [gcbasic:discussion]
      Subject: [gcbasic:discussion] Assembly programming

      Sorry for posting this in the GCB forum. I'm not a very good BASIC programmer, but I'm a much, much worse Assembly language programmer. I readily admit to not having a clue. Unfortunately I'd like to modify a program for which I only have the .ASM source, I presume it was written in Assembly language by someone cleverer than me.

      I'm trying to modify some existing code for which I only have the .ASM source.

      The idea seems to be that after a 'timeout' period, a fault is raised. A second input provides indication of a Hopper fault. Once the fault has been raised the PIC enters a loop that is only cleared on power off/on.

      I want to modify this such that if the 'Hopper' fault is cleared, so is the fault condition, but if the fault was raised by the 'timeout' condition, remain in the loop forever.

      Here is a portion of the original code:

               BTFSC     PORTB,5   ;CHECK FAULT I/P FROM HOPPER
               GOTO      FAULT
      

      ;
      DRIVE DECFSZ COUNT,1 ;DECREMENT TIME LIMIT PERIOD.
      GOTO MOTOR ;CONTINUE TO APPLY POWER.
      DECFSZ MULT,1 ;DECREMENT TIME LIMIT MULTIPLIER.
      GOTO PRESET
      GOTO FAULT ;IF MULTIPLIER REACHES ZERO THEN = FAULT.
      ;
      ; Other code here
      ;
      FAULT BSF PORTA,1 ;SWITCH MOTOR DRIVE OFF. = HIGH.
      BSF PORTA,2 ;SET ALARM O/P HIGH TO INDICATE FAULT.
      CLRWDT
      GOTO FAULT ;WAIT FOR ATTENDANT TO RESET MACHINE
      ;
      ;
      END
      And here is my modified code for the FAULT routine:

      FAULT BSF PORTA,1 ;SWITCH MOTOR DRIVE OFF. = HIGH.
      BSF PORTA,2 ;SET ALARM O/P HIGH TO INDICATE FAULT.
      CLRWDT
      MOVF MULT,F ;If Sent From Hopper Check Still Exists
      BTFSC STATUS,Z ;MULT=0, timeout. MULT>0, Hopper Fault.
      GOTO FAULT ;WAIT FOR ATTENDANT TO RESET MACHINE
      BTFSC PORTB,5 ;CHECK FAULT I/P FROM HOPPER
      GOTO FAULT ;If Hopper Fault Present, GOTO FAULT
      RETLW 0 ;Otherwise, Return.
      ;
      ;
      END
      Have I understood the flow of the program correctly in that the BTFSC PORTB,5 tests the status of PORTB5 and if set executes GOTO FAULT, otherwise executes the following line with the label DRIVE? That DECFSZ MULT,1 instruction decrements MULT by the parameter '1' and then if not set to zero executes the next instruction (GOTO PRESET) whereas if MULT is zero, skips GOTO PRESET and executes GOTO FAULT instead?

      Assuming I have understood that much, would my modifications to the FAULT routine do as I expect?
      I have attempted to test MULT to see if it is zero (which I would assume indicates a motor timeout condition has occurred) with the MOVF MULT,F and BTFSC STATUS,Z statements which if zero should loop around continuously, if this is not zero, I then re-test PORTB,5 to see if it is still set and either loop around again, or if the error has cleared, execute the RETURN.


      Assembly programming


      Sent from sourceforge.net because you indicated interest in https://sourceforge.net/p/gcbasic/discussion/579125/

      To unsubscribe from further messages, please visit https://sourceforge.net/auth/subscriptions/

       
  • mkstevo

    mkstevo - 2017-09-02

    You are right Joe, perhaps this isn't the place. If it isn't, I'll be only too happy to delete my request.

    I had understood that some of the really clever people here did have some knowledge of Assembly Programming as GCB does compile into .ASM and on occasions members have requested to look at these .ASM files in order to diagnose problems. However, relying on goodwill is possibly a little cheeky, for which I apologise again.

    I would have posted my request on some other forum but I don't have any prescence on any Assembly Language forums, as I don't use, or understand Assembly Language.

     
  • Chris Roper

    Chris Roper - 2017-09-02

    I may be wrong but, judging by the code snippet you provided, it looks like you are attempting to override a safety feature that requires operator confirmation that the fault is cleared before restarting the hopper.
    That fail safe code is there for a reason and probably required by the appropriate safety certification.
    I doubt anyone will be willing to help you circumvent that, even on an ASM forum.

     
  • mkstevo

    mkstevo - 2017-09-03

    No Chris, I'm not attempting to circumvent anything safety related.

    The original code is designed such that should a motor become stuck, or gift not be paid (from a hopper) an error is permanently raised until such time as the error is cleared, requiring the machine to be switched off and on.

    I have designed a replacement unit that will deliver a number of tickets as gifts, no longer requiring the hopper. My ticket dispensing unit raises an error should the required number of tickets not be paid out. However, my ticket dispenser has the facility that once it has been refilled with tickets, any remaining balance of unpaid tickets will be paid out, and the error cleared. Hence the reason I'd like to clear the machine error later if it was raised by the 'hopper'. No safety issues involved of any sort.

    I want to retain the 'motor timeout' errors as these do indeed require the machine to be restarted, I just thought it would be more elegant for the ticket error to be cleared on completion, something the original designer did not have to consider.

     
  • mkstevo

    mkstevo - 2017-09-03

    Well, in order to close this out and complete my request, I did what (perhaps) I should have done in the first place. I wrote the following code in GCB:

    #Chip 16C55, 4
    #Config WDT_ON
    
    #Define Hopper    PortB.5
    #Define Motor_Act PortA.1
    #Define Alarm     PortA.2
    
    Dim     Mult      As Byte
    Dim     Count     As Byte
    
    Dir     Hopper    In
    Dir     Motor_Stp Out
    Dir     Alarm     Out
    
    Let Count = 255
    Let Mult  = 255
    
    Drive
    
    Sub Drive
        Let Count=Count-1
        If Count = 0 Then
           Let Mult=Mult-1
           If Mult = 0 Then
              GoSub Fault
           End If
        End If
        If Hopper=1 Then
           GoSub Fault
        End If
        GoSub Preset
    End Sub
    
    Sub Preset
        Wait 1 mS
    End Sub
    
    Sub Fault
        FLT:
        Let Motor_Stp=1
        Let Alarm    =1
        CLRWDT
        If Mult=0 Then   'Fault sent from Motor Timeout
           Goto FLT      'Loop until Attendant Resets the Machine
        End If
        If Hopper=0 Then 'Hopper Fault Cleared
           Return        'Exit Fault Routine
        End If
        Goto FLT         'Loop until Attendant Resets the Machine
    End Sub
    

    I then compiled it, and looked at the generated .ASM file, I have removed the GCB source file coments and am only showing the Fault routine:

    FAULT
    FLT
        bsf     PORTA,1
        bsf     PORTA,2
        clrwdt
        movf    MULT,F
        btfsc   STATUS, Z
        goto    FLT
        btfss   PORTB,5
        retlw   0
        goto    FLT
        retlw   0
    

    This does look similar to that which I showed initially so I am more confident that my changes should work as I intended.

    I apologise once more if my request was inappropriate for this forum and should a moderator wish to delete this thread I shan't be in the least offended.

     

    Last edit: mkstevo 2017-09-03
  • stan cartwright

    stan cartwright - 2017-09-03

    "Sorry for posting this in the GCB forum. I'm not a very good BASIC programmer, but I'm a much, much worse Assembly language programmer. I readily admit to not having a clue."
    Really? :)

     
  • CDRIVE

    CDRIVE - 2017-09-03

    Ha! That was my reaction too!

    Cheers,
    Chris S.

     
  • William Roth

    William Roth - 2017-09-03

    @mkstevo

    You have now taken the path that I may have suggested. Write in GCB and insert the ASM into your existing program.

    Going further, I would probably re-write the entire program in GCB (time permitting). But you have not told us what microcontroller chip you are using, and have not posted complete code. So we are in guess mode as to the complexity of the complete progran and the difficulty of converting it all to GCB.

    Patching ASM can be tricky.

    William

     
    • mkstevo

      mkstevo - 2017-09-04

      I'd normally try to rewrite the entire program (which isn't that large) but...
      It is difficult for me to follow the flow and execution of an Assembly Program as it is and I don't want to try to decode the entire program. The main portion of the program itself provides a variable PWM drive for various motors that can be controlled through dip switches. This PWM is hard coded (as best I can tell) with routines for 'On' and 'Off' pulses which I can't really determine the timing of the PWM from. As the frequency of the PWM is rather critical I'd rather not mess about with this if I don't have to.

      My addition of an exit route for a 'soft' error is something which would be satisfying for me to have, but isn't critical. If I can add it, I'd like to, if I can't, so be it.

      I'll try to change the fault routine as I've indicated above. Should this not work as I hope I'll be miffed but not distraught.

       

      Last edit: mkstevo 2017-09-04

Log in to post a comment.