I know that most of the commonly used functions that you would use in C for the TI 84 Plus CE are in the ce toolchain, but how would you use an OS romcall in the middle of a C program? One example would be:

Code:

_RunIndicOff               equ 0020848h

Thank you in advance!
You can use inline ASM to do this. Or, make a separate assembly file and define the function there, and then just call it as normal.

EDIT: There’s a built in function, os_RunIndicOff, that would probably be the best solution (look at the documentation for more details).
If you needed to use a particular calling convention, inline assembly as understood by Clang (and GCC, since Clang is mostly compatible with GCC) is powerful enough to let you do that. It's useful to be somewhat aware of, even if it's not necessary here.

You should read the GCC documentation on the features for all the details, but in short:

Code:
__asm__(instructions
       : outputs
       : inputs
       : clobbers);

You can write regular old instructions with a little bit of templating, and the other parameters allow you to tell the compiler what values the assembly consumes or generates, as well as the registers that it modifies.

For instance, the x86_64 ABI for syscalls on Linux passes the syscall number in rax, then parameters in other registers in a particular order; the first two are in rdi and rsi. The syscall result is returned in rax and the syscall will modify the values of rcx, r11 and may also modify memory. So this function implements that ABI for a two-argument syscall:

Code:
uint64_t syscall2(uint64_t nr, uint64_t param1, uint64_t param2) {
    uint64_t result;
    __asm__("syscall"
           : "={rax}"(result)
           : "{rax}"(nr), "{rdi}"(a1), "{rsi}"(a2)
           : "rcx", "r11", "memory"
    );
    return result;
}

While in this example fixed registers are chosen for the input/output constraints, you can also specify other values that allow the compiler to select a register for you, which may allow it to generate better code. For instance, adding two 8-bit values on Z80 (note that I haven't tested this and I'm not certain how the Z80 target's constraints are actually defined; this may not be totally correct):

Code:
uint8_t add8(uint8_t x, uint8_t y) {
    __asm__("add a,%1"
           : "+{a}"(x)
           : "r"(y)
    );
    return x;
}

In this example we've used +{a} to tell the compiler that x is both an input and output value, and constrained it to the a register because add requires that one operand of addition be in that register. The other operand is constrained to simply be in some register, and is referred to as %1 because it is the second value listed among inputs and outputs (it's zero-indexed).


Concretely, while your specific example of RunIndicOff is best done with the provided bindings, it could be implemented easily as inline assembly because it doesn't take any parameters, nor does it return anything.

Code:
__asm__ volatile("call 020848h");

This may not entirely be sufficient, since it doesn't tell the compiler that memory is modified; you could add a memory clobber to be very generic, or a more specific one that refers to the flag byte that gets modified. The volatile ensures the compiler doesn't remove this code, which it would otherwise be free to do because it doesn't seem to have any side effects: it doesn't return any value, so it seems safe to omit because nothing visibly uses (or indeed, can use) its result.

It's also important to note that the romcall assumes that IY points to the flags (so you may need to ensure it's set), whereas os_RunIndicOff will ensure that invariant is upheld for you.
Yep, the syntax for the llvm toolchain looks like this

Code:
asm volatile("call 020848h" :: "y"(os_Flags) : "cc", "memory");

but note that the current toolchain release requires using "yl" instead of "y".

Of course os_RunIndicOff(); exists for a reason so you don't have to worry about all this.
how would you delete 1 byte from anywhere in an appvar in C?
randomguy wrote:
how would you delete 1 byte from anywhere in an appvar in C?

Generally you don't want to do this. You should write to appvars in blocks. Otherwise you will have to continuously resize and move the data around in the appvar much like you would have to do with a normal array.
so what would the most efficient bullet routine be when using a list in ice? i have one working, but it is kind of a waste of ~100 bytes. what i want to do is have a list from which i can delete and add bullet coordinates.
randomguy wrote:
so what would the most efficient bullet routine be when using a list in ice? i have one working, but it is kind of a waste of ~100 bytes. what i want to do is have a list from which i can delete and add bullet coordinates.

Why are you asking about ICE now. Unless you want to bash your brain in; don't
I still am using Ice although I am learning C, because I want to learn about making tile maps and getting better at programming on my calculator. and it doesn't matter what programming language the bullets are in (either ice or basic) because all i need to know is an efficient bullet routine with lists because there aren't any .pop or .push functions in either language.
Don't freaking use ICE tilemaps. They are not integrated as well as they are in C and will just confuse you.
ok. i guess i will just learn C. but how would you add and delete bullets in a list in ice most efficiently?
Unless you absolutely must preserve the order of the list, when you delete an entry, rather than sliding every entry that was past it up by one to fill the hole, move the last entry into the hole.

And add entries to the end to avoid having to slide entries after it down by one.
  
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 1
» 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