Optimizer corrupts prog.
Optimizer corrupts prog.
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.
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...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.
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
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
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
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.
I'm compiling a simple test program:
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?
Code: Select all
#include <stdio.h>
main()
{
printf("Hello World!\n");
}
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?
I'm using external, (non library) graphic functions .
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
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
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.
( 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
If you can run an optimized version of this plz tell me.
(compiled like:
zcc +ti8xansi -startup=1 -o shooter.bin shooter.c // no optimization and it works
then devpac8x on the shooter.bin binary.
( 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
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
*/
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.
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.
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. 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.
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. 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.
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)
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)
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.
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.