Hey guys,

A few days ago I started working on cmdOS as an occasion to train me with ASM. I didn't plan to make it do useful things, it's only a big exercise. But hey, who knows ? Wink

For now, the OS boots up, unlocks RAM, sets up LCD and stuffs, display endless "Hello world !" to the screen and turns off the calc when you press [clear].

I'm quite proud of it though, since I started with nothing done. I wrote myself the text routine (I used KnightOS's font and putSpriteOR routine tho, with the agreement of SirCmpwn), which handles text swap and newline and the routine to copy a buffer to the screen.

Current screenshot :



I'll do a github repository later.
So how much of the code was your own, and how much is based on the KnightOS kernel? What sort of features do you have planned for your OS? Do you imagine that it will stay a purely academic project, or do you see a possibility where it becomes a real OS. I often am skeptical of 3rd-party OS projects, because I feel they won't get any major acceptance without super-solid math support. What are your thoughts on that?
Only the font and the putSpriteOR routine is from KnightOS. The code which sets up the LCD and RAM is by SirCmpwn from his OS_starter_kit, and all the rest is by me.

As I said I don't plan any future for this OS. It's just a training to improve my ASM skills.
Excellent, that's a good answer. Smile I think the obvious follow-up then is what you're hoping to do with your ASM skills in the future. Some programs, utilities, and games for the TI-83+/84+, or for the TI-84+CSE, or both? Anything specific?
Nothing specific in fact, I'll have the ideas when I'll have the knowledges. Maybe this OS will actually become a real one.
matrefeytontias wrote:
Nothing specific in fact, I'll have the ideas when I'll have the knowledges. Maybe this OS will actually become a real one.
I certainly support learning new languages and programming skills just for the sake of learning, and worry about what you'll do with it later. Smile As long as you have the free time to learn, I don't think anyone has regretted learning a new language or API. I'll look forward to updates as you go on this OS and other projects, and please remember to ask us any ASM questions that you get stuck on.
Update !

The command-line now works with functions with no arguments Smile If you can think of a function I can add, tell me.

Functions implemented so far :

  • SHUTDOWN : guess its use
  • CLS : clear the command-line
  • PING : prints "Pong !" Razz
  • VERSION : prints cmdOS's version


If you type an unrecognised command, the parser will just print it back.



