Shop OBEX P1 Docs P2 Docs Learn Events
Using FlexProp to help convert Spin2 to assembly — Parallax Forums

Using FlexProp to help convert Spin2 to assembly

Converting this OLED code to inline assembly and came to this:
PinWrite(D0_pin..D7_pin, d)

Started thinking about how to do this in assembly and not seeing an easy way to do it when D0_pin and D7_pin are arbitrary. (I should probably force the data bus to have a base pin that is multiple of 8 to make things simple.) But, was wondering if I was missing something...

Occurred to me that I can just use FlexProp to compile this line and see what it makes in the pasm file it generates...

Just made this simple .spin2 file:

CON 'Testing

PUB main()|d
    d:=8
    PinWrite (7..0, d)

Compiled, and it worked. Now, I see the "__system___pinwrite" function is about as complex as I imagined. No shortcuts. Not sure how 7..0 becomes #448 or how the code works, but now I know that I definitely need to restrict pins to basepin, multiple of 8, this is just too much...

' PUB main()|d
_main
'   d:=8
'   PinWrite (7..0, d)
    mov arg01, #448
    mov arg02, #8
    call    #__system___pinwrite
_main_ret
    ret
hubexit
    jmp #cogexit

__system___pinwrite
    mov _var01, arg01
    and _var01, #31
    test    arg01, #32 wz
    shr arg01, #6
    bmask   arg01, arg01
    shl arg01, _var01
    shl arg02, _var01
 if_e   jmp #LR__0001
    or  dirb, arg01
    mov _var01, outb
    andn    _var01, arg01
    and arg02, arg01
    or  _var01, arg02
    mov outb, _var01
    jmp #LR__0002
LR__0001
    or  dira, arg01
    mov _var01, outa
    andn    _var01, arg01
    and arg02, arg01
    or  _var01, arg02
    mov outa, _var01
LR__0002
__system___pinwrite_ret
    ret

Comments

  • RaymanRayman Posts: 14,640

    Realized I can't move data bus to multiple of 8 very easily in my setup...
    https://forums.parallax.com/discussion/175283

    But, this does the trick:

        testb  d,#7 wc
        drvc  #D7_pin
        testb  d,#6 wc
        drvc  #D6_pin
        testb  d,#5 wc
        drvc  #D5_pin
        testb  d,#4 wc
        drvc  #D4_pin
        testb  d,#3 wc
        drvc  #D3_pin
        testb  d,#2 wc
        drvc  #D2_pin
        testb  d,#1 wc
        drvc  #D1_pin
        testb  d,#0 wc
        drvc  #D0_pin
    
  • JonnyMacJonnyMac Posts: 9,102
    edited 2023-04-15 18:46

    When I want to translate Spin2 straight PASM2 I look in the PNut compiler which Chip includes in the download. In some cases he uses skip sequences, but comments in the code make those easy to sort out when instructions are tightly wound. For pinwrite(), it has its own routine which is setup to work with outa or outb registers (I think I tested and it does not work across the p31/p32 boundary).

    pinw_           ror     y,#6    wc      'y=pins, w=val (begins at pop2 in LUT)
                    bitc    pinw_reg,#9     'select outa/outb for writing
    
                    bmask   v,y             'make mask
                    rol     y,#6
    
                    rol     v,y             'justify mask
                    rol     w,y             'justify val
    
                    setq    v               'mux val into outa/outb using mask
    pinw_reg        muxq    outa,w
    
            _ret_   dirh    y               'enable outputs
    

    Of course, if you're writing to a fixed set of outputs, you can simplify, I did a quick test using P59..56 on the Eval board.

    pub write4(value) | m
    
      org
                            mov       m, #%1111                     ' 4-bit mask
                            shl       m, #(56-32)                   ' align with lsb
                            andn      outb, m                       ' clear old outputs
                            and       value, #%1111                 ' truncate to 4 bits
                            shl       value, #(56-32)               ' align with lsb
                            or        outb, value                   ' output new bits
                            or        dirb, value 
      end
    

    Not sure how 7..0 becomes #448

    The P2 deals with pin groups, so 7..0 is the same as 0 addpins 7 which is 0 + (7 << 6) which is 448.

  • While a tad longer, the advantage of your testb/drvc code is that it works across the P31/P32 boundary.

Sign In or Register to comment.