Shop OBEX P1 Docs P2 Docs Learn Events
C-DOS — Parallax Forums

C-DOS

Dave HeinDave Hein Posts: 6,347
edited 2010-04-17 12:04 in Propeller 1
I've done some more work on the EEPROM file system, and I discovered I could load individual spin objects and relocate them by manipulating the object offsets.· So I decided to develop a disk operating system I call C-DOS.· I call it C-DOS because it relies heavily on the clib object I checked into the OBEX.

The current version of c-dos uses the second half of the boot loader EEPROM for the file system.· When you first start cdos you are prompted to use the format command to format the EEPROM.· You can then·use the appcall command to run the default app, which will load three small apps onto the file system.

Currently, a c-dos app can only consist of a single object that must include the clib and eefs object.· The operating system will call a method named "main", which·must be defined as

PUB main(argc, argv)

argc indicates the number of arguments that are passed, and argv is an array of string pointers containing "argc" entries.· The c-dos app object cannot use any variables defined in a VAR section, and must only use variables on the stack or in a DAT section.

I have attached the three spin files that implement c-dos, the EEPROM file system and the c-dos default app.· Let me know if you have any questions or coments.· BTW, c-lib must be loaded into the Prop's RAM using the F10 key, and not into the EEPROM using the F11 key or you will wipe out the EEPROM file system.

You will also need clib and Basic_I2C_Driver from the OBEX.

Dave

Post Edited (Dave Hein) : 4/11/2010 9:38:38 PM GMT

