Shop OBEX P1 Docs P2 Docs Learn Events
FlexProp: a complete programming system for P2 (and P1) - Page 9 — Parallax Forums

FlexProp: a complete programming system for P2 (and P1)

1679111254

Comments

  • Cluso99Cluso99 Posts: 18,066
    I didn’t think the push/pop instructions or opcode changed between rev a and b???
  • Dave HeinDave Hein Posts: 6,347
    edited 2020-11-15 21:13
    PUSH/POP use PTRA or PTRB. The pointer encoding changed. However, it is possible to encode the pointer field so that it works for both Rev A and B as long as the index is between -16 and 15.
  • In C they push the registers onto the stack and pop them off when the function call is done.
    00514 045             | pushregs_
    00514 045 2B EC 63 FD |     pop  pa
    00518 046 2B 86 60 FD |     pop  RETADDR_
    0051c 047 04 84 94 FB |     tjz  COUNT_, #pushregs_done_
    00520 048 01 84 84 F1 |     sub  COUNT_, #1
    00524 049 28 84 60 FD |     setq COUNT_
    00528 04a 00 F1 64 FC |     wrlong local01, ptra
    0052c 04b 01 84 04 F1 |     add  COUNT_, #1
    00530 04c             | pushregs_done_
    00530 04c 02 84 64 F0 |     shl  COUNT_, #2
    00534 04d 42 F0 03 F1 |     add  ptra, COUNT_
    00538 04e 02 84 44 F0 |     shr  COUNT_, #2
    0053c 04f 28 04 64 FD |     setq #2 ' push 3 registers starting at COUNT_
    00540 050 61 85 64 FC |     wrlong COUNT_, ptra++
    00544 051 F8 89 00 F6 |     mov    fp, ptra
    00548 052 2C EC 63 FD |     jmp  pa
    0054c 053             |  popregs_
    0054c 053 2B EC 63 FD |     pop    pa
    00550 054 0C F0 87 F1 |     sub    ptra, #12
    00554 055 28 04 64 FD |     setq   #2
    00558 056 00 85 04 FB |     rdlong COUNT_, ptra
    0055c 057 06 84 94 FB |     tjz    COUNT_, #popregs__ret
    00560 058 02 84 64 F0 |     shl    COUNT_, #2
    00564 059 42 F0 83 F1 |     sub    ptra, COUNT_
    00568 05a 02 84 44 F0 |     shr    COUNT_, #2
    0056c 05b 01 84 84 F1 |     sub    COUNT_, #1
    00570 05c 28 84 60 FD |     setq   COUNT_
    00574 05d 00 F1 04 FB |     rdlong local01, ptra
    00578 05e             | popregs__ret
    00578 05e 2A 86 60 FD |     push   RETADDR_
    0057c 05f 2C EC 63 FD |     jmp    pa
    

    I believe the stq x with wrlong or rdlong is the issue here.

    Mike
  • Cluso99Cluso99 Posts: 18,066
    Dave Hein wrote: »
    PUSH/POP use PTRA or PTRB. The pointer encoding changed. However, it is possible to encode the pointer field so that it works for both Rev A and B as long as the index is between -16 and 15.
    Aha. I didn't think push/pop changed, but of course these are simulated in C and yes, the PTRx modifiers were changed/fixed/improved.
  • RaymanRayman Posts: 13,797
    edited 2020-11-17 21:26
    I seem to have an issue with bool type and want to check...

    I have code like this:
        bool bMouseMoved = false;
    ...
            if (bMouseMoved)
            {
    ...
    

    That was working fine, but then started giving me errors like this:
    1>2BT_Demo.p2asm:2663: error: syntax error, unexpected ??
    

    Changing to this seemed to fix it:
    I have code like this:
        bool bMouseMoved = false;
    ...
            if (bMouseMoved==true)
            {
    ...
    

    Is the first type of usage supposed to work? Maybe that depends on exactly what kind of C you are using?
    I use this all the time in C++, but maybe one shouldn't in C?

    Actually, I think that pasm line suggests something else is the problem:
     if_??	cmp	_WaitMouseDown_bMouseMoved_0099, #0 wz
    
  • RaymanRayman Posts: 13,797
    edited 2020-11-17 21:56
    Seems like it is something to do with using a return inside a conditional structure messes it up...
    Compiles when this return is commented out:
        while (true)
        {
            CheckMouse();
            if (bLeftButtonDown)
            {
                printf("Left button Down!\n");
                //return;
            }
            if (bMouseMoved)
            {
    

    Putting any function call between the two if's fixes it. Changing return to break doesn't work. Changing the second "if" to "else if" also doesn't work...
    Removing the braces in the first if and just having "return" works...

    Update: I had a bug in my code where "bMouseMoved" was declared as both a local and a global variable. Making it just global also fixes this issue. So, maybe not a real issue?
  • Hi

    Just started using flexbasic on prop2.
    Lots of fun.
    I'm used to coding in propbasic and looking at the assembly code after to see if I could improve it for my particular use.
    There is no spi function natively on flexbasic as there is in propbasic so I coded something simple as follows-
    sub spiout(dval as ulong,bits as ubyte)
    	dim tmp1 as ulong
    	dim tmp2 as ubyte
    	tmp1=1<<(bits-1)	'bit mask msbit first
    	for tmp2=1 to bits	'output data bits
    '	do
    		if (dval and tmp1) = 0 then
    	  	output(dt) = 0
    		else
    			output(dt)=1
    		endif
    		tmp1=tmp1>>1		'put it here to allow a bit of data setup time
    		output(ck)=1		'strobe data in
    		output(ck)=0
    '	loop until tmp1=0	
    	next
    
    end sub		
    

    The first time I tried this I used the for/next loop and thought this code runs not much faster than the P1 in propbasic! in cog code- but much faster than lmm.

    so I looked at the pasm listing -
    ' sub spiout(dval as ulong,bits as ubyte)
    _spiout
     	mov	_var01, arg02
     	zerox	_var01, #7
     	sub	_var01, #1
     	decod	_var02, _var01
     ' 	tmp1=1<<(bits-1)	'bit mask msbit first
     ' 	for tmp2=1 to bits	'output data bits
     	mov	_var03, #1
     	zerox	arg02, #7
     	add	arg02, #1
    LR__0003
     	mov	_var04, _var03
     	zerox	_var04, #7
     	mov	_var01, arg02
     	zerox	_var01, #7
     	cmp	_var04, _var01 wcz
    if_ae	jmp	#LR__0004
     ' 		if (dval and tmp1) = 0 then
     	test	arg01, _var02 wz
    if_e	bitl	outa, #19
    if_ne	bith	outa, #19
     	shr	_var02, #1
     	bith	outa, #20
     	bitl	outa, #20
     	add	_var03, #1
     	jmp	#LR__0003
    LR__0004
     _spiout_ret
     	ret
    
    I struggled to comprehend much of this... anyway I then thought instead of using the for/next method I would try loop until - which produced the following pasm-
     ' sub spiout(dval as ulong,bits as ubyte)
     _spiout
     	zerox	arg02, #7
     	sub	arg02, #1
     	decod	_var01, arg02
     	loc	pa,	#(@LR__0004-@LR__0003)
     	call	#FCACHE_LOAD_
     ' 	tmp1=1<<(bits-1)	'bit mask msbit first
     ' '	for tmp2=1 to bits	'output data bits
     ' 	do
    LR__0003
     ' 		if (dval and tmp1) = 0 then
     	test	arg01, _var01 wz
    if_e	bitl	outa, #19
    if_ne	bith	outa, #19
     	shr	_var01, #1 wz
     	bith	outa, #20
     	bitl	outa, #20
    if_ne	jmp	#LR__0003
    LR__0004
    _spiout_ret
     	ret
    
    This runs twice as fast as the previous code using the for/next loop.
    I suppose in retrospect its obvious why.
    Anyway my question- If I used hand assembled code how could I improve it?- or rather- how would YOU code it.
    Beans propbasic would use the carry bit after shift to set the data pin but I haven't a clue what that would look like in P2 pasm.
    Your thoughts?

    Thanks
    Dave
  • RaymanRayman Posts: 13,797
    I see fcache being used in second version ... that may explain speed difference ...
  • @"Stephen Moraco" : thanks for your bug reports. I will try to address these (although debug() statements in pasm will probably just be ignored rather than doing anything)

    @iseries : as @Wuerfel_21 said,"register" is a reserved word in C. That said, it shouldn't have crashed the compiler, so thanks for the bug report.

    Not sure what is going on with the RevA board, but I think it's probably time to retire RevA support now that the final chip is here.

    @hinv: I suspect the minimum memory requirements for the compiler is probably more than 16 megabytes, but I haven't tried it. Running it natively on a P2 is probably not feasible.
  • @Rayman: There probably is a bug in the handling of bool, but I can't reproduce it based on the snippets you posted. Are you able to post a complete example?
  • @tritonium: using "ubyte" for a variable (instead of "uinteger") causes some performance problems, since it makes the compiler add code to force arithmetic results to fit in 8 bits (that's the "zerox" instruction). I would write it something like:
    const dt = 20
    const ck = 21
    
    sub spiout(dval as ulong, bits as ulong)
      dim as ulong tmp1, tmp2
      ' shift so first data bit is bit 31
      tmp2 = dval << (32 - bits)
      for tmp1 = 1 to bits
        if (tmp2 and 0x80000000) = 0 then
          pinlo(dt)
        else
          pinhi(dt)
        endif
        tmp2 = tmp2 << 1
        output(ck) = 1
        output(ck) = 0
      next tmp1
    end sub
    
    ' test
    spiout(0x5555, 16)
    

    The C bit can be used automatically for shifting off the bottom (bit 0) or top (bit 31) but not from bit 8, so to prime the loop we shift the data up to the top. The resulting assembly code looks like:
    _spiout
            mov     COUNT_, #2
            call    #pushregs_
            mov     local01, #32
            sub     local01, arg02
            shl     arg01, local01
            mov     local02, #1
            add     arg02, #1
            loc     pa,     #(@LR__0002-@LR__0001)
            call    #FCACHE_LOAD_
    LR__0001
            cmp     local02, arg02 wcz
     if_ae  jmp     #LR__0003
            shl     arg01, #1 wc
            drvc    #20
            bith    outa, #21
            bitl    outa, #21
            add     local02, #1
            jmp     #LR__0001
    LR__0002
    LR__0003
            mov     ptra, fp
            call    #popregs_
    _spiout_ret
            ret
    
    

    It could be made even better if you can make the number of bits a constant (e.g. an spiout8 that always outputs 8 bits).
  • RaymanRayman Posts: 13,797
    ersmith wrote: »
    @Rayman: There probably is a bug in the handling of bool, but I can't reproduce it based on the snippets you posted. Are you able to post a complete example?

    @ersmith Glad you're back!

    I was able to break this again by creating that local version of a global variable.
    It's WaitMouseDown() in 2BT_Demo1.c where the problem is...

    Fortunately, this issue actually helped me fix bad code, so maybe not so bad!


  • FlexProp 5.0.1 has been released on my github page:

    https://github.com/totalspectrum/flexprop/releases/latest

    It has a number of bug fixes to the compiler:
    Version 5.0.1
    - Added getms() and getus() for BASIC
    - Allow ptra++ in BASIC assembly
    - Allow use of constants from other objects in inline assembly
    - Allow access to array member variables in Spin
    - Convert "ret" in inline assembly to a jump to the end of it
    - Fixed a C parser crash
    - Fixed a problem with padding C structs
    - Fixed a bug parsing strings in C __pasm
    - Provided separate namespace for labels in C
    - Removed support for Rev A silicon (it was not working anyway)
    

    The GUI also has some changes:
    Version 5.0.1
    - Disabled P2a buttons
    - Enabled ANSI console mode for P1 loader in Windows
    - On Linux and Mac, use $HOME for config file location
    
  • I’m really liking the newest version. Native ATAN, ATAN2, ACos, ASIN in BASIC is making my math libs obsolete!
  • AribaAriba Posts: 2,682
    Eric

    Is there a way to use RTS instead of DTR for the P2 Reset in LoadP2?
    I see a C functions for that in the source of LoadP2/osint_xxx, but I don't find a commandline switch in the documentation which calls this function.

    Andy
  • Ariba wrote: »
    Is there a way to use RTS instead of DTR for the P2 Reset in LoadP2?
    I see a C functions for that in the source of LoadP2/osint_xxx, but I don't find a commandline switch in the documentation which calls this function.

    I don't think there's an option for that. I didn't write that code, so I don't know if it even works or not. But I'm always open to patches :).
  • AribaAriba Posts: 2,682
    ersmith wrote: »
    Ariba wrote: »
    Is there a way to use RTS instead of DTR for the P2 Reset in LoadP2?
    I see a C functions for that in the source of LoadP2/osint_xxx, but I don't find a commandline switch in the documentation which calls this function.

    I don't think there's an option for that. I didn't write that code, so I don't know if it even works or not. But I'm always open to patches :).

    Unfortunately I am not equipped to compile C or C++ programs on the PC.

    But here are the small changes I would make in the OS specific files (untested):
    osint_cygwin.c:
    osint_mingw.c:
    
    void hwreset(void)
    {
        EscapeCommFunction(hSerial, SETDTR);
        EscapeCommFunction(hSerial, SETRTS);
        Sleep(2);
        EscapeCommFunction(hSerial, CLRDTR);
        EscapeCommFunction(hSerial, CLRRTS);
        Sleep(2);
        // Purge here after reset helps to get rid of buffered data.
        PurgeComm(hSerial, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
    }
    
    
    
    osint_linux.c:
    
    void hwreset(void)
    {
        int dtr = TIOCM_DTR;
        int rts = TIOCM_RTS;
        ioctl(hSerial, TIOCMBIS, &dtr); /* assert bit */
        ioctl(hSerial, TIOCMBIS, &rts); /* assert bit */
        msleep(2);
        ioctl(hSerial, TIOCMBIC, &dtr); /* clear bit */
        ioctl(hSerial, TIOCMBIC, &rts); /* clear bit */
        msleep(2);
        ioctl(hSerial, TIOCMBIS, &dtr); /* assert bit */
        ioctl(hSerial, TIOCMBIS, &rts); /* assert bit */
        msleep(2);
        tcflush(hSerial, TCIFLUSH);
    }
    
    This will simply use RTS and DTR at the same time. This way no command line option is required. I have also set this setting in PropTool and have never had a problem with it.

    Andy
  • RaymanRayman Posts: 13,797
    edited 2020-11-30 01:10
    297 MHz seems to still not work the regular way, just FYI...

    Oops, I take that back. Seems it works with:
    enum { _clkfreq= 297000000};
  • Turning optimization off causes the follow error:
    #include <stdio.h>
    #include <propeller.h>
    
    main()
    {
        printf("Hello\n");
    }
    

    D:/Documents/My Projects/P2/dummy.p2asm:2645: error: Changing hub value for symbol ___struct_s_vfs_file_t_putchar
    D:/Documents/My Projects/P2/dummy.p2asm:2690: error: Changing hub value for symbol ___struct_s_vfs_file_t_putchar_ret
    D:/Documents/My Projects/P2/dummy.p2asm:2693: error: Changing hub value for symbol ___struct_s_vfs_file_t_getchar
    D:/Documents/My Projects/P2/dummy.p2asm:2728: error: Changing hub value for symbol ___struct_s_vfs_file_t_getchar_ret

    Mike
  • Thanks for the bug report, Mike. For now you can work around it by compiling with "-O0,remove-unused".
  • Does anyone have an example using FlexBasic to ouput to VGA?
  • This code does not compile except if I remove the one line why?
    #include <stdio.h>
    #include <propeller.h>
    
    #define _rxpin 63
    #define _txpin 62
    #define _txmode 0x7c
    #define _rxmode 0x3e
    
    
    char Buffer[50] = "Hello World\n";
    int Save[256];
    
    int main()
    {
    	int  *a;
    	int  b;
    	int  c;
    	int  d;
    	int  e;
    	int *z;
    	
    	memset(Save, 0, sizeof(Save));
    	    
       _pinl(57);
       _waitms(5000);
       _pinh(57);
    
    	z = Save;
    	a = (int*)Buffer;
    	b = (int)a + 4;
    	c = b + 4;
    	d = c + 4;
    	e = b + 100;
    	
    	__asm {
    	nop
    	nop
    	mov ptra, z
    	setq #8
    	wrlong a, ptra
    	};
    
    	printf("b %x\n", &b); <--- remove this line.
    	
    	printf("a %d, b %d, c %d, d %d, e %d\n", a, b, c, d, e);
    	printf("0 %d, 1 %d, 2 %d, 3 %d, 4 %d\n", Save[0], Save[1], Save[2], Save[3], Save[4]);
    
    	
    	while (1)
    	{
    	    _pinl(56);
    	    _waitms(500);
    	    _pinh(56);
    	    _waitms(500);
    	}
    }
    

    Mike
  • DaveJenson wrote: »
    Does anyone have an example using FlexBasic to ouput to VGA?

    In the FlexProp file samples\Multi-Language\turtle_demo.bas is a simple graphics example in BASIC that uses @rogloh 's Spin2 VGA driver to output video.
  • iseries wrote: »
    This code does not compile except if I remove the one line why?

    OK, that's a bit of a subtle one. The expression "&b" takes the address of local variable "b", which means it must be placed on the stack (not kept in a register). In the current version of flexprop, if any local variable is on the stack then they all have to be. That means that some of the variables like "a" and "z" that you're referring to in the inline assembly are not registers, and hence cannot be accessed directly by PASM instructions.

    Generally the best way to avoid this is to put the inline assembly into its own function that doesn't have any & references to variables.
  • I guess what I'm trying to do is copy all the registers into a save place but it only copies the first 3 registers. So I was trying to get the address of these variables to see if they are indeed registers and not stack values but I guess I can't get the address of register variables.

    Good to know.

    Mike
  • Oops, found it. I guess I should put ptra back to the value it was since the reset of the code is kind of using that register.

    Mike
  • ersmith wrote: »
    DaveJenson wrote: »
    Does anyone have an example using FlexBasic to ouput to VGA?

    In the FlexProp file samples\Multi-Language\turtle_demo.bas is a simple graphics example in BASIC that uses @rogloh 's Spin2 VGA driver to output video.

    Thank you! I remember that now!
  • This assembly code generates an error "operand effect on wrong register"
    #include <stdio.h>
    #include <propeller.h>
    
    int Save[256];
    
    void main()
    {
        int i, j;
        int z;
        
        z = (int)Save;
        
        __asm {
        mov j, ptra
        mov ptra, z
        wrlong i, ptra++
        wrlong j, ptra++
        mov ptra, j
    	}
    
        _pinl(56);
        _waitms(5000);
        _pinl(57);
        
        __asm {
        mov i, ptra
    	}
    
    	printf("ptra: %X %X\n", i, j);
        printf("Hello World!\n");
        
        while (1)
        	_waitms(500);
    }
    

    Mike
  • Not too experienced with C, but wasn't there a propeller2.h header specifically? Does that have hardware specific definitions in it that could cause that kind of error if the wrong one was included?

    Cheers
  • @iseries: You've found a bug in the optimizer, it was trying to replace "ptra" with a different register. Thanks for finding this, I'll get a fix in soon. In the meantime you can change the "__asm" to "__asm const" to prevent the optimizer from trying to work with the inline assembly.
Sign In or Register to comment.