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.
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.
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:
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?
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?
@"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:
@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!
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
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.
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 .
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.
/Documents/My Projects/P2/dummy.p2asm:2645: error: Changing hub value for symbol ___struct_s_vfs_file_t_putchar /Documents/My Projects/P2/dummy.p2asm:2690: error: Changing hub value for symbol ___struct_s_vfs_file_t_putchar_ret /Documents/My Projects/P2/dummy.p2asm:2693: error: Changing hub value for symbol ___struct_s_vfs_file_t_getchar /Documents/My Projects/P2/dummy.p2asm:2728: error: Changing hub value for symbol ___struct_s_vfs_file_t_getchar_ret
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);
}
}
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.
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.
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.
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?
@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.
Comments
I believe the stq x with wrlong or rdlong is the issue here.
Mike
I have code like this:
That was working fine, but then started giving me errors like this:
Changing to this seemed to fix it:
I have code like this:
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:
Compiles when this return is commented out:
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?
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-
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 -
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- 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
@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.
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:
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 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!
https://github.com/totalspectrum/flexprop/releases/latest
It has a number of bug fixes to the compiler:
The GUI also has some changes:
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
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): 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
Oops, I take that back. Seems it works with:
enum { _clkfreq= 297000000};
/Documents/My Projects/P2/dummy.p2asm:2645: error: Changing hub value for symbol ___struct_s_vfs_file_t_putchar
/Documents/My Projects/P2/dummy.p2asm:2690: error: Changing hub value for symbol ___struct_s_vfs_file_t_putchar_ret
/Documents/My Projects/P2/dummy.p2asm:2693: error: Changing hub value for symbol ___struct_s_vfs_file_t_getchar
/Documents/My Projects/P2/dummy.p2asm:2728: error: Changing hub value for symbol ___struct_s_vfs_file_t_getchar_ret
Mike
Mike
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.
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.
Good to know.
Mike
Mike
Thank you! I remember that now!
Mike
Cheers