Possibly faulty function - get_safety_pool_size

The get_safety_pool_size() function claims to return the size of the maximum memory pool that can be allocated. However, during testing with the Pro Version of the SDK, this call always seems to return 0.

Known Memory Leak

“There are several known memory leaks, but the only one they admitted to was calling exit() from within a C program terminates the thread and leaves the code segment of the running application in memory creating a memory leak of up to 64K” (reported on cydevr.net by Greg Smith)

main.e - what is this file?

According to some notes in the Pro compiler helpfile changelog, main.e is the bytecode interpreter bootstrap code. This file gets included into any applications .app archive. So, now we know. Interesting to note that if the '-g' flag is used on the compiler command line, the archiver includes the main.e from the /debug directory as opposed to the standard one.

Inline assembler

As in gcc, it is possible to 'plant' asssembler inline with the C source code. This also works with the cybiko vcc1 compiler, but is not documented in the Cybiko SDK helpfile. Simply use the construct /asm(“assembler_nmemonic and arguments”)/ This will be included, verbatim, in the assembler file which is emitted by the compiler.

The 'label','bytecode','native' and 'in_line' functions

This is an interesting feature of vcc1. If we insert a line in the C source label(“hello”);, the following is included in the resulting .asm output.

1. a '.extern' declaration of .extern xx “_label@0” - where xx is a unique number

2. the assembler code …

.ln nn 4 - where nn is the line number of the label() call.

 leagu.u xx+1 0; hello
 push
 calln.s xx; label
 stack.c 4

The 'bytecode', 'native' and 'in_line' functions do almost exactly the same, except that the .extern definitions are _bytecode@0 , _native@0 and _in_line@0 respectively. Will have to work out exactly what this is all about, later.

Array of Struct

If you have a function that defines locally a array of structs the compiler seems to code dump on compile. This is not strictly repeatable so there must be some other mitigating circumstance.

 struct _mystruct {
   int a;
   int b;
 };
 
 void func() {
   struct _mystruct hello[10];
 }

Function param same as function decl.

Although this is a coding mistake if you define a function header to use a variable name that is the same as function being invoke the compiler will not emit an error but will instead core dump.

 void world() {
 }
 void hello(int world) {
   world();
 } 
 void main() {
 }

Parse Error

Defining a variable in the middle of a code block is not allowed by the C compiler.

 void hello(int param) {
    int i;
    if (param == 0) return;
    int j;         //<-- This generates an "error - parse error" from the compiler.
 }

Unions

The 3.0.8 compiled is more than happy to compile the following although it will issue a warning about the unsigned as this is not supported until VM16.

 union value_T {
        unsigned int ui;
        int i;
 };
 typedef value_T value_t;

With all compilers after this version they will not support unions directly without error. To work around this you can wrap the union inside a struct, of course you will need to access via u.ui or u.i instead of just i and ui.

 struct int_T {
        union {
                unsigned int ui;
                int i;
              } u;
 };
 typedef struct int_T int_t;

Large Stack

The following legal code causes the assembler problems (at least on my machine) using the Cybiko SDK. The assembler reports that “error - argument 1 not in range -128..127” after the file has been compiled.

 #include "CyWin.h"
 
 long main(int argc, char* argv[], bool start)
 {
 char info[80];
 struct cEdit edit;
 }

I noticed that as well. It is due to the local stack growing too large. To keep this from occuring, you can only have up to 128 bytes of local variable storage.

The work around is to make larger local vars globals instead.

EOF Bug

FileInput_get_flags doesn't appear to work for locating the end of a file. Use Input_get_flags instead.

Bad Code

 value = FileInput_get_flags(&input_file) & FLAG_EOF;

Good Code

 value = Input_get_flags(&input_file) & FLAG_EOF;

Math Bug

Bad Code

 char i;
 i = -i;

Good Code

 char i;
 i = 0-i;

Array Bug

When using arrays, trying to do math in the first parameter will produce bad code but there is no compiler warning.

Bad Code

 int x,y,i;
 i = Test[y/4][x/4];

Good Code

 int x,y,i,ox,oy;
 ox = x/4;
 oy = y/4;
 i = Test[oy][ox];

OR

 int x,y,i,oy;
 oy = y/4;
 i = Test[oy][x/4];

draw_lib Bug

This is the function to use to draw “sprites” to the screen.

If you wish to use the 'BM_FLIP_X' and 'BM_FLIP_Y' attributes (for horizontal &/or vertical flip of your graphic) then make sure that these graphics are in their own file (in the filer.list file). and that no other extremely large graphic is in the same file. A large graphic in the same file will cause the FLIPs to not work. The result will be nothing drawn.

Return from main Bug

Sometimes when exiting a program on the Cybiko, it will unexpectedly lock up. It doesn't always happen so, what other circumstances contribute to this are unknown. But it can suddenly make working code go bad. The cure is you must have a return command and it must be a long. If you use a constant you must force a long type to the return.

return 0L;

I've never had a lockup using this and all Cybiko SDK code does this making it seem like they knew about it but never got around to fixing it.