Also, I don't show it in the screenie because I thought of it just after uploading the image, but the text wraps when you reach the bottom and the right edge of the screen Smile
Nice update Smile are these commandsatually programs that are run and output this information, or are they hardcoded into the kernel?
For now the commands are hard-coded, but I mainly did that this way to test if the input command worked well. It'll change when I'll add a filesystem Smile
matrefeytontias wrote:
For now the commands are hard-coded, but I mainly did that this way to test if the input command worked well. It'll change when I'll add a filesystem Smile
What sorts of plans have you devised for the filesystem, if any?
For the filesystem, since I don't have a clue on how it works, I'll study Xeda112358's FileSyst source code (with Xeda's agreement) to learm from it Smile
matrefeytontias wrote:
For the filesystem, since I don't have a clue on how it works, I'll study Xeda112358's FileSyst source code (with Xeda's agreement) to learm from it Smile
Well, you can make your own! The major components of a filesystem are the area that stores metadata about files (where they are, how big they are, what they're named) and the extents of the files (their contents). It's up to you to decide how to arrange those, and what extra features you want to stack on top.
Yes, you are totally free to make your own filesystem! If I was going to design my own, I would create lots of levels of indirection through the directory tree. Basically, each individual file handle is a structure (I'll use C here, though you would use equivalent ASM code)

Code:

// A pointer that leads to anywhere on the calculator
struct filesyst_pointer {
  unsigned char page;
  void* location;
}

struct file_handle {
  unsigned char[8] name;
  unsigned char[3] ext;
  // other metadata goes here
  filesyst_pointer contents;
}

The "contents" section is different depending on the file type. A special file extension here (which can't be typed - how about including a newline character in it?) would represent a directory. Its contents would be an array of filesyst_pointers to other file handles, thus creating an n-ary tree structure. Finally, to make it all work, you set up a static area of memory which contains a filesyst_pointer to the root directory.
Hey come on, I don't have the level you're thinking about >_< there are things I can't do, even knowing how. Moreover, I need to get the input working faultlessly (handle backspace, erase the whole line, handles arguments etc) before taking care of the filesystem.
matrefeytontias wrote:
Hey come on, I don't have the level you're thinking about >_< there are things I can't do, even knowing how. Moreover, I need to get the input working faultlessly (handle backspace, erase the whole line, handles arguments etc) before taking care of the filesystem.

True, true, I can understand that. The filesystem I'm proposing would also require some sort of heap allocator. Although, I should say that your issue of having a good input buffer as well as arguments for your commands would be helped by a memory heap. And fortunately for you, I wrote one (also in C, but you can glean the idea):

Code:
// The linked list node structure for keeping track of heap data
// In your case, all of these pointers would be filesyst_pointer structures, NOT actual * pointers.
struct my_heapNode{
   unsigned int size;
   void* position;
   struct my_heapNode* next;
};

typedef unsigned char bool;
#define false 0
#define true 1

// Initializes the memory allocator
void init_my_malloc(int bufferSize);
// Deinitializes the memory allocator
void deinit_my_malloc();
// Allocate size bytes of data, returns pointer to start of data
void* my_malloc(unsigned int size);
// NOT FOR USER CODE: Determines if a heapTreeNode contains enough data
bool isBigEnough(struct my_heapNode* node, unsigned int size);
// NOT FOR USER CODE: Go to the next node in the tree
void shiftToNextNode();
// Frees the pointer back to the memory allocator
void my_free(void* item);

// You would want to create two copies of these variables for the RAM and ARCHIVE sections - one for quick access, the other for the permanent filesystem.
static struct my_heapNode my_heapFront;
static struct my_heapNode* my_currentNode;
// You wouldn't need the next two variables in your case - these were just to make sure it worked
static void* memArea;
static int bufferSize;

void init_my_malloc(int bufferSize)
{
  /* In your case, this would only be called when you reset the OS. If RAM was reset,
  * you would allocate one RAM node for each page of RAM you have access to,
  * in a static portion of RAM you know you have control over.
  * If you reset ARCHIVE, you would reset RAM (creating new RAM areas)
  * and then use that to create ARCHIVE nodes for each page you have access to.
  */
  memArea = malloc(bufferSize);
  my_heapFront.size = bufferSize;
  my_heapFront.position = memArea;
  my_currentNode = &my_heapFront;

  printf("Buffer initialized.\n");
}

void deinit_my_malloc()
{
  // I kept this here for general purposes, but you'd never call this.
  free(memArea);
  printf("Buffer freed.\n");
}

void* my_malloc(unsigned int size)
{
  unsigned int trueSize = size + sizeof(unsigned int);
  struct my_heapNode* start = my_currentNode;
  void* pointer = NULL;
  do
  {
    if (isBigEnough(my_currentNode, trueSize))
    {
      my_currentNode->size -= trueSize;
      pointer = my_currentNode->position + my_currentNode->size;
      (*(unsigned int*)(pointer)) = size;
      if (my_currentNode->size == 0 && my_currentNode != &my_heapFront)
      {
        struct my_heapNode* deadNode = my_currentNode;
        while(my_currentNode->next != deadNode)
          shiftToNextNode();
        my_currentNode->next = my_currentNode->next->next;
        my_free(deadNode);
      }
      return pointer + sizeof(unsigned int);
    }
    else
    {
      shiftToNextNode();
    }
  } while (start != my_currentNode);
  return NULL; // not enough memory, so abort
}

bool isBigEnough(struct my_heapNode* node, unsigned int size)
{
  return (node != NULL && node->size >= size);
}

void shiftToNextNode()
{
  my_currentNode = my_currentNode->next;
  if (my_currentNode == NULL)
    my_currentNode = &my_heapFront;
}

void my_free(void* item)
{
  void* truePosition = item - sizeof(unsigned int);
  unsigned int itemSize = *(unsigned int*)(truePosition);
  unsigned int trueSize = itemSize + sizeof(unsigned int);
  struct my_heapNode* start = my_currentNode;
  do
  {
    if (my_currentNode->position + my_currentNode->size == truePosition)
    {
      my_currentNode->size += trueSize;
      return;
    }
    else if (truePosition + trueSize == my_currentNode->position)
    {
      my_currentNode->position -= trueSize;
      my_currentNode->size += trueSize;
      return;
    }
    else
    {
       shiftToNextNode();
    }
  } while (start != my_currentNode);
  // No adjacent memory areas, so create a new node
  struct my_heapNode* newNode = my_malloc(sizeof(struct my_heapNode));
  newNode->next = my_currentNode->next;
  my_currentNode->next = newNode;
}
Thanks for helping, but I don't quite get it >_< Please note that I have no idea how to allocate memory, nor how it works, nor what it actually means. Sad

EDIT : to sum up I'd say that I'm worse than bad at system programming. When you explain something please do it like you would do if you were talking to someone with no programming experience.
matrefeytontias wrote:
Thanks for helping, but I don't quite get it >_< Please note that I have no idea how to allocate memory, nor how it works, nor what it actually means. Sad

EDIT : to sum up I'd say that I'm worse than bad at system programming. When you explain something please do it like you would do if you were talking to someone with no programming experience.


Some good places to start:

http://en.wikipedia.org/wiki/Memory_management
http://en.wikipedia.org/wiki/Memory_management_(operating_systems)
http://www-ee.eng.hawaii.edu/~tep/EE160/Book/chap14/subsection2.1.1.8.html
http://en.wikipedia.org/wiki/Virtual_memory
http://www.win.tue.nl/~aeb/linux/fs/fat/fat-1.html

A few good preliminary reads that may help you understand things better.
Thanks, I'll read them carefully Smile but does that mean that I'll have to rewrite every single input function to make them work with the new allocated memory instead of using static mem ?

I planned to use static mem for command inputs mainly for a thing : arguments will always be stored at the same location, making them easy to reach for external programs.
matrefeytontias wrote:
Thanks, I'll read them carefully Smile but does that mean that I'll have to rewrite every single input function to make them work with the new allocated memory instead of using static mem ?

I planned to use static mem for command inputs mainly for a thing : arguments will always be stored at the same location, making them easy to reach for external programs.


What type of input functions, the console input ones? And, as for storing "arguments", what type of arguments do you mean, and why would external programs need to reference them? A bit of clarification will give me a better idea of how your kernel currently works Smile
Yeah, I meant the console inputs. And by "arguments", I mean everything that is after the command name. I planned to make every single command of the command line (like shutdown, ping etc) a program which will be ran with or without arguments. For example, the echo command would simply look like this :
Code:
 ld hl,inputBufArgsSec ; arguments are all stored here. The arguments string ends with a '\n',0 because of the way the input works
 call printString
 ret


EDIT : the point of using static memory is, like I said, that you always know where to find your datas, and you don't have to take care of allocating or deallocating it.
  
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
Page 1 of 3
» All times are UTC - 5 Hours
 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

 

Advertisement