Comments

  • mikedivmikediv Posts: 825
    edited 2010-04-11 23:41
    Hey Dave I have not tried this yet but pretty cool thanks for sharing
  • mparkmpark Posts: 1,305
    edited 2010-04-12 00:19
    I can't find clib in obex. Link pliz?
  • Dave HeinDave Hein Posts: 6,347
    edited 2010-04-12 00:45
    mpark said...
    I can't find clib in obex. Link pliz?
    CLIB is located at http://obex.parallax.com/objects/594/·.· For some reason the OBEX search wasn't finding the term "clib" in the title.· I added it to the description so the seach works OK now.
  • Brian RileyBrian Riley Posts: 626
    edited 2010-04-12 04:24
    Both cdos.spin and testclib.spin generate an error in line 272 of cfloatsring.spin

    cheers .... BBR

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    cheers ... brian riley, n1bq, underhill center, vermont
    The Shoppe at Wulfden
    www.wulfden.org/TheShoppe/
    www.wulfden.org/TheShoppe/prop/ - Propeller Products
    www.wulfden.org/TheShoppe/k107/ - Serial LCD Display Gear
  • kuronekokuroneko Posts: 3,623
    edited 2010-04-12 05:01
    Brian Riley said...
    Both cdos.spin and testclib.spin generate an error in line 272 of cfloatsring.spin
    Compiles fine here (PropTool 1.2.7).
  • Dave HeinDave Hein Posts: 6,347
    edited 2010-04-12 13:56
    Brian Riley said...
    Both cdos.spin and testclib.spin generate an error in line 272 of cfloatsring.spin
    Line 272 is "repeat -exp10", correct?· It compiles OK under version 1.2.5 and 1.2.7(R2).· You might try upgrading the prop tool on your computer.· Or, you can comment out the four references to cfloatstr in clib.spin.· cdos.spin doesn't use floating point.
    Dave
  • kuronekokuroneko Posts: 3,623
    edited 2010-04-12 14:19
    Seems that BST chokes on repeat -variable.

    Mentioned this in the bst thread as well (http://forums.parallax.com/showthread.php?p=755835).

    Post Edited (kuroneko) : 4/12/2010 2:32:57 PM GMT
  • Dave HeinDave Hein Posts: 6,347
    edited 2010-04-12 15:53
    I tried the latest version of BST (version 0.19.3) and it still has a problem with repeat -variable.· You can change line 272 to "repeat 0-exp10" to work around the problem.· Note that BST has an option to remove unused methods.· This option should not be checked when building cdos because the method call table must be the same as when the app was built.

    Just a few comments about how I dynamically load apps.· The apps are stored in the file system as a memory image of the app object.· I prefix the memory image with the four ascii characters "Exec" to·distinguish apps files from other·files.· The app files are created by building a version of cdos with the app, and then using the appsave command to store it as a file.· After I created the sample apps hello, echo and clock I had to use the dumpf command to print out the hex codes, and then manually create the default app which writes the app files on a new file system.

    This is a tedious and manual process, and· I'll have to figure out a way to automate this by transferring the files from the host computer somehow.

    cdos currently uses a small area of memory used by the default app to load and run apps from the file system.· I allocate 200 longs for the stack and the malloc heap follows immediately after the stack to the end of RAM.· I'm going to change this so that the malloc heap will sit in between the cdos object and the clib object.· This will allow me to run larger apps that are as large as the heap space.

    One limitation of spin code is that it can only call methods in other objects that are at a higher address.· They can never reference an object at a lower address.· This is because object offsets must always be positive.· They can never be negative.· I've tried, and it doesn't work if they're negative.· I am guessing that the spin interpreter doesn't mask of the address to 16 bits when adding an offset.· Therefore, a negative 16-bit offest will actually produce a 17-bit address when added to a 16-bit address.

    Moving the malloc heap and keeping the app space between the cdos object and the rest of the code will allow this to work.

    Dave
  • Brian RileyBrian Riley Posts: 626
    edited 2010-04-12 20:10
    I was using latest BST under Mac OSX ... anudder one for Brad to ponder ...
    Dave Hein said...
    Brian Riley said...

    Both cdos.spin and testclib.spin generate an error in line 272 of cfloatsring.spin
    Line 272 is "repeat -exp10", correct? It compiles OK under version 1.2.5 and 1.2.7(R2). You might try upgrading the prop tool on your computer. Or, you can comment out the four references to cfloatstr in clib.spin. cdos.spin doesn't use floating point.
    Dave
    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    cheers ... brian riley, n1bq, underhill center, vermont
    The Shoppe at Wulfden
    www.wulfden.org/TheShoppe/
    www.wulfden.org/TheShoppe/prop/ - Propeller Products
    www.wulfden.org/TheShoppe/k107/ - Serial LCD Display Gear
  • jazzedjazzed Posts: 11,803
    edited 2010-04-12 21:43
    Hi Dave.

    This is a nice effort especially for small utilities that can be run without rebooting the Propeller for reloads. Make a shell interface for scripting and you get lots of flexibility. I suppose you've looked at how some of the other boot-loaders work too; they need to reboot after loading each application to get back to the "O/S" prompt, but complete unmodified spin programs can be launched like that.

    Thanks for contributing your efforts here.
    --Steve

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    May the road rise to meet you; may the sun shine on your back.
    May you create something useful, even if it's just a hack.
  • Dave HeinDave Hein Posts: 6,347
    edited 2010-04-12 23:43
    Steve,

    Thanks for the comments.· I am aware of some of the boot-loaders that reboot after loading.· That approach is probably the more effective way to reload programs.· C-DOS is more of a test program for the EEPROM file system than a real OS.· However, I found it intriguing that I could splice in fragements of a spin program, and it actually works.· A hello world program takes less than 50 bytes as long as the OS is there to provide system services.

    I'm·adding I/O redirection to the command line so that the standard input and output can be redirected to files.· This will add a lot more power to simple apps stored in the file system.· One problem I would like to solve is a way to efficiently transfer files between the Prop and a PC.· The approach I would like to take is to run an app on the PC that talks to the prop over a serial line.· It would provide a serial terminal similar to the Parallax Serial Terminal, but it would also allow the prop to access the PC's file system.· A simple message protocol could be used to pass file I/O information between the prop and the PC.· Unfortunately, it seems like Microsoft has made it difficult to write simple programs that talk to a serial port under Windows.

    Dave
  • jazzedjazzed Posts: 11,803
    edited 2010-04-13 02:44
    Rayman has a Y-modem package you can use for file transfers. There are other ideas to consider if you haven't seen them like stevenmess DOL Dynamic Object Loading (.dll for spin) and various members observations that one can start drivers in cogs and reload spin that can communicate with the cogs to use all 48K memory for applications.

    Cheers.
    --Steve

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    May the road rise to meet you; may the sun shine on your back.
    May you create something useful, even if it's just a hack.
  • Dave HeinDave Hein Posts: 6,347
    edited 2010-04-14 17:46
    jazzed said...
    Rayman has a Y-modem package you can use for file transfers. There are other ideas to consider if you haven't seen them like stevenmess DOL Dynamic Object Loading (.dll for spin) and various members observations that one can start drivers in cogs and reload spin that can communicate with the cogs to use all 48K memory for applications.
    I looked at stevemess' DOL, and it looks very similar to what I'm doing.· I haven't tried relocating the VAR section yet.· It takes a little more trickery than just relocating the object offsets.· It seems like I would have to reserve an area in the VAR space for an app's VARs, and apps would be limited to the size of that space.· For now, I'm just avoiding the VAR issue and only using DAT variables.
    I looked at OBC's PropDOS.· It's a good solution for dynamically loading Spin programs.
    I recall seeing the thread about Rayman's Y-modem package.· I thought about using Windows Hyperterminal to download either ASCII text files, or hex dumps of binary files.· However, I'm still trying to figure out how to do my own Windows/DOS app that would work as a serial terminal/file server/time server for C-DOS on the prop.
    I have done a little more work on C-DOS, and I have file redirection working.· I can type commands like "cat >file1", "cat file1 file2 >file3" and "cat <file1 >>file2".· This all works OK.· I did find a bug in the clib memcpy function.· memcpy will use either bytemove, wordmove or longmove depeding on the the memory alignment of the pointers and the byte count.· However, when I use wordmove or longmove I neglected to divide the byte count by 2 or 4.· This means I was coping either 2 times or 4 times the number of bytes that I should have.· Needless to say, funny things were happening.· I'll fix that in the next version of clib in a few days.
    Dave
  • Cluso99Cluso99 Posts: 18,069
    edited 2010-04-15 00:17
    Dave: Have you looked at Sphinx / SphinxOS ? link in my signature.

    Andy's PropTerminal may also be able to do some of the PC side.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Links to other interesting threads:

    · Home of the MultiBladeProps: TriBlade,·RamBlade,·SixBlade, website
    · Single Board Computer:·3 Propeller ICs·and a·TriBladeProp board (ZiCog Z80 Emulator)
    · Prop Tools under Development or Completed (Index)
    · Emulators: CPUs Z80 etc; Micros Altair etc;· Terminals·VT100 etc; (Index) ZiCog (Z80) , MoCog (6809)·
    · Prop OS: SphinxOS·, PropDos , PropCmd··· Search the Propeller forums·(uses advanced Google search)
    My cruising website is: ·www.bluemagic.biz·· MultiBlade Props: www.cluso.bluemagic.biz
  • Dave HeinDave Hein Posts: 6,347
    edited 2010-04-15 04:11
    Wow, Sphinx and SphinxOS look amazing.· I'll have to try it out.· The amount of stuff done on the prop is a bit overwhelming.· I'll have to spend some time just trying to understand what's already been done on the prop.

    Thanks,
    Dave
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2010-04-15 05:09
    This is a great bit of code. Writing an operating system can be great fun.

    Re "One problem I would like to solve is a way to efficiently transfer files between the Prop and a PC. The approach I would like to take is to run an app on the PC that talks to the prop over a serial line. It would provide a serial terminal similar to the Parallax Serial Terminal, but it would also allow the prop to access the PC's file system. A simple message protocol could be used to pass file I/O information between the prop and the PC. Unfortunately, it seems like Microsoft has made it difficult to write simple programs that talk to a serial port under Windows.

    This can be done. First step is to write a program that can talk to the serial port. vb.net can do this and you can either start from a blank vb.net program and write some very simple code to output a byte and read a byte back and then build it from there, or you can take a complicated bit of working code and try to find the bits in it that do what you want to do. If you are ok being overwhelmed with code see my link at the bottom of this post, scroll down to just above the first picture and there is the text " 2) An IDE written in free vb.net for writing software (C, Basic, Assembly), easy file transfers etc". Click on the IDE to get the complete vb.net source. I presume you can get hold of vb.net as well (it is a free download).

    There are a number of ways to talk to the serial port - I've gone for a Timer and then poll the port regularly. This interfaces with a terminal screen. This program has grown like topsy, but what it can do is write/compile/download a 'hello world' in C or Basic or Assembly with one keypress and get that running on a propeller. You can then view the output on both a local screen and on a terminal screen on the PC as part of this program.

    But what I think might interest you is the code for the file transfer protocol. I've gone for xmodem rather than ymodem as the code is small and simple. I've coded xmodem in both vb.net and sbasic and I also have the Z80 assembly version and it is a protocol both simple enough to understand and also to write code for in multiple languages. However, what I don't have is xmodem written in spin or pasm (as it is easier to run it in z80 assembly using an emulation on a propeller). So if you want xmodem for file transfers the PC side is written but not the spin side.

    In practice using the code is extremely easy. Select 'download', browse to a file and click 'ok'. The file is then transferred to the propeller and stored on an sd card (or in your case, you would store to eeprom). Or you can transfer a file from the propeller back to the PC.

    Of course the ultra simple way of transferring data is just to dump it out the serial port. But the problem is that whatever is receiving the bytes needs to know what is the start, and what is the end and what to call that file. xmodem is one step up from that. You send some bytes "XMODEM R MYFILE.TXT" and then carriage return, and that runs the xmodem program, R tells it to Receive, and then the name of the file you want to call this. Xmodem has some other features too, like timing out if nothing is sent, and sending data in packets with a checksum, a 'finish' packet and also is a protocol you can find in most terminal programs.

    xmodem and ymodem are rather similar (xmodem sends files one at a time, ymodem can do groups of files, xmodem needs the filename set manually, ymodem includes it in the first data block) so if there is already ymodem code out there for the propeller it would make things a lot easier.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    www.smarthome.viviti.com/propeller

    Post Edited (Dr_Acula) : 4/15/2010 5:21:51 AM GMT
  • Cluso99Cluso99 Posts: 18,069
    edited 2010-04-15 08:57
    Sphinx has a PC C program to do simple file transfers. I wanted to redo the spin side to make them seperate Sphinx-aware programs rather than embed the code within Sphinx. The PC side is easy and could also be done in VB.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Links to other interesting threads:

    · Home of the MultiBladeProps: TriBlade,·RamBlade,·SixBlade, website
    · Single Board Computer:·3 Propeller ICs·and a·TriBladeProp board (ZiCog Z80 Emulator)
    · Prop Tools under Development or Completed (Index)
    · Emulators: CPUs Z80 etc; Micros Altair etc;· Terminals·VT100 etc; (Index) ZiCog (Z80) , MoCog (6809)·
    · Prop OS: SphinxOS·, PropDos , PropCmd··· Search the Propeller forums·(uses advanced Google search)
    My cruising website is: ·www.bluemagic.biz·· MultiBlade Props: www.cluso.bluemagic.biz
  • stevenmess2004stevenmess2004 Posts: 1,102
    edited 2010-04-15 13:23
    Dave Hein said...
    One limitation of spin code is that it can only call methods in other objects that are at a higher address. They can never reference an object at a lower address. This is because object offsets must always be positive. They can never be negative. I've tried, and it doesn't work if they're negative. I am guessing that the spin interpreter doesn't mask of the address to 16 bits when adding an offset. Therefore, a negative 16-bit offest will actually produce a 17-bit address when added to a 16-bit address.

    I'm fairly sure that I've called objects that have a lower address in DOL. You may even see this behaviour in standard spin programs because of how the compiler works.

    VAR space is easy, you can get the size required by doing some maths on the object header, have a look at DOL. If you have any questions just ask, I'd write more now but it's past my bedtime and I have to work tomorrow [noparse]:([/noparse]

    Steven
  • Dave HeinDave Hein Posts: 6,347
    edited 2010-04-15 23:24
    Dr_Acula, I'll look into the ymodem object.· It sounds like a good approach for downloading files from the PC to the file system.

    Cluso99, I'll look at the Sphinx PC C program.· That might be a good starting point for what I want to·ultimately do.

    Steven, can you verify whether objects can call other objects at a lower address?· It appears to me that the Prop tool arranges the objects in order so that they can always call objects at a higher address.· As far as I can tell there can never be three objects that reference each other, such as A references B, B reference C and C references A.· There would be no way to order them so they always call a higher address.
  • stevenmess2004stevenmess2004 Posts: 1,102
    edited 2010-04-16 08:23
    I'm probably not going to be able to actually test any code until sometime after the 27th. However think about this arrangement
    MainObject
    |-fsrw
    |-SomeotherObject
    |-fsrw

    In this case SomeOtherObject calls fsrw which has a lower address than SomeOtherObject. I'm also pretty certain that I was also using loading programs with DOL that were then calling DOL again to load other objects.
  • mparkmpark Posts: 1,305
    edited 2010-04-16 08:45
    You'll only get one copy of fsrw. Dave is correct.
  • stevenmess2004stevenmess2004 Posts: 1,102
    edited 2010-04-16 11:45
    Yeah, I just checked on bst and you would only get one copy of fsrw and it would be at the bottom of the tree.

    However, I just checked some of my DOL2 code and I was calling DOL from an object that I loaded during runtime so it is possible to call another object with a lower address.

    Here is the code from the interpreter. I've removed the bits that don't relate to a standard object call and unrolled the loop. How Chip managed to come up with this I don't know...
    '
    ' call obj.sub    11
    '
                            rdbyte  y,pcurr                 'get obj index byte
                            add     pcurr,#1
    
                            shl     y,#2                    'lookup words from table
                            add     y,pbase
                            rdlong  y,y                  
    
                            mov     x,y                     'get low word       x=long[noparse][[/noparse]index*2+objectBase]
                            shr     y,#16                   'get high word     y=long[noparse][[/noparse]index*2+objectBase]>>16
    
            if_c            jmp     #callobj        wz      'obj[noparse][[/noparse]].sub? (z=0)
    
    [b]callobj                 add     pbase,x                 'set relative obj bases  
                            add     vbase,y         wc      '(c=0, z=0 still)[/b]
                                                    
                            'do it all again to get the method
                            rdbyte  y,pcurr                 'get method index byte
                            add     pcurr,#1
    
                            shl     y,#2                    'lookup words from table
                            add     y,pbase
                            rdlong  y,y
    
                            mov     x,y                     'get low word
                            shr     y,#16                   'get high word
    
                            mov     dbase,dcall             'get new dcall
                            rdword  dcall,dcall             'set old dcall
                            wrword  pcurr,dbase             'set return pcurr
                            add     dbase,#2                'set call dbase
    
                           [b] add     dcurr,y                 'set call dcurr[/b]
    
    spcurr  if_nc           mov     pcurr,pbase             'set call pcurr (c=0)
         [b]   if_nc           add     pcurr,x[/b]
    
                            jmp     #loop
    
    



    Okay, the bits I've bolded are where the addition to the object and variable bases occur. In all these cases the two values have been seperated out so overflow from one to the other can't happen. If a two's complement negative number is for the offset in the object table than everything will work as expected and you can call an object lower in memory.

    edit: I had the shift the wrong way in the comments.
  • Dave HeinDave Hein Posts: 6,347
    edited 2010-04-16 13:00
    I was thinking that addresses had to stay within a 16-bit range to address the RAM/ROM.· However, the prop's hardware must ignore the upper 16 bits when addressing memory. An address of $12340100 would access the same location as $00000100.· Clearly, the interpreter is making no effort to clear the upper 16 bits of the address.

    Therefore, negative offsets should work.· For some reason my initial tests failed, but I think I failed to fix up all the offsets in the relocated object.· I'll try it again to see if it works.
  • stevenmess2004stevenmess2004 Posts: 1,102
    edited 2010-04-16 23:07
    Yep, the upper 16 bits gets ignored. At one stage I tried adding the addresses together without separating them into the two parts which caused overflow problems, but when you do separate them you can do whatever you like.
  • Dave HeinDave Hein Posts: 6,347
    edited 2010-04-17 12:04
    Steven,

    I tried the negative offsets again, and I got it to work OK.· This simplyfies things a lot.· I use the same technique that you use in the DOL by allocating a·block of memory and copying the object into the malloc'ed block.· After the app returns I free up the memory block.· I still haven't added a VAR block.· I need to study your solution some more so I fully understand it.

    Thanks for help.

    Dave
Sign In or Register to comment.