Shop OBEX P1 Docs P2 Docs Learn Events
Zog - A ZPU processor core for the Prop + GNU C, C++ and FORTRAN.Now replaces S - Page 32 — Parallax Forums

Zog - A ZPU processor core for the Prop + GNU C, C++ and FORTRAN.Now replaces S

1293032343538

Comments

  • jazzedjazzed Posts: 11,803
    edited 2010-12-29 15:59
    I'm sorry. Timesharing the serial line is unreasonable unless it's one of those old style BBS programs. I'm off my game today since I was up all night. It's just curious to me that anyone needs a display on the target during the loader stage in the first place ... updating loader status on the PC should be good enough. It's OK for debugging I guess, and it's your effort so I should be more supportive of that.
  • David BetzDavid Betz Posts: 14,511
    edited 2010-12-29 16:15
    I did it for debugging. When I first wrote the helper program it didn't work correctly for quite a while (no surprise!). Having debugging output independent of the serial connection helped me debug it. You're right that there isn't really a need for it once the system is working. I'll put all of the TV stuff under a USE_DEBUG conditional.
  • David BetzDavid Betz Posts: 14,511
    edited 2011-01-01 19:34
    I've been slogging away at cleaning up my ZOG toolchain for the C3 and I think I'm making some progress. I now have a PC loader program that builds for Windows (both Win32 and cygwin) and Linux. I suspect getting it to build on the Macintosh would be easy. After all, it's just a simple command line tool. It can write files to an SD card, directly to C3 flash or to RAM on either the C3 or jazzed's SDRAM board. I've tested the C3 downloads but I don't have the hardware required to test the SDRAM board support so I'll have to wait for jazzed to let me know if it is working.

    My next task is to try to make the runtime code more flexible. Right now I always load a serial driver and use it for stdin/stdout/stderr I/O. I want to change that to allow stdio to be redirected to other drivers like the TV driver or the higher res Tv2 driver that jazzed has been working on. My question now is how to do that. The easiest way I can come up with is to have all stdio (console and file) redirected to /dev/null by default and then to have functions you can call to redirect it to a device. The idea would be to have the C program load the required driver (serial, TV, etc.) and then call a function to redirect stdio to that driver. This is pretty easy to do but it means that you'd have to modify every C program with code to load the driver and call the redirect function. That means you couldn't run unmodified generic C code without adding these calls.

    Another approach would be to use build-time switches to load the appropriate drivers. This has the advantage that it doesn't require modifications to standard C code but it also complicates the build process.

    Any thoughts?
  • David BetzDavid Betz Posts: 14,511
    edited 2011-01-01 20:26
    I have a question about the memory layout of a ZOG program. It seems that the start address is at location zero but it is my understanding that there are also pseudo-registers located at location zero as well (return values for syscalls for instance). How is this conflict resolved? Is there a jmp instruction at location zero initially and then it gets overwritten by the register values after initialization?
  • jazzedjazzed Posts: 11,803
    edited 2011-01-01 22:38
    David Betz wrote: »
    It can write files to an SD card, directly to C3 flash or to RAM on either the C3 or jazzed's SDRAM board. I've tested the C3 downloads but I don't have the hardware required to test the SDRAM board support so I'll have to wait for jazzed to let me know if it is working.
    Downloads appear to work but nothing will run. Guess i'll be doing those zog.spin diffs soon.
    David Betz wrote: »
    The idea would be to have the C program load the required driver (serial, TV, etc.) and then call a function to redirect stdio to that driver.
    The easy thing to do is overload putchar and use driver methods for cases like TV where users may want to read/write screen memory.
  • David BetzDavid Betz Posts: 14,511
    edited 2011-01-02 00:30
    jazzed wrote: »
    Downloads appear to work but nothing will run. Guess i'll be doing those zog.spin diffs soon.


    The easy thing to do is overload putchar and use driver methods for cases like TV where users may want to read/write screen memory.

    The problem with overloading putchar is that it only allows the stdio functions to work. It doesn't allow open/close/read/write functions to address the console. Those are lower level functions that work with file descriptors instead of stdio FILE variables. Of course, your point is still valid if I instead allow the user to redefine the read/write functions. I've not wanted to do that because it makes it more difficult for the user to just redirect console I/O and not file I/O. I'll come up with a proposal tomorrow (Sunday).
  • Heater.Heater. Posts: 21,230
    edited 2011-01-02 00:48
    David,
    It seems that the start address is at location zero but it is my understanding that there are also pseudo-registers located at location zero as well

    The start of a ZPU binary contains the following at address zero:
    _start:
    _memreg:
                    ; intSp must be 0 when we jump to _premain
    
                    im ZPU_ID
                    loadsp 0
                    im _cpu_config
                    store
                    config
                    jmp _premain
    

    No idea where the _memreg gets initialised though. Have a look in crt0.S

    After that is an interrupt vector and a table of vectors for instruction emulation. The later should really be removed as we don't use the ZPU EMULATE instruction.
  • David BetzDavid Betz Posts: 14,511
    edited 2011-01-02 19:43
    Thanks for the information on memreg and how it relates to the startup code. Unfortunately, I didn't get to creating an SDRAM linker script today. I ended up spending most of the day trying to come up with an easy way to select console and file I/O drivers at build time. My plan was to split my libprop.a library into a number of smaller libraries, one for each type of console I/O (none, serial, TV, etc) and one for each type of file I/O (none, SD, etc). Unfortunately, that didn't work. I couldn't control which files were pulled out of each library accurately enough. I'm going to have to come up with some other approach, possibly including actual code in main() to select the appropriate console and file I/O code. I wanted to avoid that to make it possible to compile and run unmodified generic C source code on the Propeller but I'm out of ideas on how to do that at the moment.

    One thing I did realize today is that once I get past this library issue I *do* have the ability to test the linker script that will ultimately be used with jazzed's SDRAM board. Since it maps RAM starting at zero it can use the same linker script as the C3 uses when it runs entirely out of SRAM and not flash. That will let me test things before sending them to jazzed which will probably make it more likely that when I do release my code it will actually work on his SDRAM board. :-)

    Unfortunately, I won't have anywhere near as much time to work on this now since my week long holiday break is over. :-(
  • David BetzDavid Betz Posts: 14,511
    edited 2011-01-03 12:52
    I ended up taking advantage of a feature of the current ZPU runtime code. If an application defines the function _initIO it gets called before main(). I'm using that as a hook to setup console and file I/O so that the original generic C code doesn't have to be modified. You just add another file to your project that defines how I/O is done under ZOG. I've attached a simple sample of how this can be used to setup either serial or TV console I/O.
    c
    c
    110B
  • David BetzDavid Betz Posts: 14,511
    edited 2011-01-04 17:11
    Heater: Have you ever tried setjmp and longjmp? I don't think they're working. At least, that's the simplest explanation for why my basic interpreter can't recover from errors. I looked at the code and it doesn't look obviously wrong to me but I don't really know the ZPU instruction set. Have you tried these?

    Edit:

    Sometimes it seems like I'm talking to myself in here! :-)

    I just wrote a test program and at least simple cases of setjmp/longjmp seem to be working. I guess I'll have to look for my basic bug elsewhere...
  • jazzedjazzed Posts: 11,803
    edited 2011-01-04 20:53
    And Zog turns 48 ... next stop, over the hill.

    It feels like summer in my office. Long, slow days minus the heat.
    Still working on that integrated package here.

    Good luck with setjmp/longjmp.
  • Heater.Heater. Posts: 21,230
    edited 2011-01-05 00:55
    Sorry for the absence of heat. Seems I'm kicking off the new year with 12 hour working days and general panic all around. I have a lot of Zogging to catch up on now.

    Actually I don't think I've ever used setjmp/longjmp on any machine but it looks like you have it working in some way.

    Speaking of heat, it's still 14 degrees C below here and a serious lot of snow.
  • David BetzDavid Betz Posts: 14,511
    edited 2011-01-05 08:32
    Where is the best description of the ZPU instruction set? I'm finding that I sometimes need to try to read ZPU assembly code and I'd like to understand the instruction set better.
  • Heater.Heater. Posts: 21,230
    edited 2011-01-05 08:56
    The only ZPU instruction set document I know of is here : http://repo.or.cz/w/zpu.git?a=blob_plain;f=zpu/docs/zpu_arch.html;hb=HEAD

    Be warned it has a few errors.

    My ZPU emulator written in C is a good reference, it does exactly what the ZPU HDL does, tested and compared over millions of instruction steps. You can find it attached to the first post of this thread.

    Else its dig out the ZPU simulator in Java from the ZPU git repository, which is the reference zpu_in_c and ZOG were written against.
  • David BetzDavid Betz Posts: 14,511
    edited 2011-01-08 15:29
    Heater: Why do you store the address of the ZOG dispatch table in io_command at startup?
  • Heater.Heater. Posts: 21,230
    edited 2011-01-08 22:11
    David,
    Why do you store the address of the ZOG dispatch table in io_command at startup?
    As far as I know ZOG does not do any such thing! Which bit of code are you thinking of?

    ZOG is given the address of his own dispatch table during start up via a PAR parameter block. Is that what you mean?

    The idea here is that the dispatch table is in HUB and can be relocated to any HUB location prior to starting ZOG. For example run_zog puts it at the end of HUB.

    I thought you had already done something like that?
  • David BetzDavid Betz Posts: 14,511
    edited 2011-01-09 06:25
    [QUOTE=Heater.;966658As far as I know ZOG does not do any such thing! Which bit of code are you thinking of?

    ZOG is given the address of his own dispatch table during start up via a PAR parameter block. Is that what you mean?

    The idea here is that the dispatch table is in HUB and can be relocated to any HUB location prior to starting ZOG. For example run_zog puts it at the end of HUB.

    I thought you had already done something like that?[/QUOTE]
    The line I commented out is at the end of the initialization code just before the jmp to #execute.
                            wrlong  dispatch_tab_addr, io_command_addr
                            jmp     #execute
    

    Edit: I just checked my copy of zog.spin from your release 1.6 and don't find that line. Maybe I added it in my sleep one night? :-)
    Anyway, I'll remove it. Sorry for the false alarm!!

    Yes, I'm relocating the zog dispatch table to high hub memory. In fact, I stole my code from your run_zog.spin file! :-)

    I have ZOG running pretty well on the C3 now and I've written a loader that makes it pretty easy to develop programs using GCC and then load them into the C3 without having to edit any Spin code. I can do all of my development with just the cygwin toolset using make and gcc as well as zogload (my loader program) without having to use either BST or the Parallax Spin tool. I can support sending files from the PC to the SD card or directly to either C3 flash or SRAM. This loader also works with jazzed's SDRAM board as of yesterday.

    C programs can use getchar/putchar and the associated stdio library functions to handle console I/O to either a serial port or the TV/keyboard. The stdio functions can also be used for file SD card file I/O.

    So, I have a question for you. I'd like to put together a toolset to upload to the C3 FTP directory. This will consist of a version of ZOG.spin and my loader program as well as the ZPU toolset and maybe some pieces from cygwin (make mostly). I don't think there is any license statement in ZOG.spin at the moment. What license would you like to use? Is the MIT license okay?
  • David BetzDavid Betz Posts: 14,511
    edited 2011-01-11 10:33
    I'm trying to tie up some loose ends before releasing a C3 version of ZOG and I have a couple of questions about the flags passed to the C compiler.

    CFLAGS=-g -Wall -Os

    I'm assuming none of those are actually necessary for proper operation. Certainly the -Wall just controls warning messages and -g controls the generation of debug information in the object file. Is -Os required or does it just provide better space optimization?

    LDFLAGS=-phi -Wl,--relax -Wl,--gc-sections

    What do these do and which are necessary? I think -phi selects a linker script. Do I need it if I supply my own linker script explicitly? What do the --relax and --gc-sections options to the linker do and are they necessary?

    Thanks,
    David
  • Heater.Heater. Posts: 21,230
    edited 2011-01-11 11:06
    David,

    I don't know if -phi selects a linker script but if you leave it out or get it wrong you get an error about undefined reference to `ZPU_ID'. See crt0.S.
    These ids are used to select different versions of the ZPU processor depending on the subset of instructions they implement. The Java ZPU simulator uses this id, delivered by the "config" instruction in order to perform the correct cpu level simulation. I guess we could live with out it. Or just ignore it as we do now:)

    -g we can drop as we don't have a debugger to use its output.
    -Wall is always good.
    -Os is optimize for size. Removing -Os makes my hello.c 500 bytes bigger.

    -Wl,--gc-sections Not sure what this does but again it adds 500 bytes to hello.bin if it is not there.

    -Wl,--relax IS VERY IMPORTANT!!!!

    As you know the IM instruction loads immediate values to the stack. It does it 7 bits at a time. The bigger the number you want to load the more IM instructions you need to build it up. It takes 5 IM's in a row to build a 32 bit number.

    The compiled and assembled modules will always have 5 IM instructions in a row for each immediate that is loaded. This is very wasteful of space and time as a lot of numbers used in code are only one or two bytes wide so one or two IM's would be enough.

    It is the linker that checks the use of all these IM's and reduces the number of them used wherever possible. That is "relaxing"

    This is probably the most important optimization option as it has a huge effect on code size and execution speed. e.g. hello.bin is 23K without it but 18K with it!!
  • David BetzDavid Betz Posts: 14,511
    edited 2011-01-11 11:08
    Thanks for your response! That was very helpful.
  • David BetzDavid Betz Posts: 14,511
    edited 2011-01-15 07:05
    I'm trying to put together a ZOG package for the C3 and I'm having trouble figure out a minimal environment necessary for running the ZPU tools under Windows. I know they work under Cygwin but I'd like to avoid having to tell people to go through the whole gory Cygwin installation process just to run the ZPU compiler. I've tried just copying the Cygwin DLLs to the ZPU executables directory but they don't seem to work correctly. For instance, trying to compile a C program using the command:

    zpu-elf-gcc -c hello.c

    Produces the following error message:

    zpu-elf-gcc: installation problem, cannot exec 'cc1': No such file or directory

    There is no 'cc1' program that comes with the ZPU tools. There isn't even a 'zpu-elf-cc1'. Any idea how I can get around this problem? I want to provide a simple batch file to compile and link a ZPU program for ZOG under the Windows command prompt.

    Thanks,
    David
  • Heater.Heater. Posts: 21,230
    edited 2011-01-15 08:03
    Sure there is:

    ./toolchain/install/libexec/gcc/zpu-elf/3.4.2/cc1
  • David BetzDavid Betz Posts: 14,511
    edited 2011-01-15 09:57
    Heater. wrote: »
    Sure there is:

    ./toolchain/install/libexec/gcc/zpu-elf/3.4.2/cc1

    That's interesting. I guess it must be a path problem then. Thanks!
  • David BetzDavid Betz Posts: 14,511
    edited 2011-01-27 06:59
    I thought it might be good to move this discussion to the forum instead of email since others may have opinions on this. I have two proposals for revising the ZOG memory map. One is a minor change in what we already have to make space for the hub ROM as well as the larger hub RAM in Propeller 2. The other is more dramatic providing much a larger space for external memory. Both have the virtue that they do not use negative addresses.

    First proposal:

    0x00000000 - 0x0fffffff for external RAM/ROM (256mb max)
    0x10000000 - 0x17ffffff for hub memory (I'm sure Propeller 3 will have 128mb of hub memory!)
    0x18000000 - 0x1fffffff for COG memory and any I/O registers (although my version of ZOG doesn't use them)

    Second proposal:

    0x00000000 - 0x3fffffff External RAM/ROM (1gb max)
    0x40000000 - 0x403fffff Hub RAM/ROM (4mb max)
    0x40400000 - 0x404001ff COG RAM (2k but top could be expanded)

    Heater pointed out in the email thread that the larger addresses require more IM instructions. I think this suggests that the more modest first proposal might be best but will that leave enough external RAM/ROM space for future Propeller boards. I think jazzed is already planning a 128mb board. Is 256mb too little address space for external RAM/ROM?
  • jazzedjazzed Posts: 11,803
    edited 2011-01-27 07:51
    The first proposal is fine. I've wanted to move COG registers so we could access the ROM tables anyway.

    As far as SDRAM size, I've decided to use a single chip solution which means maximum 64MB.
  • David BetzDavid Betz Posts: 14,511
    edited 2011-01-27 10:00
    jazzed wrote: »
    As far as SDRAM size, I've decided to use a single chip solution which means maximum 64MB.

    So I guess that means that the current 256mb of space for external RAM/ROM is sufficient. Now that you've decided not to use a second SDRAM chip, any chance you'll make a version of the MicroPropPC with 64mb of SDRAM and 64mb of flash? :-)
  • David BetzDavid Betz Posts: 14,511
    edited 2011-01-31 06:39
    Heater: Do you have any idea how big a job it would be to make a little endian version of ZOG? It seems that the latest ZPU toolchain can support generating little endinan object files using the -mno-bytesbig compiler option. Would recompiling newlib using that option be all that is needed to make a complete little endian ZPU toolchain? Then, of course, ZOG itself would need to be modified but I suspect that isn't much more than deleting a bunch of XOR with %11 instructions, right? I think ZOG would work much better with PASM drivers if we could make it little endian like the rest of the Propeller world. When you just run simple C programs like fibo it doesn't matter much but when you start trying to interact with drivers it becomes a pain to have to byte and word swap all of the place.
  • Heater.Heater. Posts: 21,230
    edited 2011-01-31 09:48
    David,

    Intriguing, I have never heard of no-bytesbig before. Google knows nothing except what the ZPU guys have been doing. My current version of zpu-gcc does not accept it.

    Anyway, if it works I guess removing the byte reversal step from the Makefiles and those XORs from the byte and word access routines is enough to change Zogs endianness. So not a big job there.

    Then we only have to worry about any endianness issues that might show up in newlib and the crt0.S etc.

    If it can be made to work that would be very convenient, as you say. I'll try and get my zpu-gcc up dated and try some experiments.
  • David BetzDavid Betz Posts: 14,511
    edited 2011-01-31 10:02
    Try typing "zpu-elf-gcc --target-help" to get the target-specific options. If you don't find that you have "-mno-bytesbig" then you might have an old version. I notice that the binary version I downloaded doesn't have it but the version I built from sources does.
  • Heater.Heater. Posts: 21,230
    edited 2011-01-31 10:38
    Just built the latest zpugcc from git. It accepts -mnobytes-big.

    But I can't see that it does anything. I added -mnobytes-big to both the compile and link flags in the Makefile for my old endian.c test. In the resulting listing file I see:

    00003ca4 <a_number>:
    3ca4: 76 loadsp 24
    3ca5: 54 storesp 16
    3ca6: 32 xor
    3ca7: 10 addsp 0

    The bytes are in the same order whether I have nobytes-big or not.
Sign In or Register to comment.