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

12345679»

Comments

  • I didn’t think the push/pop instructions or opcode changed between rev a and b???
  • Dave HeinDave Hein Posts: 6,204
    edited 2020-11-15 - 21:13:59
    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
  • 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: 11,485
    edited 2020-11-17 - 21:26:40
    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: 11,485
    edited 2020-11-17 - 21:56:57
    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
  • 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).
  • 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!


Sign In or Register to comment.