Let's say one was using the following code to get the key value.

Code:
while (iContinue) {
      Bdisp_AllCr_VRAM();   
      GetKey(&key);
      switch (key) {
             // Key statements
      }
   }


How would one use this to index an array, say:

Code:
char* string = "Hello WorldABCDEFGHIJKLMNOPQRTSUV";


Also, how can you get the intermediate Assembly output of the compiler?
what's wrong with
Code:
string[key]
??


To answer your second question, many cc's take the -S option to output an assembly file instead of an object file or executable.
Thanks.

Is there some way to call arbitrary syscalls?

For example, the following code would presumably call syscall 0x0C01 with the single argument msgno:


Code:
int syscall = 0x0C01;
int args = 1;
int msgno = 1;
void syscall( syscall, args, msgno);
Best to add it to libfxcg, which is pretty easy, and gets them out there for others to use:

Code:
#include "asm.h"
SYSCALL(name, address)


To get your changes included in the official repo, you can fork then request a pull. That or just ask Jonimus to include your changes.

It would be possible to do it outside the library and purely in your own code, but you lose efficiency compared to including it in libfxcg, as well as some dirty tricks to make the compiler pretend some generic syscall function may take any arguments (I'm thinking weird function casts). It's strange enough that I can't be bothered to come up with an example of it, so just modify libfxcg.
My best idea would to use a #define statement and them have asm code in there, but I'm not entirely sure how to handle all the arguments. The other possibility is to use a function pointer to call an address. And I wouldn't worry to much about efficiency because I assume your only using this for testing and will add these syscalls once they're found and documented.

I'm working on some code, but I now see it's impossible to do this without asm and even with it is very long and obfuscated. I'll get that out once finished.

btw does anyone have the syntax for how gcc includes asm code in C files.
z80man, you put your ASM code in a .s file, then just glom it together in your compile line, eg.:

gcc -o outputfile inputfile.c blah.o other.o stuff.s
That's one way to do it, anyway. You also need to have a header file somewhere providing the prototype for whatever functions you define in stuff.s there.

Alternatively, you can inline it, but that gets rather messy with longer routines:

Code:

// x86 example, but gets the point across
void clearYMMs() {
    asm("\tvzeroall");
}
I know with x86 gcc when using inline asm you can specify registers and memory used to help the compiler make optimizations. I wonder if the SuperH version has this
How does one print a number (preferably in hex?)
I think this routine should do the trick. Also not too hard to convert to asm if you wish. Actually I probably would've written it faster if it was in asm Wink

To use it just pass an int argument and it returns a pointer to a string of ascii hex that you can print with, void PrintXY( int x, int y, char*msg, int mode, int color)


Code:

char* integer_to_hex(int integer)
{
   const char hex[]= "0123456789abcdef";
   char result[]= "00000000";
   int temp;
   char ctemp;
   for(int index = 0; index < 8; index++)
   {
      temp = (integer & (0xf0000000 >> index << 2)) >> 28-(index <<2);
      ctemp = hex[temp];
      result[index] = ctemp;
   }
   return result;
}
z80man wrote:
I know with x86 gcc when using inline asm you can specify registers and memory used to help the compiler make optimizations. I wonder if the SuperH version has this

Yes, all targets for gcc have that, since it's still gcc.


Code:
asm ( assembler template
    : output operands                  /* optional */
    : input operands                   /* optional */
    : list of clobbered registers      /* optional */
    );

Detailed HOWTO.
There are some syscalls that convert to hex as well iirc. but if we get newlib built you can just use snprintf and then print it with printxy
This has been really annoying, but for some reason division bugs out.

Basically, the code in main declares the variables (i is X, j is y, k is z) and attempts a simple "projection" onto the screen using the z coordinate. For some reason, this causes a bunch of different glitches. For one thing, on every other button press, the line disappears. Press a valid button again and the line will come back. Another thing is that changing the value of k sends the endpoints of the line way off into infinity. If you change the value back, then the line is stuck in that portion of the screen until you clear the program. However, commenting out the division makes the whole thing work properly again, so project_x and project_y are definitely the problem. Is division just not defined?


Code:
#include <display.h>
#include <keyboard_syscalls.h>
#include <SYSTEM_syscalls.h>
#include <keyboard.hpp>
#include <display_syscalls.h>
//

//draws a point of color color at (x0, y0)
void plot(int x0, int y0, int color) {
   char* VRAM = (char*)0xA8000000;
   VRAM += 2*(y0*LCD_WIDTH_PX + x0);
   *(VRAM++) = (color&0x0000FF00)>>8;
   *(VRAM++) = (color&0x000000FF);
   return;
}


//Uses the Bresenham line algorithm
void drawLine(int x1, int y1, int x2, int y2, int color) {
    signed char ix;
    signed char iy;
 
    // if x1 == x2 or y1 == y2, then it does not matter what we set here
    int delta_x = (x2 > x1?(ix = 1, x2 - x1):(ix = -1, x1 - x2)) << 1;
    int delta_y = (y2 > y1?(iy = 1, y2 - y1):(iy = -1, y1 - y2)) << 1;
 
   plot(x1, y1, color); 
    if (delta_x >= delta_y) {
        int error = delta_y - (delta_x >> 1);        // error may go below zero
        while (x1 != x2) {
            if (error >= 0) {
                if (error || (ix > 0)) {
                    y1 += iy;
                    error -= delta_x;
                }                           // else do nothing
         }                              // else do nothing
            x1 += ix;
            error += delta_y;
            plot(x1, y1, color);
        }
    } else {
        int error = delta_x - (delta_y >> 1);      // error may go below zero
        while (y1 != y2) {
            if (error >= 0) {
                if (error || (iy > 0)) {
                    x1 += ix;
                    error -= delta_y;
                }                           // else do nothing
            }                              // else do nothing
            y1 += iy;
            error += delta_x; 
            plot(x1, y1, color);
        }
    }
}

int project_x(int i0,int j0, int k0) {
   return i0/k0;
}

int project_y(int i4,int j4,int k4) {
   return (-j4)/k4;
}
   




int main(void) {
   int x = 1;
   int y = 1;
   int key;
   int color = 0x000000FF;
   int mode = 0;
   int iContinue = 1;
   
   
   int i1 = 1;
   int i2 = 50;
   int i3 = 60;
   
   int j1 = 1;
   int j2 = 50;
   int j3 = 60;
   
   int k1 = 0;
   int k2 = 1;
   int k3 = 1;
   
   int xRadius = 20;
   int yRadius = 10;

   char* array = "--- ";
   array[1] = 0xE5;
   array[2] = 0xE2;
   array[3] = 0xE3;
   int background = 0x01;

   while (iContinue) {
      Bdisp_AllCr_VRAM();   
     i2 = project_x(i2,j2,k2);
     j2 = project_y(i2,j2,k2);
     i3 = project_x(i3,j3,k3);
     j3 = project_y(i3,j3,k3);
     drawLine(i2, j2, i3, j3, color);
     Bdisp_PutDisp_DD();
     GetKey(&key);
      switch (key) {
         case KEY_CTRL_EXIT:
            iContinue = 0;
            break;
         case KEY_CTRL_UP:
            j2 = j2 == 1 ? 8 : j2-1;
            break;
         case KEY_CTRL_DOWN:
            j2 = j2 == 8 ? 1 : j2+1;
            break;
         case KEY_CTRL_LEFT:
            i2 = i2 == 0 ? 21 : i2-1;
            break;
         case KEY_CTRL_RIGHT:
            i2 = i2 == 21 ? i2=1 : i2+1;
            break;
         case KEY_CHAR_PLUS:
            k2 = k2 == 7 ? 0 : k2+1;
            break;
         case KEY_CHAR_MINUS:
            if (k2>0) {
         k2 = k2 == 0 ? 7 : k2-1;
         }
            break;
         case KEY_CHAR_8:
            j3 = j3 == 1 ? 8 : j3-1;
            break;
         case KEY_CHAR_2:
            j3 = j3 == 8 ? 1 : j3+1;
            break;
         case KEY_CHAR_4:
            i3 = i3 == 0 ? 21 : i3-1;
            break;
         case KEY_CHAR_6:
            i3 = i3 == 21 ? i3=1 : i3+1;
            break;
         case KEY_CHAR_0:
            k3 = k3 == 7 ? 0 : k3+1;
            break;
         case KEY_CHAR_EXP:
         if (k3>0) {
            k3 = k3 == 0 ? 7 : k3-1;
         }
            break;
      }
   }

   return 0;

}
Divison is absolutely defined, but why are you using signed chars instead of signed ints? You gain absolutely no speed benefits from that, and in fact a speed penalty, from what I've heard. I'd be happy to share the line function from Prizm Obliterate in the Useful Routines topic if I haven't already done so.
z80man wrote:
I think this routine should do the trick. Also not too hard to convert to asm if you wish. Actually I probably would've written it faster if it was in asm Wink

To use it just pass an int argument and it returns a pointer to a string of ascii hex that you can print with, void PrintXY( int x, int y, char*msg, int mode, int color)


Code:

char* integer_to_hex(int integer)
{
   const char hex[]= "0123456789abcdef";
   char result[]= "00000000";
   int temp;
   char ctemp;
   for(int index = 0; index < 8; index++)
   {
      temp = (integer & (0xf0000000 >> index << 2)) >> 28-(index <<2);
      ctemp = hex[temp];
      result[index] = ctemp;
   }
   return result;
}


That doesn't work - you can't return something created on the stack (well, you CAN, but it absolutely won't work correctly). Also, snprintf would work as well. C's library is small enough as it is, no reason to poorly re-invent what actually is there. Wink
Kllrnohj wrote:
That doesn't work - you can't return something created on the stack (well, you CAN, but it absolutely won't work correctly). Also, snprintf would work as well. C's library is small enough as it is, no reason to poorly re-invent what actually is there. Wink


Sometimes it actually will appear to work, but only just long enough to lull you into a false sense of complacency.
Qwerty.55 wrote:
Is division just not defined?


Rule of thumb, *ALWAYS* assume it is your code that is wrong. Extremely rarely is the library/compiler wrong for standard/widely used libraries and compilers.

Quote:

Code:
//draws a point of color color at (x0, y0)
void plot(int x0, int y0, int color) {
   char* VRAM = (char*)0xA8000000;
   VRAM += 2*(y0*LCD_WIDTH_PX + x0);
   *(VRAM++) = (color&0x0000FF00)>>8;
   *(VRAM++) = (color&0x000000FF);
   return;
}


VRAM should really be a global constant or define. Also, not sure if this matters for Prizm or not, but VRAM should have the "volatile" keyword (so "volatile char* VRAM")

Quote:

Code:
char* array = "--- ";
   array[1] = 0xE5;
   array[2] = 0xE2;
   array[3] = 0xE3;


Uh, what are you trying to do here?

If you just want an array of bytes and not necessarily a string, consider using something like this instead:

Code:
unsigned char array[] = {0xE5, 0xE2, 0xE3}


Also, arrays are index from 0, not sure if you realize that (not that you even use array anywhere, so you should probably just delete that block)
KermMartian wrote:
Divison is absolutely defined, but why are you using signed chars instead of signed ints? You gain absolutely no speed benefits from that, and in fact a speed penalty, from what I've heard. I'd be happy to share the line function from Prizm Obliterate in the Useful Routines topic if I haven't already done so.


The line algorithm is copied and pasted directly from your post in the useful routines thread Razz

Quote:
Also, snprintf would work as well. C's library is small enough as it is, no reason to poorly re-invent what actually is there.


snprintf isn't defined in the current libraries, which is precisely why I was asking.


Code:
Rule of thumb, *ALWAYS* assume it is your code that is wrong. Extremely rarely is the library/compiler wrong for standard/widely used libraries and compilers.


Normally I do, except that there are so many bugs that don't seem to be even faintly related to the division that I couldn't figure out any other explanation. Add the fact that the libraries for the Prizm are... "limited" and you can see why I might ask after a few hours of puzzlement.


Quote:
Also, arrays are index from 0, not sure if you realize that (not that you even use array anywhere, so you should probably just delete that block)


I was using the array for something earlier and I forgot to remove it. Also, I'm quite aware of 0 indexing Wink
Kllrnohj wrote:

That doesn't work - you can't return something created on the stack (well, you CAN, but it absolutely won't work correctly). Also, snprintf would work as well. C's library is small enough as it is, no reason to poorly re-invent what actually is there. Wink
I think I meant there to return only a pointer not the entire array. Or if I'm wrong it should be marked as static. And what printxy() is, is a Prizm-OS syscall. There is no snprintf() yet and if there was it would have to contain printxy() unless a new text routine was created which is unlikely.
You mean printf(). Sprintf() and snprintf() copy the formatted text into a string instead of printing it to the screen, and therefore could be used independent of the display method.
  
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