All the Zog interpreter variables have been overlaid against the init code thus saving 20-30 LONGs in Cog. There are now 42 LONGs free when built for using external memory.
Put back the fibo test source code that went missing in 1.2.
If this voting thing works as well as I would hope, which depends on us I guess, it would be great to be able to do a search for all the highest rated threads.
Then all those "classic" threads like Bill Henning's introduction of LMM or BradC's and Mica Dowty's USB threads or many others would be easy to get to. It would be a great way for people new to the Prop to find all kinds of interesting things you can do with a Propeller before you even know what you are looking for.
I was just now wondering why the fibo source had dropped off the Zog tree and was busy putting it back. The attached source generates the same binary.
Thanks for that.
I expect a long day of debugging today. I started using the hello.c program last night for debugging. It gets right up to launching main and stops. I have tools to figure out what's happening with the PASM, but some of the zpu instructions are a mystery to me right now Too bad I have to learn them to make more progress.
The following trace shows the instruction address fetch for executing hello.bin - the last column "D" result has the address.
Starting SD driver...0000FFFF
Mounting SD...00000000Opening ZPU image...00000000Reading image...Done
0000: 0B 0B 0B 0B 82700B 0B 80 FB DC 0C 3A 0B 0B 800010: EC FA 04000000000000000000000000000020: 0B 0B 0B 899004000000000000000000000030: 000000000000000000000000000000000040: 71 FD 06087283060981058205832B 2A 830050: FF FF 06520400000000000000000000000060: 71 FD 060883 FF FF 7383060981058205830070: 2B 2B 09067383 FF FF 0B 0B 0B 0B 83 A704000080: 720981057205737309060906730973060090: 070A 810653510400000000000000000000A0: 72722473732E 0753510400000000000000B0: 0000000000000000000000000000000000C0: 717371097106810630720A 100A 720A 1000D0: 0A 31050A 81065151535104000000000000E0: 72722673732E 0753510400000000000000F0: 00000000000000000000000000000000Starting BMA Debugger ...
BMA Debugger Started.
T0.PC 008 Ok> i 176Step-watch Instruction @ 176T0.PC 176 . : mov A0BFCBCC D:1E500000000 S:1CC 00000000 D=1E500000000T0.PC 176 . : mov A0BFCBCC D:1E500000003 S:1CC 00000001 D=1E500000001 Z
T0.PC 176 . : mov A0BFCBCC D:1E500000002 S:1CC 00000002 D=1E500000002 Z
T0.PC 176 . : mov A0BFCBCC D:1E500000001 S:1CC 00000003 D=1E500000003 Z
T0.PC 176 . : mov A0BFCBCC D:1E500000000 S:1CC 00000004 D=1E500000004 Z
T0.PC 176 . : mov A0BFCBCC D:1E50000FFFA S:1CC 00000005 D=1E500000005 Z
T0.PC 176 . : mov A0BFCBCC D:1E50000FFF4 S:1CC 00000006 D=1E500000006 Z C
T0.PC 176 . : mov A0BFCBCC D:1E500000007 S:1CC 00000007 D=1E500000007 Z C
T0.PC 176 . : mov A0BFCBCC D:1E500000004 S:1CC 00000008 D=1E500000008 Z C
T0.PC 176 . : mov A0BFCBCC D:1E50000FFF2 S:1CC 00000009 D=1E500000009 Z C
T0.PC 176 . : mov A0BFCBCC D:1E50000000B S:1CC 0000000A D=1E50000000A C
T0.PC 176 . : mov A0BFCBCC D:1E500000009 S:1CC 0000000B D=1E50000000B C
T0.PC 176 . : mov A0BFCBCC D:1E50000FFF7 S:1CC 0000000C D=1E50000000C Z C
T0.PC 176 . : mov A0BFCBCC D:1E50000FFFB S:1CC 0000000D D=1E50000000D Z C
T0.PC 176 . : mov A0BFCBCC D:1E50000000F S:1CC 0000000E D=1E50000000E Z C
T0.PC 176 . : mov A0BFCBCC D:1E50000000D S:1CC 0000000F D=1E50000000F Z C
T0.PC 176 . : mov A0BFCBCC D:1E50000FFFA S:1CC 00000010 D=1E500000010 Z C
T0.PC 176 . : mov A0BFCBCC D:1E500000013 S:1CC 00000011 D=1E500000011 C
T0.PC 176 . : mov A0BFCBCC D:1E500000012 S:1CC 00000012 D=1E500000012 C
T0.PC 176 . : mov A0BFCBCC D:1E50000FFFB S:1CC 0000367A D=1E50000367A Z C
T0.PC 176 . : mov A0BFCBCC D:1E50000FFFA S:1CC 0000367B D=1E50000367B Z C
T0.PC 176 . : mov A0BFCBCC D:1E50000367B S:1CC 0000367C D=1E50000367C Z C
T0.PC 176 . : mov A0BFCBCC D:1E50000FFF7 S:1CC 0000367D D=1E50000367D Z C
T0.PC 176 . : mov A0BFCBCC D:1E50000FFF6 S:1CC 0000367E D=1E50000367E Z C
T0.PC 176 . : mov A0BFCBCC D:1E50000367F S:1CC 0000367F D=1E50000367F Z C
T0.PC 176 . : mov A0BFCBCC D:1E50000FFF2 S:1CC 00003680 D=1E500003680 Z C
T0.PC 176 . : mov A0BFCBCC D:1E500003683 S:1CC 00003681 D=1E500003681 C
T0.PC 176 . : mov A0BFCBCC D:1E500003682 S:1CC 00003682 D=1E500003682 C
T0.PC 176 . : mov A0BFCBCC D:1E500003DDF S:1CC 00003683 D=1E500003683 Z C
T0.PC 176 . : mov A0BFCBCC D:1E50000FFF0 S:1CC 00003684 D=1E500003684 Z C
T0.PC 176 . : mov A0BFCBCC D:1E50000FFF7 S:1CC 00003685 D=1E500003685 Z C
T0.PC 176 . : mov A0BFCBCC D:1E50000FFFC S:1CC 00003686 D=1E500003686 Z C
T0.PC 176 . : mov A0BFCBCC D:1E50000FFF2 S:1CC 00003687 D=1E500003687 Z C
T0.PC 176 . : mov A0BFCBCC D:1E50000FFF3 S:1CC 00003688 D=1E500003688 Z C
T0.PC 176 . : mov A0BFCBCC D:1E50000FFF2 S:1CC 00003689 D=1E500003689 Z C
T0.PC 176 . : mov A0BFCBCC D:1E50000FFF4 S:1CC 00003689 D=1E500003689 Z C
T0.PC 176 . : mov A0BFCBCC D:1E50000FFFC S:1CC 0000368A D=1E50000368A Z C
T0.PC 176 . : mov A0BFCBCC D:1E50000FFFE S:1CC 0000368B D=1E50000368B C
T0.PC 176 . : mov A0BFCBCC D:1E50000FFFA S:1CC 0000368C D=1E50000368C Z C
T0.PC 176 . : mov A0BFCBCC D:1E50000368F S:1CC 0000368D D=1E50000368D C
T0.PC 176 . : mov A0BFCBCC D:1E50000368E S:1CC 0000368E D=1E50000368E C
T0.PC 176 . : mov A0BFCBCC D:1E50000FFFF S:1CC 0000368F D=1E50000368F Z C
T0.PC 176 . : mov A0BFCBCC D:1E50000FFFE S:1CC 00003690 D=1E500003690 Z C
T0.PC 176 . : mov A0BFCBCC D:1E500003693 S:1CC 00003691 D=1E500003691 C
T0.PC 176 . : mov A0BFCBCC D:1E500003692 S:1CC 00003692 D=1E500003692 C
T0.PC 176 . : mov A0BFCBCC D:1E500003691 S:1CC 000044E7 D=1E5000044E7 Z C
T0.PC 176 . : mov A0BFCBCC D:1E50000FFFA S:1CC 000044E8 D=1E5000044E8 Z C
T0.PC 1AA Ok>
I'll be getting more GadgetGangster hardware today. I'll put that and an SDRAM board in the mail to you soon.
Hello world
The meaning of life = 42HiZog say hello
0000000eargc = 00000001Address of argv[0] = 00003dbc
_hardware = 00000000_cpu_config = 00000002ZPU_ID = 0000000e
_use_syscall = 00000000Please type 4 characters...
1234You typed...
1234The following should be deadbeef
deadbeefThe following should be 0000000900000009The following should be 0001da31
FIBO using SdramCache is slower than VMCOG and Triblade,
but it crashes the same. At least the FIBO results are correct.
Is ZOG is running out of stack?
"Two wrongs don't make a right, but three rights make a left."
-Cosmo, Fairly Odd Parents
I'm not sure I have ever written a program that exits gracefully, in general they are not supposed to stop
The C run time supplied with zpu-gcc has the break point in it. Which seems quite reasonable to me in the absence of HALT. I guess as we don't have a break point debugger we can just treat it as "end of prog" and print something polite.
We have to tweak Zog to allow up to 32MB RAM. Currently addresses over 64K are mapped into HUB space.
I wasn't trying being critical of the way the program terminates. BREAKPOINT quickly took on the meaning "oops" and I didn't realize it had another context
I'll migrate to zog_v1_3 vintage at some point. I could try a file that "would likely remove" the 64KB restriction if you have one. The right thing to do is of course get hardware to you for development and as I've mentioned that's in process.
Meanwhile, I'm experimenting with different cache line sizes to check performance impact and may settle on something other than 32bytes. I should try xxtea and other programs as well.
To use up to 32MB RAM change the definition of vhub_end in zog.spin as so:
vhub_end long $01FFFFFF ' 32M - 1
That will allow access up to 32 MB of ext RAM whilst buggering up access to HUB RAM from C. But as we are not currently doing any of that who cares for now?
At least when I make that change here fibo still runs OK.
Speaking of "oops", we'll soon have uCLinux running on the Prop:)
I forgot to mention and perhaps you have spotted it already but it is necessary to change the constant zpu_memory_size in debug_zog.spin to use 32MB external RAM. This ends up getting used to set the initial value of the ZPU stack pointer.
I have used malloc from external memory, in one version of test_libzog where it put the FDX C++ object on the heap. malloc should work, after all iprintf uses it.
The only memory accesses in ZOG that get mapped to HUB RAM or I/O ports are read_long and write_long. They both check if the address is 64K and up and then branch off to do I/O or HUB access if so.
Look for:
read_long cmp address, word_mask wc'FIXME this only allows 64K RAMif_ncjmp #in_long
and similar for write_long.
That cmp will need to be changed to test against 32M instead of 64K
Sorry, forgot about that.
Then you might want to revisit those tests against vhub_end that get us into HUB RAM or just remove them.
We now have mostly functional 32MB Propeller programs
Changing those two word_mask comparisons to vhub_end did it - thanks. I assume something else depends on the resulting C state as just removing the check causes run-time failure.
Here's what I'm getting on the malloc business. No idea why 4MB+ fails. How big is an sbrk block? My malloc pointer is a char* and was getting null pointers without a cast before ... I'm getting lazy .
Malloc big buffer size:256Freebigbuffer....Malloc big buffer size:2097152Freebigbuffer.Malloc big buffer size:4194304Oops,mallocfailed.Malloc big buffer size:8388608Oops,mallocfailed.Malloc big buffer size:16777216Oops,mallocfailed.
voidmalloctest(int size){
char* mp;
printf("Malloc big buffer size: %d\r\n",size);
mp = (char*)malloc(size);
if(mp != 0) {
printf("Free big buffer.\r\n");
free(mp);
}
else {
printf("Oops, malloc failed.\r\n");
}
}
// called with:for(n = 8; n < 25; n++)
malloctest(1<<n);
I'll add some buffer test mashup code tomorrow and see what happens.
The latest uClinux distribution is > 300MB. It took over half an hour to get the package and archive manager is *still* opening it.
Guess I should post the debug_zog and zog spin files. I'll wait on posting the SDRAM drivers until later.
It makes sense, if that check is remove then you no longer get memory mapped I/O ports mapped in and iprintf etc stops working.
If you put _use_syscall = 1; at the beginning of main() then the C run time will use SYSCALL instead of memory mapped I/O ports which would no longer be needed.
"How big is an sbrk block?" - No idea I'm afraid.
Not sure why the lack of a cast would get you a NULL pointer. A compiler warning/error yes but...
I downloaded the Cygwin version of GCC ZPU toolchain and the 'include' directory seems to be empty. Where do I get the header files to go with the ZPU toolchain?
I have never tried the Cygwin version so I'm not sure I can be much help, I'll try and find time to set up a Windows box (We don't have any around here normally) and have a play.
Which "include" directory do you mean? And at what point is it missing?
I can see 21 include directories under my "toolchain"
Can you try a command like:
$ find -name include
and post the result?
I suspect the directory may be there but there is some include path not set up correctly.
I downloaded the Cygwin version of GCC ZPU toolchain and the 'include' directory seems to be empty. Where do I get the header files to go with the ZPU toolchain?
Hi David.
Yesterday I Installed Cygwin (with gcc-core developer tools), zpugcccygwin.tar.bz2, and zog on my netbook for a demo. I was able to build programs no problem. I suspect that any extra include files necessary are part of the gcc-core developer package, so you might want to install that.
I've attached a test_libzog.binary that you will need for 80MHz operation (change the name to test_libzog.bin after download). Heaters library is by default 104MHz. Other frequencies require another build - seems there should be a solution easier to customize.
Thanks for the 80mhz library. I have my program compiling and linking succcessfully. I'm wondering what library functions are available on the Propeller? Is there a header file that lists the low-level library functions like serial I/O, etc? I'd like to stay away from using stdio.h as much as possible so I want to use low level stuff to make it more likely that my program will actually fit in the 32k hub memory.
I'm also not entirely clear on how to go from a test.bin file to something that can be loaded and run on the Propeller. Is there an example of how to do this somewhere?
I don't understand it all either run_zog.spin is a bit of a mystery to me though it uses test_libzog.bin. In retrospect I'm not sure how test_libzog.bin is used exactly, but it is an output from the lib/Makefile.
I've been using debug_zog.spin as the top spin object. I build with "bstc -Ox debug_zog" for example. So for non XMM builds in debug_zog.spin I keep #define USE_HUB_MEMORY uncommented and change the file to load as defined for zpu_image which by default is fibo.bin. The image to load is built from one of the test subdirectories.
Maybe just try the debug_zog.spin route until heater can explain the rest.
Is it possible to load run_zog.spin into the Propeller Tool directly or must you use bstc? My guess is that something like bstc is necessary since the Propeller Tool doesn't understand the compile time conditionals that are in the zog spin code. Is that correct?
I guess what I'm really trying to understand is what runtime support is available to programs compiled to run under the ZOG VM? Can the programs use stdio with fopen/fclose/etc? What low-level I/O functions are available. It would be nice to have a simple list of the functions that are available in the runtime.
Fibo(20) now takes 3247ms with the 32MB SDRAM and 16KB cache. That's the best I can get without wandering into the replacement policy jungle. The cache line size is 128 bytes. I was able to squeeze in the 16K cache by recycling the driver space. The size of debug_zog.binary is now about 27K.
I experimented with a 4-way associative cache and got something working, but the performance was worse than straight direct mapped cache.
Is it possible to load run_zog.spin into the Propeller Tool directly or must you use bstc? My guess is that something like bstc is necessary since the Propeller Tool doesn't understand the compile time conditionals that are in the zog spin code. Is that correct?
The short answer is no.
The long answer is a very, very, very painful yes.
I guess what I'm really trying to understand is what runtime support is available to programs compiled to run under the ZOG VM? Can the programs use stdio with fopen/fclose/etc? What low-level I/O functions are available. It would be nice to have a simple list of the functions that are available in the runtime.
The short answer is no.
The long answer is a very, very, very painful yes.
That's what I thought. I've downloaded bstc and bstl and will use those for my ZOG work.
Are there any examples of relatively large programs ported to ZOG? I've only seen small demo programs so far. Any idea how big a program might fit into HUBmemory? The platform I'm coding for won't have a big attached SRAM.
I just downloaded Cygwin into Windows XP running in VirtualBox. Takes for ever if you install everything:) Compiling with install/bin/zpu-elf-gcc -phi hello.c just worked out of the box. You have yours working as well now so let's move on.
I'm wondering what library functions are available on the Propeller?
and
Can the programs use stdio with fopen/fclose/etc? What low-level I/O functions are available. It would be nice to have a simple list of the functions that are available in the runtime.
Good question, and one that I have not got to the bottom of yet.
Firstly IO.
Out of the box the ZPU tool chain, is set up to support some simple configurations of the ZPU processor core on an FPGA. It's only I/O is a console port which is memory mapped and a timer register. If you really want to get into this you would have to download the tool chain sources and have a look in the C run time support source.
Zog implements the console port by way of checking ZPU LOAD and STORE instructions. If the address is outside of the ZPU memory range then the access is passed along to the debug_zog COG to handle. Look for zog_mbox in the code. Currently debug_zog sees I/O commands for the console port address and uses FullDuplexSerial to do the work.
In this way things like printf work and we can get "Hello World" running.
There is an alternative I/O mechanism that uses the ZPU SYSCALL instruction. If you put "_use_syscall = 1;" in your program then then standard input and output are redirected to use SYSCALL. This mechanism seesm to be implemented in ZPU for use with the Java simulator. Zog passes all SYSCALLs out to debug_zog in much the same way as I/O operations.
The only syscalls implemented in debug_zog are SYS_read and SYS_write and they only work on the stdio file handles at the moment. Again, enough to get "Hello world" working. Perhaps the syscall mechanism will be expanded to use the SD card file system at some point.
So, given the fact that C programs under Zog have no file system yet most of the standard C library is there. Have a look in your install/zpu-elf/include/ directory to see what we have. I cannot guarantee how much of it is actually implemented though. For that we would have to look at the C libraries "newlib" and "libgloss" source.
If you want to get into floating point there is libm chock full of sin, cos, tan, etc. But warning, the resulting binaries will be huge and slow. I'm working on adding a floating point "coprocessor" cog which will improve that situation dramatically.
I'd like to stay away from using stdio.h as much as possible so I want to use low level stuff to make it more likely that my program will actually fit in the 32k hub memory.
Good plan, things like printf are rather huge (There is a smaller iprintf though and there is a print function that is small and works directly on the ZPU UART port). Have a look in hello.c for examples. You can slways read/write bytes directly to that UART prort address from your C code and build up your own mini I/O library. Taking things further one could add further IO ports to debug_zog and use them for whatever other device drivers you want.
I'm also not entirely clear on how to go from a test.bin file to something that can be loaded and run on the Propeller. Is there an example of how to do this somewhere?
debug_zog.spin is the top level object that starts up Zog and provides I/O for ZOG, in there you will see that the ZPU binary is included into the Spin using a "file" statement when running ZPU code from HUB memory. Of course one could hack that around to load the binary from an SD card file instead as is done when exeuting from external memory.
Are there any examples of relatively large programs ported to ZOG? I've only seen small demo programs so far. Any idea how big a program might fit into HUBmemory?
Not yet. At the moment in time I'm still amazed the thing works at all:) A minimal C program currently comes out at 3K bytes or so. I'm going to look into shrinking that. There is at least 1K of vector table that gets included with the run time that we don't use and should be removed.
I've been running programs with debug_zog that sit in 26K Bytes of HUB memory leaving 252 LONGs free. Just tweak the
"zpu_memory_size" constant.
General:
debug_zog as it's name suggests has grown as a tool to debug the interpreter, the external RAM, and C programs it runs. As a result it ends up providing the console I/O and even SD card support which is usefull for actual applications. It serves as an example of ZOG usage. It can of course be chopped down or extended as required for any particular application.
run_zog is something of an experiment at the moment. The aims here are:
1) Get Zog and C code running with minimal memory foot print for the Spin startup code and hence maximum HUB memory for C.
2) Optionally enable Zog to takeover the entire Propeller with no Spin code left at run time at all.
As such it has no I/O, it's just a loader. That means that any I/O, a serial port for example, has to be created in C. Enter libzog.
libzog is even more experimental and has the following ideas in mind:
1) Create C versions of things like FullDuplexSerial. That is use the PASM parts of existing objects, possibly adapted a little, and replace the Spin interfaces with C interfaces. This has been shown to be quite workable and FullDuplexSerial and VMCog have C wrappers.
2) libzog is an experiment in working with C++ under Zog. Which turns out is a good fit for makeing the equivalent of Spin objects.
3) libzog will grow to support Arduino programs.
4) Zog itself should be have a C++ wrapper so that it can be used from C++ programs. That is staring multiple interpreter instances as you do in Spin.
test_libzog is just a little test harness for the objects in libzog and is first program we have that runs with out any Spin code left in the Prop.
I think for any real application Zog will need access to Prop features like waitxx, DIRA, INA, OUT, CNT, LOCKS etc etc. I want to put as much of that as possible into the interpreter COG. Space is getting tight.
If you have a pressing need for anything let us know and I'll move it up the priority list.
Comments
fibo(24) = 046368 (19072ms)
fibo(25) = 075025 (30859ms)
fibo(26) = 121393 (08971ms)
Yep, the count rolls over.
I was just now wondering why the fibo source had dropped off the Zog tree and was busy putting it back. The attached source generates the same binary.
Did you notice this thread now has a 5 star rating? I wonder how that happened?:)
No functional changes.
All the Zog interpreter variables have been overlaid against the init code thus saving 20-30 LONGs in Cog. There are now 42 LONGs free when built for using external memory.
Put back the fibo test source code that went missing in 1.2.
I notice this thread now has two 5 star votes:)
If this voting thing works as well as I would hope, which depends on us I guess, it would be great to be able to do a search for all the highest rated threads.
Then all those "classic" threads like Bill Henning's introduction of LMM or BradC's and Mica Dowty's USB threads or many others would be easy to get to. It would be a great way for people new to the Prop to find all kinds of interesting things you can do with a Propeller before you even know what you are looking for.
I expect a long day of debugging today. I started using the hello.c program last night for debugging. It gets right up to launching main and stops. I have tools to figure out what's happening with the PASM, but some of the zpu instructions are a mystery to me right now
The following trace shows the instruction address fetch for executing hello.bin - the last column "D" result has the address.
Starting SD driver...0000FFFF Mounting SD...00000000 Opening ZPU image...00000000 Reading image...Done 0000: 0B 0B 0B 0B 82 70 0B 0B 80 FB DC 0C 3A 0B 0B 80 0010: EC FA 04 00 00 00 00 00 00 00 00 00 00 00 00 00 0020: 0B 0B 0B 89 90 04 00 00 00 00 00 00 00 00 00 00 0030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0040: 71 FD 06 08 72 83 06 09 81 05 82 05 83 2B 2A 83 0050: FF FF 06 52 04 00 00 00 00 00 00 00 00 00 00 00 0060: 71 FD 06 08 83 FF FF 73 83 06 09 81 05 82 05 83 0070: 2B 2B 09 06 73 83 FF FF 0B 0B 0B 0B 83 A7 04 00 0080: 72 09 81 05 72 05 73 73 09 06 09 06 73 09 73 06 0090: 07 0A 81 06 53 51 04 00 00 00 00 00 00 00 00 00 00A0: 72 72 24 73 73 2E 07 53 51 04 00 00 00 00 00 00 00B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00C0: 71 73 71 09 71 06 81 06 30 72 0A 10 0A 72 0A 10 00D0: 0A 31 05 0A 81 06 51 51 53 51 04 00 00 00 00 00 00E0: 72 72 26 73 73 2E 07 53 51 04 00 00 00 00 00 00 00F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Starting BMA Debugger ... BMA Debugger Started. T0.PC 008 Ok> i 176 Step-watch Instruction @ 176 T0.PC 176 . : mov A0BFCBCC D:1E5 00000000 S:1CC 00000000 D=1E5 00000000 T0.PC 176 . : mov A0BFCBCC D:1E5 00000003 S:1CC 00000001 D=1E5 00000001 Z T0.PC 176 . : mov A0BFCBCC D:1E5 00000002 S:1CC 00000002 D=1E5 00000002 Z T0.PC 176 . : mov A0BFCBCC D:1E5 00000001 S:1CC 00000003 D=1E5 00000003 Z T0.PC 176 . : mov A0BFCBCC D:1E5 00000000 S:1CC 00000004 D=1E5 00000004 Z T0.PC 176 . : mov A0BFCBCC D:1E5 0000FFFA S:1CC 00000005 D=1E5 00000005 Z T0.PC 176 . : mov A0BFCBCC D:1E5 0000FFF4 S:1CC 00000006 D=1E5 00000006 Z C T0.PC 176 . : mov A0BFCBCC D:1E5 00000007 S:1CC 00000007 D=1E5 00000007 Z C T0.PC 176 . : mov A0BFCBCC D:1E5 00000004 S:1CC 00000008 D=1E5 00000008 Z C T0.PC 176 . : mov A0BFCBCC D:1E5 0000FFF2 S:1CC 00000009 D=1E5 00000009 Z C T0.PC 176 . : mov A0BFCBCC D:1E5 0000000B S:1CC 0000000A D=1E5 0000000A C T0.PC 176 . : mov A0BFCBCC D:1E5 00000009 S:1CC 0000000B D=1E5 0000000B C T0.PC 176 . : mov A0BFCBCC D:1E5 0000FFF7 S:1CC 0000000C D=1E5 0000000C Z C T0.PC 176 . : mov A0BFCBCC D:1E5 0000FFFB S:1CC 0000000D D=1E5 0000000D Z C T0.PC 176 . : mov A0BFCBCC D:1E5 0000000F S:1CC 0000000E D=1E5 0000000E Z C T0.PC 176 . : mov A0BFCBCC D:1E5 0000000D S:1CC 0000000F D=1E5 0000000F Z C T0.PC 176 . : mov A0BFCBCC D:1E5 0000FFFA S:1CC 00000010 D=1E5 00000010 Z C T0.PC 176 . : mov A0BFCBCC D:1E5 00000013 S:1CC 00000011 D=1E5 00000011 C T0.PC 176 . : mov A0BFCBCC D:1E5 00000012 S:1CC 00000012 D=1E5 00000012 C T0.PC 176 . : mov A0BFCBCC D:1E5 0000FFFB S:1CC 0000367A D=1E5 0000367A Z C T0.PC 176 . : mov A0BFCBCC D:1E5 0000FFFA S:1CC 0000367B D=1E5 0000367B Z C T0.PC 176 . : mov A0BFCBCC D:1E5 0000367B S:1CC 0000367C D=1E5 0000367C Z C T0.PC 176 . : mov A0BFCBCC D:1E5 0000FFF7 S:1CC 0000367D D=1E5 0000367D Z C T0.PC 176 . : mov A0BFCBCC D:1E5 0000FFF6 S:1CC 0000367E D=1E5 0000367E Z C T0.PC 176 . : mov A0BFCBCC D:1E5 0000367F S:1CC 0000367F D=1E5 0000367F Z C T0.PC 176 . : mov A0BFCBCC D:1E5 0000FFF2 S:1CC 00003680 D=1E5 00003680 Z C T0.PC 176 . : mov A0BFCBCC D:1E5 00003683 S:1CC 00003681 D=1E5 00003681 C T0.PC 176 . : mov A0BFCBCC D:1E5 00003682 S:1CC 00003682 D=1E5 00003682 C T0.PC 176 . : mov A0BFCBCC D:1E5 00003DDF S:1CC 00003683 D=1E5 00003683 Z C T0.PC 176 . : mov A0BFCBCC D:1E5 0000FFF0 S:1CC 00003684 D=1E5 00003684 Z C T0.PC 176 . : mov A0BFCBCC D:1E5 0000FFF7 S:1CC 00003685 D=1E5 00003685 Z C T0.PC 176 . : mov A0BFCBCC D:1E5 0000FFFC S:1CC 00003686 D=1E5 00003686 Z C T0.PC 176 . : mov A0BFCBCC D:1E5 0000FFF2 S:1CC 00003687 D=1E5 00003687 Z C T0.PC 176 . : mov A0BFCBCC D:1E5 0000FFF3 S:1CC 00003688 D=1E5 00003688 Z C T0.PC 176 . : mov A0BFCBCC D:1E5 0000FFF2 S:1CC 00003689 D=1E5 00003689 Z C T0.PC 176 . : mov A0BFCBCC D:1E5 0000FFF4 S:1CC 00003689 D=1E5 00003689 Z C T0.PC 176 . : mov A0BFCBCC D:1E5 0000FFFC S:1CC 0000368A D=1E5 0000368A Z C T0.PC 176 . : mov A0BFCBCC D:1E5 0000FFFE S:1CC 0000368B D=1E5 0000368B C T0.PC 176 . : mov A0BFCBCC D:1E5 0000FFFA S:1CC 0000368C D=1E5 0000368C Z C T0.PC 176 . : mov A0BFCBCC D:1E5 0000368F S:1CC 0000368D D=1E5 0000368D C T0.PC 176 . : mov A0BFCBCC D:1E5 0000368E S:1CC 0000368E D=1E5 0000368E C T0.PC 176 . : mov A0BFCBCC D:1E5 0000FFFF S:1CC 0000368F D=1E5 0000368F Z C T0.PC 176 . : mov A0BFCBCC D:1E5 0000FFFE S:1CC 00003690 D=1E5 00003690 Z C T0.PC 176 . : mov A0BFCBCC D:1E5 00003693 S:1CC 00003691 D=1E5 00003691 C T0.PC 176 . : mov A0BFCBCC D:1E5 00003692 S:1CC 00003692 D=1E5 00003692 C T0.PC 176 . : mov A0BFCBCC D:1E5 00003691 S:1CC 000044E7 D=1E5 000044E7 Z C T0.PC 176 . : mov A0BFCBCC D:1E5 0000FFFA S:1CC 000044E8 D=1E5 000044E8 Z C T0.PC 1AA Ok>
I'll be getting more GadgetGangster hardware today. I'll put that and an SDRAM board in the mail to you soon.--Steve
I'm a bit busy to concentrate on that post just now.
Have you tried setting #define SINGLE_STEP ?
With that and the hello.lst file in hand you can follow execution all the way to main fairly easily and see every op code it picks up.
That's about all I had to use.
I guess I would have noticed that eventually.
Hello world The meaning of life = 42 Hi Zog say hello 0000000e argc = 00000001 Address of argv[0] = 00003dbc _hardware = 00000000 _cpu_config = 00000002 ZPU_ID = 0000000e _use_syscall = 00000000 Please type 4 characters... 1234You typed... 1234 The following should be deadbeef deadbeef The following should be 00000009 00000009 The following should be 0001da31
But FIBO fails. :mad: ... more work to do.
FIBO using SdramCache is slower than VMCOG and Triblade,
but it crashes the same. At least the FIBO results are correct.
Is ZOG is running out of stack?
"Two wrongs don't make a right, but three rights make a left."
-Cosmo, Fairly Odd Parents
fibo(00) = 000000 (00000ms) fibo(01) = 000001 (00000ms) fibo(02) = 000001 (00000ms) fibo(03) = 000002 (00000ms) fibo(04) = 000003 (00001ms) fibo(05) = 000005 (00002ms) fibo(06) = 000008 (00003ms) fibo(07) = 000013 (00006ms) fibo(08) = 000021 (00010ms) fibo(09) = 000034 (00017ms) fibo(10) = 000055 (00028ms) fibo(11) = 000089 (00045ms) fibo(12) = 000144 (00073ms) fibo(13) = 000233 (00119ms) fibo(14) = 000377 (00192ms) fibo(15) = 000610 (00311ms) fibo(16) = 000987 (00504ms) fibo(17) = 001597 (00816ms) fibo(18) = 002584 (01321ms) fibo(19) = 004181 (02138ms) fibo(20) = 006765 (03460ms) fibo(21) = 010946 (05598ms) fibo(22) = 017711 (09059ms) fibo(23) = 028657 (14658ms) fibo(24) = 046368 (23717ms) fibo(25) = 075025 (38376ms) fibo(26) = 121393 (21133ms) #pc,opcode,sp,top_of_stack,next_on_stack #---------- 0X00034D1 0X00 0X0000FFB8 0X00003822 BREAKPOINT
That's no crash. It only goes up to fibo(26). When main exits in eventually halts with a breakpoint instruction.
Now is this the old VMCOG and 20 pages? What about other page settings?
Wow. Ok. Would be nice to have a graceful exit
That's using SDRAM without VMCOG, a 16K cache, and 32 byte cache line.
I'm not sure I have ever written a program that exits gracefully, in general they are not supposed to stop
The C run time supplied with zpu-gcc has the break point in it. Which seems quite reasonable to me in the absence of HALT. I guess as we don't have a break point debugger we can just treat it as "end of prog" and print something polite.
We have to tweak Zog to allow up to 32MB RAM. Currently addresses over 64K are mapped into HUB space.
I'll migrate to zog_v1_3 vintage at some point. I could try a file that "would likely remove" the 64KB restriction if you have one. The right thing to do is of course get hardware to you for development and as I've mentioned that's in process.
Meanwhile, I'm experimenting with different cache line sizes to check performance impact and may settle on something other than 32bytes. I should try xxtea and other programs as well.
Cheers.
--Steve
To use up to 32MB RAM change the definition of vhub_end in zog.spin as so:
vhub_end long $01FFFFFF ' 32M - 1
That will allow access up to 32 MB of ext RAM whilst buggering up access to HUB RAM from C. But as we are not currently doing any of that who cares for now?
At least when I make that change here fibo still runs OK.
Speaking of "oops", we'll soon have uCLinux running on the Prop:)
Changing vhub_end seems to work. Thanks.
"But that's impossible."
I'm glad you said so. Now I know it's as good as done:)
I forgot to mention and perhaps you have spotted it already but it is necessary to change the constant zpu_memory_size in debug_zog.spin to use 32MB external RAM. This ends up getting used to set the initial value of the ZPU stack pointer.
zpu_memory_size = (1 << 16) 'This works
zpu_memory_size = (1 << 17) 'This fails
--Steve
I have used malloc from external memory, in one version of test_libzog where it put the FDX C++ object on the heap. malloc should work, after all iprintf uses it.
The only memory accesses in ZOG that get mapped to HUB RAM or I/O ports are read_long and write_long. They both check if the address is 64K and up and then branch off to do I/O or HUB access if so.
Look for:
read_long cmp address, word_mask wc 'FIXME this only allows 64K RAM if_nc jmp #in_long
and similar for write_long.
That cmp will need to be changed to test against 32M instead of 64K
Sorry, forgot about that.
Then you might want to revisit those tests against vhub_end that get us into HUB RAM or just remove them.
Changing those two word_mask comparisons to vhub_end did it - thanks. I assume something else depends on the resulting C state as just removing the check causes run-time failure.
Here's what I'm getting on the malloc business. No idea why 4MB+ fails. How big is an sbrk block? My malloc pointer is a char* and was getting null pointers without a cast before ... I'm getting lazy
Malloc big buffer size: 256 Free big buffer. ... Malloc big buffer size: 2097152 Free big buffer. Malloc big buffer size: 4194304 Oops, malloc failed. Malloc big buffer size: 8388608 Oops, malloc failed. Malloc big buffer size: 16777216 Oops, malloc failed.
void malloctest(int size) { char* mp; printf("Malloc big buffer size: %d\r\n",size); mp = (char*)malloc(size); if(mp != 0) { printf("Free big buffer.\r\n"); free(mp); } else { printf("Oops, malloc failed.\r\n"); } } // called with: for(n = 8; n < 25; n++) malloctest(1<<n);
I'll add some buffer test mashup code tomorrow and see what happens.
The latest uClinux distribution is > 300MB. It took over half an hour to get the package and archive manager is *still* opening it.
Guess I should post the debug_zog and zog spin files. I'll wait on posting the SDRAM drivers until later.
Cheers.
--Steve
It makes sense, if that check is remove then you no longer get memory mapped I/O ports mapped in and iprintf etc stops working.
If you put _use_syscall = 1; at the beginning of main() then the C run time will use SYSCALL instead of memory mapped I/O ports which would no longer be needed.
"How big is an sbrk block?" - No idea I'm afraid.
Not sure why the lack of a cast would get you a NULL pointer. A compiler warning/error yes but...
Thanks,
David Betz
I have never tried the Cygwin version so I'm not sure I can be much help, I'll try and find time to set up a Windows box (We don't have any around here normally) and have a play.
Which "include" directory do you mean? And at what point is it missing?
I can see 21 include directories under my "toolchain"
Can you try a command like:
$ find -name include
and post the result?
I suspect the directory may be there but there is some include path not set up correctly.
Here is what I have:
$ find -name include ./binutils/include ./gcc/libffi/include ./gcc/libstdc++-v3/include ./gcc/include ./gcc/boehm-gc/include ./gcc/newlib/testsuite/include ./gcc/newlib/libc/include ./gcc/newlib/libc/sys/rtems/include ./gcc/newlib/libc/sys/linux/include ./gcc/newlib/libc/sys/linux/machine/i386/include ./gcc/gcc/doc/include ./gcc/libjava/include ./gdb/include ./install/include ./install/lib/gcc/zpu-elf/3.4.2/include ./install/lib/gcc/zpu-elf/3.4.2/install-tools/include ./install/zpu-elf/include ./gccbuild/zpu-elf/libstdc++-v3/include ./gccbuild/gcc/cp/include ./gccbuild/gcc/include ./gccbuild/gcc/f/include ./gccbuild/gcc/fixinc/include
Yesterday I Installed Cygwin (with gcc-core developer tools), zpugcccygwin.tar.bz2, and zog on my netbook for a demo. I was able to build programs no problem. I suspect that any extra include files necessary are part of the gcc-core developer package, so you might want to install that.
I've attached a test_libzog.binary that you will need for 80MHz operation (change the name to test_libzog.bin after download). Heaters library is by default 104MHz. Other frequencies require another build - seems there should be a solution easier to customize.
--Steve
I'm also not entirely clear on how to go from a test.bin file to something that can be loaded and run on the Propeller. Is there an example of how to do this somewhere?
Thanks,
David
I've been using debug_zog.spin as the top spin object. I build with "bstc -Ox debug_zog" for example. So for non XMM builds in debug_zog.spin I keep #define USE_HUB_MEMORY uncommented and change the file to load as defined for zpu_image which by default is fibo.bin. The image to load is built from one of the test subdirectories.
Maybe just try the debug_zog.spin route until heater can explain the rest.
--Steve
I guess what I'm really trying to understand is what runtime support is available to programs compiled to run under the ZOG VM? Can the programs use stdio with fopen/fclose/etc? What low-level I/O functions are available. It would be nice to have a simple list of the functions that are available in the runtime.
I experimented with a 4-way associative cache and got something working, but the performance was worse than straight direct mapped cache.
I'll focus on malloc and other testing now .....
@David, Heater must be on holiday.
The short answer is no.
The long answer is a very, very, very painful yes.
It would best for Heater to answer these.
--Steve
That's what I thought. I've downloaded bstc and bstl and will use those for my ZOG work.
Are there any examples of relatively large programs ported to ZOG? I've only seen small demo programs so far. Any idea how big a program might fit into HUBmemory? The platform I'm coding for won't have a big attached SRAM.
I just downloaded Cygwin into Windows XP running in VirtualBox. Takes for ever if you install everything:) Compiling with install/bin/zpu-elf-gcc -phi hello.c just worked out of the box. You have yours working as well now so let's move on.
and
Good question, and one that I have not got to the bottom of yet.
Firstly IO.
Out of the box the ZPU tool chain, is set up to support some simple configurations of the ZPU processor core on an FPGA. It's only I/O is a console port which is memory mapped and a timer register. If you really want to get into this you would have to download the tool chain sources and have a look in the C run time support source.
Zog implements the console port by way of checking ZPU LOAD and STORE instructions. If the address is outside of the ZPU memory range then the access is passed along to the debug_zog COG to handle. Look for zog_mbox in the code. Currently debug_zog sees I/O commands for the console port address and uses FullDuplexSerial to do the work.
In this way things like printf work and we can get "Hello World" running.
There is an alternative I/O mechanism that uses the ZPU SYSCALL instruction. If you put "_use_syscall = 1;" in your program then then standard input and output are redirected to use SYSCALL. This mechanism seesm to be implemented in ZPU for use with the Java simulator. Zog passes all SYSCALLs out to debug_zog in much the same way as I/O operations.
The only syscalls implemented in debug_zog are SYS_read and SYS_write and they only work on the stdio file handles at the moment. Again, enough to get "Hello world" working. Perhaps the syscall mechanism will be expanded to use the SD card file system at some point.
So, given the fact that C programs under Zog have no file system yet most of the standard C library is there. Have a look in your install/zpu-elf/include/ directory to see what we have. I cannot guarantee how much of it is actually implemented though. For that we would have to look at the C libraries "newlib" and "libgloss" source.
If you want to get into floating point there is libm chock full of sin, cos, tan, etc. But warning, the resulting binaries will be huge and slow. I'm working on adding a floating point "coprocessor" cog which will improve that situation dramatically.
Good plan, things like printf are rather huge (There is a smaller iprintf though and there is a print function that is small and works directly on the ZPU UART port). Have a look in hello.c for examples. You can slways read/write bytes directly to that UART prort address from your C code and build up your own mini I/O library. Taking things further one could add further IO ports to debug_zog and use them for whatever other device drivers you want.
debug_zog.spin is the top level object that starts up Zog and provides I/O for ZOG, in there you will see that the ZPU binary is included into the Spin using a "file" statement when running ZPU code from HUB memory. Of course one could hack that around to load the binary from an SD card file instead as is done when exeuting from external memory.
Not yet. At the moment in time I'm still amazed the thing works at all:) A minimal C program currently comes out at 3K bytes or so. I'm going to look into shrinking that. There is at least 1K of vector table that gets included with the run time that we don't use and should be removed.
I've been running programs with debug_zog that sit in 26K Bytes of HUB memory leaving 252 LONGs free. Just tweak the
"zpu_memory_size" constant.
General:
debug_zog as it's name suggests has grown as a tool to debug the interpreter, the external RAM, and C programs it runs. As a result it ends up providing the console I/O and even SD card support which is usefull for actual applications. It serves as an example of ZOG usage. It can of course be chopped down or extended as required for any particular application.
run_zog is something of an experiment at the moment. The aims here are:
1) Get Zog and C code running with minimal memory foot print for the Spin startup code and hence maximum HUB memory for C.
2) Optionally enable Zog to takeover the entire Propeller with no Spin code left at run time at all.
As such it has no I/O, it's just a loader. That means that any I/O, a serial port for example, has to be created in C. Enter libzog.
libzog is even more experimental and has the following ideas in mind:
1) Create C versions of things like FullDuplexSerial. That is use the PASM parts of existing objects, possibly adapted a little, and replace the Spin interfaces with C interfaces. This has been shown to be quite workable and FullDuplexSerial and VMCog have C wrappers.
2) libzog is an experiment in working with C++ under Zog. Which turns out is a good fit for makeing the equivalent of Spin objects.
3) libzog will grow to support Arduino programs.
4) Zog itself should be have a C++ wrapper so that it can be used from C++ programs. That is staring multiple interpreter instances as you do in Spin.
test_libzog is just a little test harness for the objects in libzog and is first program we have that runs with out any Spin code left in the Prop.
I think for any real application Zog will need access to Prop features like waitxx, DIRA, INA, OUT, CNT, LOCKS etc etc. I want to put as much of that as possible into the interpreter COG. Space is getting tight.
If you have a pressing need for anything let us know and I'll move it up the priority list.