Optimizer corrupts prog.

TI-82, TI-83 (plus, silver..), TI-84, TI-85 and TI-86
Post Reply
cjgone
Member
Posts: 15
Joined: Wed Dec 26, 2007 11:41 pm

Optimizer corrupts prog.

Post by cjgone »

When I use the optimizer, it corrupts my program... I'm not sure, why but is it possible to specify a block of code not to be optimized?

The header gets screwed up.
alvin
Well known member
Posts: 1872
Joined: Mon Jul 16, 2007 7:39 pm

Post by alvin »

cjgone wrote:When I use the optimizer, it corrupts my program... I'm not sure, why but is it possible to specify a block of code not to be optimized?
The header gets screwed up.
Is the optimizer making an error or is it that a header becomes invalid because the instructions are changed? I just want to make it clear :) If the former I wouldn't mind seeing a code fragment so we can chase down the problem...

Anyway I am fairly sure the answer is no, it is not possible to exempt a specific block of code from the optimizer. The optimizer is invoked after the compiler on an entire file and I do not believe the optimizer has any options for excluding a block from being analyzed... perhaps dom or stef will confirm this.

But I can think of a few things you can do about this.

1. If the specific code fragment is small, hand assemble it and insert it as raw bytes into the code.

Code: Select all

THIS:

#asm
ld hl,10
add hl,de

;; copt: don't touch this
sla c
rl b
adc hl,hl
;; end don't touch this

call function
#endasm

BECOMES:

#asm
ld hl,10
add hl,de

;; copt: don't touch this
;;sla c
defb 203, 33
;;rl b
defb 203, 16
;;adc hl,hl
defb 237, 106
;; end don't touch this

call function
#endasm
2. Compile with optimization turned off. This might be helpful to see if the optimizer is actually causing the problem, however you probably won't want to do this for the final product.

zcc +zx -O0 .... (optimization level 0 means no optimization)
http://www.z88dk.org/wiki/doku.php/zcc

3. Because the optimizer works on individual files, separate code you don't want optimized into its own file. Then compile that file separately with optimization turned off and link the already assembled output file with the rest of the c program.

Code: Select all

zcc  -c -O0 opt_off_please.c                          // compile individual file with optimization turned off
zcc +zx myprog.c opt_off_please.o -lndos ....           // compile main c file and link with already assembled opt_off file
cjgone
Member
Posts: 15
Joined: Wed Dec 26, 2007 11:41 pm

Post by cjgone »

Code: Select all

Label7:
     im   2      ; i don't know why the program is put into interrupt mode 2 in the start.  
     call Label10  ;main
I'm having a look at this now but to answer this question: if you use graphics the crt0 will create an im2 routine so that it can swap between two display images at the right time to simulate gray-scale graphics. If you do not use graphics (which is your case as I've been tracing through the crt0 code) an im2 routine is still installed. The reason is that the z88dk libraries make extensive use of the EXX registers but the standard TI interrupt does not preserve those registers. So the standard interrupt has to be replaced in order to make sure those registers do get saved, hence the im2.

EDIT: This is actually alvin saying the above.. I accidentally edited cygone's post.. Sorry!
Last edited by cjgone on Tue Mar 11, 2008 12:22 am, edited 1 time in total.
alvin
Well known member
Posts: 1872
Joined: Mon Jul 16, 2007 7:39 pm

Post by alvin »

Wow sorry cygone, I didn't realize I could edit other people's posts but it looks like I hit edit instead of quote and actually edited your post instead of quoting it.
Nevermind, still looking into that optimizer thing now.
alvin
Well known member
Posts: 1872
Joined: Mon Jul 16, 2007 7:39 pm

Post by alvin »

I'm compiling a simple test program:

Code: Select all

#include <stdio.h>

main()
{
   printf("Hello World!\n");
}
using:

zcc +ti8x -startup=10 test.c -o test.bin -lndos -Ca-l -notemp

with the last two options there to get crt0.lst which lists how the startup code should look like.

I compared the binary generated with crt0.lst and they looked identical to me. I don't see any messing with the header by the optimizer?

Compare the binary you have on your pc with the bytes received by the calculator.. maybe there's something going awry there?
cjgone
Member
Posts: 15
Joined: Wed Dec 26, 2007 11:41 pm

Post by cjgone »

I'm using external, (non library) graphic functions :P.

I used an on calc dissassembler, and it shows the same as the calc one.

I'm not sure though, that if I do -O0, it gives the same optimization as -O2 and it only works in one specific place: after zcc. Anywhere else i put it, it doesn't do anything.

But, when i print the asm, it says: "file.opt" which supposedly means optimized, but i get it when i use no optimization. :S
cjgone
Member
Posts: 15
Joined: Wed Dec 26, 2007 11:41 pm

Post by cjgone »

