Author Topic: Timekeeping  (Read 4725 times)

0 Members and 1 Guest are viewing this topic.

Offline Terrav

  • LV1 Newcomer (Next: 20)
  • *
  • Posts: 7
  • Rating: +0/-0
    • View Profile
Timekeeping
« on: January 26, 2021, 06:40:45 pm »
I recently finished making a Minesweeper program for MirageOS and I was wondering how I could keep track of time. I know there must be some sort of hardware clock; how do I use it? Or at least is there an assembly routine that will allow me to read it?

Offline E37

  • LV6 Super Member (Next: 500)
  • ******
  • Posts: 358
  • Rating: +23/-0
  • Trial and error is the best teacher
    • View Profile
Re: Timekeeping
« Reply #1 on: January 29, 2021, 02:30:47 pm »
Here is an axiom that I wrote a while ago to deal with 4 byte numbers and timekeeping. It uses the system clock so it is accurate to the second. If you need fractions of a second, you will have to use interrupts.

Commands:
All commands are located under Vars->Window->T/Theta or U/V/W

Time:
ClkOn //Starts the system clock if it isn't running already.
ClkOff //Stops the system clock and sets it to 0. If you want to zero the clock, just turn it off and back on. Note that this resets the user's on-calc clock as well. Not that anyone really cares...
GetTime(oPtr) //Sets the 4 bytes pointed to to the current time in seconds. If you are expecting time to be less than 16 hours, you can just read the first two bytes of that. For example you can do GetTime(oA) and then just read A to get the time passed in seconds. (Although doing so will modify B as well)

4 byte math:
Although you didn't ask for this, Ill document it anyway since there is a lot of 4 byte math commands in the axiom.
All commands return their first argument.

Add(oPtr1, oPtr2) //Adds the number pointed to by oPtr2 to oPtr1. oPtr2 is unchanged. Like all 4 byte commands, this returns the first argument, oPtr1.
Add(oPtr1) //Increments the 4 byte value pointed to.
Sub(oPtr1, oPtr2) //The same as Add( but subtracts the numbers instead. oPtr2 is unchanged.
Sub(oPtr1, oPtr2)r //Returns the sign of the subtraction operation. Basically it returns 1 if the value pointed to by oPtr1 is greater than oPtr2, 0 if they are equal and -1 (65536) if oPtr2 is greater. The contents of oPtr1 and oPtr2 are unchanged
Sub(oPtr1) //Decrements the value pointed to.
Ld(oPtr1, oPtr2) //Sets the value pointed to by oPtr1 to the value pointed to byo Ptr2. Basically {oPtr2}r->{oPtr1}r:{oPtr2+2}r->{oPtr1+2}r
Ld(oPtr1, low, high) //Loads the value of low, high into oPtr1. Basically low->{oPtr1}r:high->{oPtr1+2}r
Ld(low, high)r //Loads the value of low, high into a temporary spot and returns the pointer to it. Useful if you want to do a constant operation (like adding 285 to a number) but don't want to have a dedicated scrap area of memory for it. There can only be one at a time so make sure you aren't using the value of the last one before using another.
Ld(oPtr1)r //Sets the 4 byte value pointed to by Ptr1 to 0
Mul2(oPtr1) //Multiplies the value pointed to by oPtr1 by 2. Like all 4 byte commands, it returns a pointer to its first argument, oPtr1. This means that doing Mul2(Mul2(oPtr1)) is a good way of multiplying by 4
Div2(oPtr1) //Works the same way as Mul2 but divides by 2 instead.
Mul(oPtr1, oPtr2) //Multiplies oPtr1 by oPtr2. Unlike other commands, this modifies oPtr2. You have been warned.
Div(oPtr1, oPtr2) //Divides oPtr1 by oPtr2. Unlike other commands, this modifies oPtr2.
Div()r //Returns the pointer to the remainder of the last Div(oPtr1, oPtr2) operation.
_min(oPtr1, oPtr2) //Returns the pointer to the smaller of oPtr1 and oPtr2. This leaves both oPtr1 and oPtr2 unchanged. (but the result returned will be either oPtr1 or oPtr2)
_max(oPtr1, oPtr2) //Returns the pointer to the larger of oPtr1 and oPtr2.


If you need a routine to display 4 byte values, I can share my text axiom.
I'm still around... kind of.

Offline Terrav

  • LV1 Newcomer (Next: 20)
  • *
  • Posts: 7
  • Rating: +0/-0
    • View Profile
Re: Timekeeping
« Reply #2 on: January 29, 2021, 03:35:42 pm »
Thanks! It would also be great if I could use your text axiom as well; I've been trying to make my own but it is turning out to be horribly inefficient.

Offline E37

  • LV6 Super Member (Next: 500)
  • ******
  • Posts: 358
  • Rating: +23/-0
  • Trial and error is the best teacher
    • View Profile
Re: Timekeeping
« Reply #3 on: January 29, 2021, 04:19:16 pm »
Here's my text axiom:
All commands located under Matrix (2nd->math)
All the text drawing commands use small font and are unaffected by modes like Fix 5. It does use the built in pen for text locations so commands like Axe's built in Text(x, y) would affect text drawn from the axiom. All commands are just as fast as Axe's or faster. This is because a lot of Axe's text stuff is calls to the operating system which is slow but very size-efficient. Drawing text with this axiom is about 2x faster than using Axe's built in text routines. Thanks Zeda for for optimization help!

Text drawing commands:
Since this is an axiom, I can't take a variable number of arguments for the text like Axe does. You will just have to call text( multiple times if you want to draw multiple strings.
text(x, y, string) //Moves the pen to x, y and draws the text to the main buffer.
text(x, y, string, buffer) //Same as text(x, y, string) but it draws to the specified buffer. Putting L6 in for the buffer would make it identical to text(x, y, string)
text(string) //Draws the string to the main buffer at the pen's current location.
text(string, buffer) //Draws the string to the specified buffer at the pen's current location.

Conversion functions. Most of these just take a value and turn it into a string to be displayed. Several are redundant from Axe but I needed to make copies because Axe's are locked into their functions.
VALUE>char //converts the value (0-255) into a character and returns a pointer to the string. Not terribly useful.
VALUE>dec //converts the value (0-65536) into a string. Works like Axe's >Dec function but is faster. It also gives a string which means it can be used in place of Axe's >dec function. It also doesn't have the weird spaces padding it to 5 characters long.
VALUE>decr //Converts the binary value (0-255) to a string of 1's and 0's.
POINTER>decrr //Converts the 4 byte value pointed into a string. Basically its >Dec but for 4 byte numbers. Note that it wants a pointer!
POINTER>tok //Gets the string for the token pointed to. Note that this is a pointer. Similar to Axe's >Tok
POINTER>tokr //Returns 1 if the value pointed to is a 2-byte token or 0 otherwise.
If you want to display hex values, just use Axe's built int >Hex. It returns a pointer so it works with all the text( commands.
I'm still around... kind of.