Lol, i'm comepletely free source so:
(compiled like:

zcc +ti8xansi -startup=1 -o shooter.bin shooter.c // no optimization and it works
then devpac8x on the shooter.bin binary. :o
( 6k, atm, but i'm adding more code, so it will over reach the limit sometime soon.)

Its a unexciting lil' arcade shooter with little functionality atm :D

Code: Select all

/*
Spaceship shooter
by: cjgone(2)
*/
// THIS PROGRAM IS FREE SOURCE
//Feel free to modifiy, but removing my name from the code or claiming it as your own is prohibited.
void CreateNewBullet(unsigned struct Bullet * CurBullet, unsigned char xx, unsigned char yy, unsigned char pwr );
void HandleBullets( unsigned struct Bullet * BulPtr,unsigned struct Enemy * ex_ptr, unsigned struct PowerUp * pwrx);
void putspriteXOR(  unsigned char x , unsigned char height,unsigned char y ,unsigned char *sprite);
unsigned char chkkey(void);
void ClrScreen(void);
void fastcopy(void);
void Intialize_Enemies( unsigned char * enemyptr, unsigned struct Enemies * enemyx );
void ResetBullets( unsigned struct Bullet * ptrb, unsigned struct Bullet * e_ptr, unsigned struct PowerUp * Powerz );
void Move_Enemies( unsigned struct Enemy * e_ptr,unsigned struct Bullet * Eb_ptr, unsigned char inc_counter );
unsigned char ChkGameOver( unsigned struct Enemy * e_ptr);
void Drw_Explosion( unsigned struct Enemy * e_ptr );
unsigned char Handle_EnemyBullets( unsigned struct Bullet * eb_ptr, unsigned char xcor, unsigned char ycor, unsigned char invincible );
unsigned char Random( void );
void CreateNewPowerUp(unsigned struct PowerUp * pwr, unsigned char xx, unsigned char yy, unsigned char newpowerx );
unsigned char Handle_PowerUps( unsigned struct PowerUp * pwrx, unsigned char xcor, unsigned char ycor );
#define LEFT   8
#define RIGHT  9
#define UP    11
#define DOWN  10
#define SECOND 20
#define END 25
#define e_num 5
#define NUM_BULLETS 32
#define GAMEOVER 1
#define DEAD 1
unsigned char EnemyTemplate[10] = { 4,0,16,0,28,0,40,0,52,0 };  // xcor,ycor for enemies
//unsigned char movetablex[64] = { 1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1  };
/*
pictures
*/
unsigned char ship[4]= { 24, 36, 66, 255 }; 
unsigned char shot[4] = { 24,36,36,24 };
unsigned char enemypic[4] = { 255, 66, 36, 24 };
unsigned char Explosion_Pic[8] = {85,170,85,170,85,170,85,170};
unsigned char blank[4] = { 0,0,0,0 };
unsigned char PowerUp1[4] = { 255, 153, 153, 255 };
unsigned char PowerUp2[4] = { 255, 128, 128, 255 };
/*
Pcture:
{ 00011000, 00100100, 01000010, 11111111 };
*/
unsigned struct Enemy
{
        unsigned char statusx;  // 1 or 0 depending on if it exists or not
        unsigned char xcor;
        unsigned char ycor;
        unsigned char path;
        unsigned char count;
};
unsigned struct Bullet
{
        unsigned char status; // 1 or 0
        unsigned char xcor2;
        unsigned char ycor2;
};
unsigned struct PowerUp
{
        unsigned char status;
        unsigned char power;
        unsigned char xcor;
        unsigned char ycor;
};
main()
{

/*
Your spaceship
*/
        unsigned char xc = 48;
        unsigned char yc = 60;
        unsigned struct Bullet Bullets[32];
        unsigned char ptr = 0;
        unsigned char inc_counter = 0;
        unsigned char chk;
        unsigned char lives = 5;
        unsigned char life_count = 0;
        unsigned char fx_count = 0;
        unsigned char ptype = 0;
        unsigned char t_ptype= 0;
/*
Enemy Decloration
*/
        unsigned struct Enemy Enemies[10];
        unsigned struct Bullet Ebullets[20];
        unsigned struct PowerUp PowerUps[10];
/*
Other Variables
*/
        unsigned char curkey;        
        unsigned char counter = 0;
        unsigned char counterx = 0;
        unsigned char gamestatus = 0;
/*
Initialization
*/

        ClrScreen();

        
        Intialize_Enemies( EnemyTemplate , &Enemies[0] );
        ResetBullets( &Bullets[0], &Ebullets[0], &PowerUps[0] );
        putspriteXOR(  xc , 4, yc , ship); // put sprite XOR is just a routine that inverts the screen where the picture is drawn, so if you draw twice, it'll re invert the screen
        //back to normal
        fastcopy();
        //Ebullets.status = 1;
        //Ebullets.xcor2 = 10;
        //Ebullets.ycor2 = 2;
        //putspriteXOR(Ebullets.xcor2, 4, Ebullets.ycor2, shot );
/*
Main code
*/
        while(1)
        {
                curkey = chkkey();
/*
Key Presses
*/
                if ( curkey == LEFT && xc != 0)
                {                
                                if (life_count == 0 || life_count & 1)
                                {
                                        putspriteXOR(  xc , 4, yc , ship); // delete
                                        xc--;
                                        putspriteXOR(  xc , 4, yc , ship); // draw
                                }
                                else
                                {
                                        xc--; //invincible mode, where it is drawing itself
                                }
                }
                if ( curkey == RIGHT && xc !=88)
                {
                        if ( life_count == 0 || life_count & 1)
                        {        
                                putspriteXOR(  xc , 4, yc , ship);
                                xc++;
                                putspriteXOR(  xc , 4, yc , ship);
                        }
                        else
                        {
                                xc++;
                        }
                }
                if ( curkey == END || chk == DEAD )
                {
                        break;
                }
                if ( ChkGameOver( &Enemies[0] ) )
                {
                        Intialize_Enemies( EnemyTemplate , &Enemies[0] );
                        fx_count = 0;
                }
                        
                if ( counterx == 14 )
                {
                        if ( curkey == SECOND )
                        {
                                CreateNewBullet( &Bullets[0], xc, yc, ptype );
                        }
                }

                        if ( life_count != 0)
                        {
                                putspriteXOR(  xc , 4, yc , ship);
                                life_count = (life_count + 1) % 251;

                        }
                if ( counter == 1)
                {
/*
Handle Enemies
*/
                        Drw_Explosion( &Enemies[0] );
                        Move_Enemies( &Enemies[0], &Ebullets[0], fx_count );
                        if ( Enemies[0].ycor == 25 )
                                fx_count = (fx_count+1) % 64;
                        HandleBullets( &Bullets[0], &Enemies[0], &PowerUps[0] );
                        t_ptype = Handle_PowerUps( &PowerUps[0], xc, yc );
                        if ( t_ptype != 0 )
                                ptype = t_ptype;

                        if ( Handle_EnemyBullets( &Ebullets[0], xc, yc, life_count ) ) // IF true, you lose a life
                        {
                                lives--;
                                if ( lives== 0 )
                                        chk = 1;
                                life_count = 1;
                        }
                        fastcopy();
                }
/*
Counter increments
*/
                        counter = (counter+1) % 3;
                        counterx = (counterx+1) % 15;
/*
Bullet Handling
*/
        }
        //printf("ycor = %d, %d, %d, %d\n",Enemies[0].ycor,Enemies[1].ycor,Enemies[2].ycor,Enemies[3].ycor);
}                
/* 
*********************************************
FUNCTIONS
*********************************************
*/
unsigned char Random( void )
{
        //not so random ;d
        static  unsigned char randx = 1;
        static  unsigned char x = 40;
        randx = ( randx + 1) % x;
        x = ( x + 1) % 50; 
        return randx;
        //randx = ((3517 * randx + 431)/210) % 30;
        //return randx;
}
/*
When an enemy dies, a kaboom is drawn, this deletes sometime later
*/
void Drw_Explosion( unsigned struct Enemy * e_ptr )
{
        unsigned char a;
        //static unsigned char count = 0;
        for ( a = 0; a < e_num; a++ )
        {
                if ( e_ptr->statusx == 2 && e_ptr->count == 39)
                {
                        putspriteXOR( e_ptr->xcor, 8, e_ptr->ycor, Explosion_Pic ); // delete the pic
                        e_ptr->statusx = 0;
                }
                
                e_ptr->count = (e_ptr->count + 1) % 40;
                e_ptr++;
        }
        //count = (count + 1) % 40; // every 1\40 time
}
/*
Checks the number of enemies left and decides if the game is over or not
*/
unsigned char ChkGameOver( unsigned struct Enemy * e_ptr)
{
        unsigned char a;
        unsigned char counter = 0;
        for ( a = 0; a < e_num; a++)
        {
                if (e_ptr->statusx == 0)
                        counter++;
                e_ptr++;
        }
        if (counter == e_num )
                return GAMEOVER;
        else
                return 0;
}
/*
Pointer to an array of unsigned structures for the enemy ships, pointer to the table, which is *tableptr
*/
void Move_Enemies( unsigned struct Enemy * e_ptr, unsigned struct Bullet * Eb_ptr, unsigned char inc_counter ) 
//void Move_Enemies( unsigned struct Enemy * e_ptr, unsigned char ptrx, unsigned char *tptr)
{

        unsigned char a;
        unsigned char rand;
        static unsigned char ebptr = 0;
        unsigned char epic = 0;
        //static unsigned char inc_counter = 0;
        unsigned char addfactor;
        if ( inc_counter < 32 )
                addfactor = 1;
        else
                addfactor = -1;
        for ( a = 0; a < e_num; a++ ) // 5 times 
        { 

                if (e_ptr->statusx == 1)
                {
                        putspriteXOR( e_ptr->xcor , 4, e_ptr->ycor , enemypic);
                        
                        if ( e_ptr->ycor < 25 )
                                e_ptr->ycor = e_ptr->ycor + 1;  // ty to sean
                        else
                                e_ptr->xcor = (e_ptr->xcor) + addfactor;
                                
                        putspriteXOR( e_ptr->xcor , 4, e_ptr->ycor , enemypic);

                        rand = Random();
                        if ( rand == 1 && e_ptr->ycor == 25 )
                        {
                                Eb_ptr = Eb_ptr + ebptr;
                                Eb_ptr->status = 1;
                                Eb_ptr->xcor2 = e_ptr->xcor;
                                Eb_ptr->ycor2 = e_ptr->ycor + 5;
                                putspriteXOR(  Eb_ptr->xcor2 , 4, Eb_ptr->ycor2 , shot);
                                ebptr = (ebptr+1) % 20;
                        }
                }
                e_ptr++;
        }
                e_ptr = e_ptr - e_num;
}
/*
Clears the user bullets for a new game
*/
void ResetBullets( unsigned struct Bullet * ptrb, unsigned struct Bullet * e_ptr, unsigned struct PowerUp * Powerz )
{
        unsigned char a; 
        for ( a = 0; a<32; a++ )
        {
                ptrb->status = 0;
                ptrb++;
        }
        for ( a = 0; a<20; a++ )
        {
                e_ptr->status = 0;
                e_ptr++;
        }
        for ( a = 0; a < 10; a++)
        {
                Powerz->status = 0;
                Powerz++;
        }
}
/*
Takes a pointer to a the table of x & y coordinates and loads it into the enemy unsigned structure
 */
void Intialize_Enemies( unsigned char * enemyptr, unsigned struct Enemy * enemyx )
{
        unsigned char a;
        for ( a = 0; a < e_num ; a++)   // 5 times
        {
                enemyx->statusx = 1;
                enemyx->xcor = enemyptr[2*a];
                enemyx->ycor = enemyptr[a*2 +1];
                enemyx++;
                putspriteXOR(  enemyptr[2*a] , 4, enemyptr[2*a+1] , enemypic);
                // define enemyPic
        }
}
/*
Handle the enemy bullets 
*/
/*
NEEDS TO BE CHECKED
*/
unsigned char Handle_PowerUps( unsigned struct PowerUp * pwrx, unsigned char xcor, unsigned char ycor )
{
        unsigned char a;
        unsigned char * Pic;
        unsigned char v_pwr = 0;
        for ( a = 0; a < 10; a++)
        {
                if ( pwrx->status == 1 )
                {
                        switch ( pwrx-> power )
                        {
                                case 1:
                                        Pic = PowerUp1;
                                        break;
                                case 2:
                                        Pic = PowerUp2;
                                        break;
                        }
                        putspriteXOR(  pwrx->xcor , 4, pwrx->ycor, Pic);
                        if ( pwrx->ycor != 60 )
                        {
                                pwrx->ycor++;
                                if (pwrx->xcor >= xcor && pwrx->xcor <= xcor + 7 && pwrx->ycor+3 >= ycor && pwrx->ycor+3 <= ycor +3 )
                    {
                                        pwrx->status = 0;
                                        v_pwr = pwrx->power;
                                }
                                //if ( xcor+3 >= eb_ptr->xcor2 && xcor+3 <= (eb_ptr->xcor2+7) && ycor>= eb_ptr->ycor2 && ycor <= eb_ptr->ycor2 + 3 )                                
                                 else if (pwrx->xcor +3 >= xcor && pwrx->xcor <= xcor + 7 && pwrx->ycor+3 >= ycor && pwrx->ycor+3 <= ycor +3 )        
                                {
                                        pwrx->status = 0;
                                        v_pwr = pwrx->power;
                                }
                                else
                                        putspriteXOR(  pwrx->xcor , 4, pwrx->ycor, Pic);
                        }
                        else
                                pwrx->status = 0;
                }
                pwrx++;
        }
        return v_pwr;
}        
unsigned char Handle_EnemyBullets( unsigned struct Bullet * eb_ptr, unsigned char xcor, unsigned char ycor, unsigned char invincible )
{
        unsigned char curpointer = 0;
        unsigned char bx;
        unsigned char by;
        unsigned char a;
        unsigned char r_value = 0;
        for ( curpointer = 0; curpointer < 20; curpointer++)
        {
                if (eb_ptr->status == 1 )
                {
                        bx = eb_ptr->xcor2;
                        by = eb_ptr->ycor2;
                        putspriteXOR(  bx , 4, by , shot);
                        by++;
                        if ( by != 61 )
                        {
                                eb_ptr->ycor2 = by;
                                if ( invincible == 0 && eb_ptr->xcor2 >= xcor && eb_ptr->xcor2 <= xcor + 7 && eb_ptr->ycor2+3 >= ycor && eb_ptr->ycor2+3 <= ycor +3 )
                    {
                                        eb_ptr->status = 0;
                                        r_value = DEAD;
                                }
                                //if ( xcor+3 >= eb_ptr->xcor2 && xcor+3 <= (eb_ptr->xcor2+7) && ycor>= eb_ptr->ycor2 && ycor <= eb_ptr->ycor2 + 3 )                                
                                 else if (invincible == 0 && eb_ptr->xcor2 +3 >= xcor && eb_ptr->xcor2 <= xcor + 7 && eb_ptr->ycor2+3 >= ycor && eb_ptr->ycor2+3 <= ycor +3 )        
                                {
                                        eb_ptr->status = 0;
                                        r_value = DEAD;
                                }
                                else
                                        putspriteXOR(  bx , 4, by , shot);        
                        }
                        else
                                eb_ptr->status = 0;
                }
                eb_ptr++;
        }
        return r_value;
}        
/* 
*********************************************
Moves existing bullets upwards or downwards (status == 1)

Arguments: The Bullet unsigned structure

Returns: Nothing
*********************************************
*/
void HandleBullets( unsigned struct Bullet * BulPtr, unsigned struct Enemy * ex_ptr, unsigned struct PowerUp * pwrx)
{
        unsigned char curpointer = 0;
        unsigned char bx;
        unsigned char by;
        unsigned char a;
        unsigned char newpowerup;
        unsigned char * Pic;
        //unsigned char e_count = 0;
        for ( curpointer = 0; curpointer < NUM_BULLETS; curpointer++)
        {
                if (BulPtr->status == 1 )
                {
                        bx = BulPtr->xcor2;
                        by = BulPtr->ycor2;
                        putspriteXOR(  bx , 4, by , shot);
                        by = by -1 ;
                        if ( by != -1 )
                        {
                                BulPtr->ycor2 = by;
/*
Checks for collision
*/
                                for ( a = 0; a < e_num; a++) // sees if the bullet hits the ships
                                {
                                        //if ( ex_ptr->statusx != 0 )
                                        //{
                                                if ( ex_ptr->statusx == 1 && (BulPtr->xcor2) >= (ex_ptr->xcor) && (BulPtr->xcor2) <= (ex_ptr->xcor+7) &&  (BulPtr->ycor2) >= (ex_ptr->ycor) && (BulPtr->ycor2) <= (ex_ptr->ycor + 3) )
                                                {
                                                        //scorex = scorex+5;
                                                        ex_ptr->statusx = 2;
                                                        ex_ptr->count = 0;
                                                        //ex_ptr->statusx = 0;
                                                        putspriteXOR( ex_ptr->xcor, 4, ex_ptr->ycor, enemypic);
                                                        putspriteXOR( ex_ptr->xcor, 8, ex_ptr->ycor, Explosion_Pic );                                                        
                                                        BulPtr->status = 0;
                                                        if ( Random())
                                                        {
                                                                newpowerup = 1; // will be random in the future :D
                                                                switch (newpowerup) // more room reserved for other power UPS
                                                                {
                                                                        case 1:
                                                                                Pic = PowerUp1; //address
                                                                                break;
                                                                        case 2:
                                                                                Pic = PowerUp2;
                                                                                break;
                                                                }
                                                        putspriteXOR( ex_ptr->xcor, 4, ex_ptr->ycor, Pic);
                                                        CreateNewPowerUp( pwrx, ex_ptr->xcor, ex_ptr->ycor, newpowerup );
                                                        }
                                                        //e_count++;
                                                }
                                                else if ( ex_ptr->statusx == 1 && (BulPtr->xcor2+7) >= (ex_ptr->xcor) && (BulPtr->xcor2+7) <= (ex_ptr->xcor+7) &&  (BulPtr->ycor2) >= (ex_ptr->ycor) && (BulPtr->ycor2) <= (ex_ptr->ycor + 3) )
                                                {
                                                        //scorex = scorex+5;
                                                        ex_ptr->statusx = 2;
                                                        //ex_ptr->statusx = 0;
                                                        ex_ptr->count = 0;
                                                        putspriteXOR( ex_ptr->xcor, 4, ex_ptr->ycor, enemypic);
                                                        putspriteXOR( ex_ptr->xcor, 8, ex_ptr->ycor, Explosion_Pic );
                                                        BulPtr->status = 0;
                                                        if ( Random() )
                                                        {
                                                                newpowerup = 1; // will be random in the future :D
                                                                switch (newpowerup) // more room reserved for other power UPS
                                                                {
                                                                        case 1:
                                                                                Pic = PowerUp1; //address
                                                                                break;
                                                                        case 2:
                                                                                Pic = PowerUp2;
                                                                                break;
                                                                }
                                                        putspriteXOR( ex_ptr->xcor, 4, ex_ptr->ycor, Pic);
                                                        CreateNewPowerUp( pwrx, ex_ptr->xcor, ex_ptr->ycor, newpowerup );
                                                        }
                                                        //e_count++;
                                                }
                                        //}
                                        ex_ptr++;
                                }
                                        //if (e_count == 0)
                                        if ( BulPtr->status )
                                                        putspriteXOR(  bx , 4, by , shot); // if there is no collision, redraw the bullet.
                                        ex_ptr = ex_ptr - e_num;
                        }
                        else
                                BulPtr->status = 0;
                }
                BulPtr++;
        }
}
/* 
*********************************************
Creates a new bullet at the location of the ptr (0-15)

Arguments: Pointer to the next bullet, pointer to the bullet unsigned structure, x cor, ycor of the ship

Returns: Nothing
*********************************************
*/
void CreateNewBullet( unsigned struct Bullet * CurBullet, unsigned char xx, unsigned char yy, unsigned char pwr )
{
        static unsigned char ptr = 0;
        CurBullet = CurBullet + ptr;
        CurBullet->status = 1;
        CurBullet->xcor2 = xx ;
        CurBullet->ycor2 = yy - 5;
        putspriteXOR(  xx , 4, yy-5 , shot);
        CurBullet = CurBullet - ptr;
        ptr = (ptr +1) & 31;
        if ( pwr == 1)
        {
                CurBullet = CurBullet + ptr;
                CurBullet->status = 1;
                CurBullet->xcor2 = xx-5 ;
                CurBullet->ycor2 = yy - 5;
                putspriteXOR(  xx-5 , 4, yy-5 , shot);
                ptr = (ptr +1) & 31;
        }
}        


/*
This creates a powerup from the function Handle Bullets
when an enemy dies, theres a low chance a powerup is created

if it is, then this initializes it :D
*/
void CreateNewPowerUp(unsigned struct PowerUp * pwr, unsigned char xx, unsigned char yy, unsigned char newpowerx )
{
        static unsigned char ptr = 0;
        pwr = pwr + ptr;
        pwr->status = 1;
        pwr->xcor = xx;
        pwr->ycor = yy;
        pwr->power = newpowerx;
        ptr = (ptr + 1) % 10;
}
/* 
*********************************************
Checks for left\right key input

Arguments: None

Returns:
8 if Left
9 if Right
*********************************************
*/
unsigned char chkkey(void)
{
#asm
        push af
        ld a,$FF
        out (1),a
        nop

        ld a,$FE
     out (1),a
     nop
     nop
     in a,(1)
      cp $FD
      jr z,Left

    ld a,$FF
      nop
      out (1),a
   
      ld a,$FE
      out (1),a
      nop
          nop

     in a,(1)
     cp $FB
         jr z,Right
         
        ld a,$FF
        out (1),a
        nop

        ld a,$BF
     out (1),a
     nop
     nop
    in a,(1)
    cp $DF
    jr z,Second
        
        ld a,$FF
        out (1),a
        nop

        ld a,$BF
     out (1),a
     nop
     nop
    in a,(1)
    cp $FE
    jr z,End

         pop af
         ld hl,0
         ret
Left:
        pop af
        ld hl,8 ; left
        ret
Right:
        pop af
        ld hl,9 ;right
        ret
Second:
        pop af
        ld hl,20 ;2nd
        ret
End:
        pop af
        ld hl,25 ;END
        ret
#endasm
}
/* 
*********************************************
Clears the LCD buffer at $9340

Arguments: None

Returns: Nothing
*********************************************
*/
void ClrScreen(void)
{
/*
#asm

        ld hl,_Image1
        ld de,$9340
        ld bc,768
        ldir
        
#endasm
  //fastcopy();
 */
}
/* 
*********************************************
Copies the buffer at $9340 to the LCD
By: Joe Wingbermuehle
Arguments: None

Returns: Nothing
*********************************************
*/
void fastcopy(void)
{
#asm
._fastCopyx
         ; push af
         ; push de
         ; push hl
         ; push bc
          ld a,0
          out ($20),a
         di
         ld a,$80
         out ($10),a
         ld hl,$9340-12-(-(12*64)+1)
         ld a,$20
         ld c,a
         inc hl
         dec hl
._fastCopyAgainx
         ld b,64
         inc c
         ld de,-(12*64)+1
         out ($10),a
         add hl,de
         ld de,10
._fastCopyLoopx
         add hl,de
         inc hl
         inc hl
         inc de
         ld a,(hl)
         out ($11),a
         dec de
         djnz _fastCopyLoopx
         ld a,c
         cp $2B+1
         jr nz,_fastCopyAgainx
          ld a,1
          out ($20),a
        ;pop bc
        ;pop hl
        ;pop de
        ;pop af
#endasm
}
/* 
*********************************************
Copies an XOR 8 by x sprite to $9340
(Did not write)
Arguments: xcor, height of image, ycor, and the pictures address

Returns: Nothing
*********************************************
*/
void putspriteXOR(  unsigned char x , unsigned char height,unsigned char y ,unsigned char *sprite)
{
#asm
        ;push hl
        ;push de
        ;push af
        ;push bc
    ld hl,2
    add hl,sp
    ld e,(hl)
    inc hl
    ld d,(hl)
    push de
    pop ix
    inc hl
    ld c,(hl)
    inc hl
    inc hl
        ld b,(hl)
    inc hl
    inc hl
    ld a,(hl)
    ld l,c
    ; A = x coordinate
; L = y coordinate
; B = number of rows
; IX = address of sprite
    LD     H, 0
    LD     D, H
    LD     E, L
    ADD    HL, HL
    ADD    HL, DE
    ADD    HL, HL
    ADD    HL, HL
    LD     E, A
    SRL    E
    SRL    E
    SRL    E
    ADD    HL, DE
    LD     DE, $9340
    ADD    HL, DE
    AND    7
    JR     Z, _Aligned
    LD     C, A
    LD     DE, 12
._RowLoop
    PUSH   BC
    LD     B, C
    defb $DD, $4E, $00
    XOR    A

._ShiftLoop
    SRL    C
    RRA
    djnz _ShiftLoop
    INC    HL
    XOR    (HL)
    LD     (HL), A
    DEC    HL
    LD     A, C
    XOR    (HL)
    LD     (HL), A
    ADD    HL, DE
    INC    IX
    POP    BC
    djnz _RowLoop
    jr _End
._Aligned
    LD     DE, 12
._PutLoop
    defb $DD, $7E, $00
    XOR    (HL)
    LD     (HL), A
    INC    IX
    ADD    HL, DE
    DJNZ   _PutLoop
._End
        ;pop bc
        ;pop af
        ;pop de
        ;pop hl
#endasm
}
/*
#asm
._Image1

defb $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FB,$FF,$FF
defb $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
defb $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
defb $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$EF,$EF,$FF,$BF,$FF
defb $FF,$FF,$FF,$FF,$7F,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$BF,$FF,$FF,$FF
defb $FF,$FE,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FB,$FF,$FF,$FF,$FF,$FF
defb $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
defb $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
defb $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
defb $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$BF,$FF,$FF,$FF,$F7,$FF
defb $FF,$FF,$FF,$FF,$DF,$FF,$FF,$FF,$FE,$FF,$FF,$FF,$FF,$FF,$FF,$FF


defb $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FB,$F7,$FF,$FF,$FF,$FF,$FF,$FF,$FF
defb $FF,$FF,$FF,$FF,$FF,$FF,$FF,$DF,$FF,$FF,$FF,$FF,$FF,$FD,$FF,$FF
defb $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
defb $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$7F
defb $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
defb $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$EF,$FF,$FF
defb $FF,$FF,$FF,$FF,$FB,$FF,$FB,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
defb $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$7F,$FF,$7F,$FF,$FF,$FF,$FF,$FF

defb $FF,$FF,$FB,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
defb $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
defb $FF,$FF,$FF,$FF,$BF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
defb $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
defb $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
defb $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
defb $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$EF,$FF,$FF,$FF,$FF,$FF,$FF
defb $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FE,$FF,$FF,$FF,$FF,$FF,$FF,$FF
defb $FF,$FF,$FF,$FF,$FF,$FF,$F7,$FF,$FE,$FF,$F7,$FF,$FF,$FF,$FF,$FF
defb $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$DF,$FF,$FF,$FF,$FF
defb $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
defb $EF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF

defb $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
defb $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$DF,$FF,$FF,$FF,$FF
defb $FE,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FB,$FF,$FF,$FF,$FF,$FF,$FF
defb $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
defb $FF,$FF,$FF,$FD,$FF,$FF,$FF,$FF,$FF,$BF,$FF,$FF,$FF,$FF,$FF,$FF
defb $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FB,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
defb $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$7F,$FF,$FF,$FF,$FF
defb $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
defb $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
defb $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$F7,$FF,$FF,$FF,$EF,$FF,$FF
defb $FF,$FF,$F7,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
defb $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FB,$FF,$FF,$FF
defb $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FB,$FF,$FF,$FF,$F7
defb $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$F7,$FF,$FF,$FF,$FF
defb $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
defb $FF,$FF,$FF,$FF,$FF,$FB,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
defb $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
#endasm
*/
If you can run an optimized version of this plz tell me. :o
stefano
Well known member
Posts: 1534
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

I built it with the following command:
zcc +ti8xansi -startup=1 -oshooter -create-app shooter.c

It runs fine on VTI.. I suppose it is optimized.
Disabling the optimizator (parameter -O0) shooter.8xp size changes from 7.320 to 8.442 ..

I suppose a real calculator behaves differently ?
cjgone
Member
Posts: 15
Joined: Wed Dec 26, 2007 11:41 pm

Post by cjgone »

Ah... my program is 7.3k on my calc... i didn't realize that was optimized?(?)))

When i did the -O2 alone it dropped it to like 5k ;o



I'm confused now. :(
Last edited by cjgone on Mon Mar 17, 2008 10:38 pm, edited 1 time in total.
stefano
Well known member
Posts: 1534
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

Dominic solved the puzzle, explaining the -O0 optimization flag makes the code become slightly bigger, a trick used in the UZI project.

The zcc.opt file presence is normal, it has to do with several functionalities of the compiler, not only the optimization.
cjgone
Member
Posts: 15
Joined: Wed Dec 26, 2007 11:41 pm

Post by cjgone »

Erm, how do I create a binary for an application?
stefano
Well known member
Posts: 1534
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

I'm not sure I understood your question, but I suppose it has to do with the packaging problems many people (including Henk Poley) claimed about in the whole z88dk life.


The command:
zcc +ti8xansi -startup=1 -oshooter -create-app shooter.c

....worked for me. It creates two files, a raw "shooter.bin" file and the "shooter.8xp" one wich is supposed to be ready to be uploaded onto the calculator. By passing the "-startup=1" parameter I'm choosing to formati it for the ION shell (or compatible)... see:

http://www.z88dk.org/wiki/doku.php/plat ... #ti83_plus


I can pass it to the VTI emulator and run it, but I never tested it on a real calculator. Period.


The latter file is the one people seems to have problems with; I suppose there could be two problems:
- The file extension, maybe some transfer tool requires it to be renamed to ".83P" ?
- A 2 byte binary prefix that seems to be automatically added by the transfer tools in some case and that is missing on the other case.

So depending on the Hardware/Software combination developers could experiment hassles... I never had enough informations on this to map the conditions and the actual target platforms in which a fix could be necessary, I just know it is limited to the TI83 / TI83 Plus range.

So, if you can't pass the binary to your calculator or your emulator, try the following (ION shell only):
edit the file "{z88dk}/lib/ti83p_crt0.asm" and go to line 146.

You shoud find the following code:
org $9D95
;org $9D93
;defb $BB,$6D
ret

Comment out the default origin location and un-comment the two following lines.
Let me know if it helps.
cjgone
Member
Posts: 15
Joined: Wed Dec 26, 2007 11:41 pm

Post by cjgone »

^ I used the above from the start.

I'm confused. Is the 7.3k the optimized file?
stefano
Well known member
Posts: 1534
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

I think so.
If you find the size unacceptable we can work on it, but first.. can you run the code ?
cjgone
Member
Posts: 15
Joined: Wed Dec 26, 2007 11:41 pm

Post by cjgone »

Hm, knowing that i'll add more code, i'm pretty sure the prog will always pass 8k, the ti limit.

However, if I write an application, I can get 16k+ of mem.

Does the compiler support creation of apps? And if so, how would I do that for the Ti-84?




Yes, I could run the optimized file of 7.3k... I'm not sure how i got the 5.6k file which doesn't work, but. :o Jut gonna do an app atm, unless theres a way in the compiler to patch jumps if the code is copied to different mem locations, etc.
Last edited by cjgone on Thu May 29, 2008 4:58 am, edited 1 time in total.
stefano
Well known member
Posts: 1534
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

There could be a way to compile a self-relocatable program, but size will be surely bigger.
Could it help ?
cjgone
Member
Posts: 15
Joined: Wed Dec 26, 2007 11:41 pm

Post by cjgone »

Yea. I went back to assembly coding and it's not to exciting. ;)

How would I compile a self-relocating file?
stefano
Well known member
Posts: 1534
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

Well, Z80ASM is able to do it, but it expects that the current location is put in the IY register.
Look for the section "- Generate address independent code, -R", here:
http://z88dk.cvs.sourceforge.net/*check ... z80asm.txt

I succeeded in making it transparently work for the ZX Spectrum in the "bin2bas-rem.c" support tool patching the self relocation code to pass the ORG address from BC to IY.
http://www.z88dk.org/wiki/doku.php/plat ... ther_tools
http://z88dk.cvs.sourceforge.net/z88dk/ ... iew=markup (see line 123)
cjgone
Member
Posts: 15
Joined: Wed Dec 26, 2007 11:41 pm

Post by cjgone »

Erm, I think IY is used by the Ti operating system.

I'm not to familiar with the ORG statement, but can I create a function and have a .ORG above it to patch where i'll copy the funtion to via a pointer?
stefano
Well known member
Posts: 1534
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

You're in the same sotuation I was with the Spectrum.
It it ok to use BC in place of IY ?
cjgone
Member
Posts: 15
Joined: Wed Dec 26, 2007 11:41 pm

Post by cjgone »

Probably, BC is free.
stefano
Well known member
Posts: 1534
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

This still touches IY a bit, but it is worth to try...

Don't care for the value you have in ORG.
Compile the program in this way:
zcc +ti83 -Ca-R program.c

You'll get a relocatable RAW binary.
Then patch it overwriting the first 4 bytes with:
$C5 /* push bc */
$C5 /* push bc */
$FD /* --- */
$E1 /* pop iy */

Your machine code caller needs to set BC with the location of the first byte of this block and jump to it.
Post Reply