Login
Back to forumReply to this topicGo to last reply

Posted By

javierglez
on 2023-03-16
17:21:23
 cc65 and disk access

Hello, I've written some code in cc65 to do disk access, I think it's pretty standard, it's below.

Works OK on VICE VIC20 and VICE C16, but not on Yape.

Actually the story is a bit longer because I've written a puzzle game. Yesterday I checked on the real thing and it doesn't work (it does on a real VIC20, the same code except for the graphics).

I'm going to put all the data into the binary as anyway it doesn't fit in a standard C16 but I'm not happy.

I suspect it's cc65 fault. I'm sharing it here in case someone involved with them minds to check. I've checked the ROM disassembly book and confirmed the addresses correspond to disk access routines. I don't understand how location $01 works and so and so.

It crashes right in the beginning, fopen, either write or read.

The CPU enters the following loop:


. E2D4 A5 01      LDA $01     HC=$CA VC=$112 TV=000 SP=E4 A<-$4D
>
. E2D6 C5 01      CMP $01     HC=$D0 VC=$112 TV=000 SP=E4 $0001->$4D
>
. E2D8 D0 FA      BNE $E2D4   HC=$D4 VC=$112 TV=000 SP=E4
>
. E2DA 0A         ASL         HC=$D8 VC=$112 TV=000 SP=E4 A<-$9A
>
. E2DB 60         RTS         HC=$00 VC=$112 TV=000 SP=E6
>
. E1A2 90 FB      BCC $E19F   HC=$06 VC=$112 TV=000 SP=E6
>
. E19F 20 D4 E2   JSR $E2D4   HC=$12 VC=$112 TV=000 SP=E4


Here's the code


#include
#include
#include
#include
#include

#include "circu.h"

FILE * abrirfichero(const char * filename, const char * modo)
{
FILE * fichero;
fichero = fopen(filename, modo);
return fichero;
}

void grabartabla(FILE * fichero, char * valor, char tabla[])
{
int i, j, c;
char a;

fputc(*valor, fichero);
for ( i = 0; i < 8; i++ )
{
for ( j = 0; j < 8; j++ )
{
a = tabla[ i + 8*j ];
c = fputc( a, fichero);
}
}
}

void leertabla(FILE * fichero, char * valor, char tabla[])
{
int i, j;
char nombre[12];
char a = fgetc(fichero);
*valor = a;

for ( i = 0; i < 8; i++ )
{
for ( j = 0; j < 8; j++ )
{
a = fgetc(fichero );
tabla[ i + 8*j ] = a;
}
}
}

void cerrarfichero(FILE * fichero)
{
fclose(fichero);
}

/* the actual data vecposini, circuitos is in the h file */
int main(int argc, char *argv[])
{
int i, j;
char nombre[12];
char * circuito;
char * posini = 0;
char nivel = 0;
char maxnivel = 65;
FILE * fichero;
char lectura[65];


while (nivel < maxnivel)
{
*posini = vecposini[nivel];
sprintf(nombre, "circu%02d", nivel);
puts(nombre);
fichero = abrirfichero(nombre,"wb");
if (fichero)
{
circuito = &circuitos[ (int)(nivel) * 64 ];
grabartabla(fichero, posini, circuito);
}
cerrarfichero(fichero);
fichero = abrirfichero(nombre,"rb");
if (fichero)
{
leertabla(fichero, posini, lectura);
for ( i = 0; i < 8; i++ )
{
for ( j = 0; j < 8; j++ )
{
printf( "%d ", lectura[ i * 8+ j ] );
}
printf( "\n" );
}

printf("\n");
}
cerrarfichero(fichero);
nivel++;
}
return 0;
}


Posted By

javierglez
on 2023-03-23
08:21:19
 Re: cc65 and disk access

In this particular case it was the char * posini = 0;
Then the pointer posini was allocated at $00,$01 and writing once to $01 would freeze the serial bus. On the VIC20 it wasn't a problem because $00 and $01 are unused.

I tried to fix the code to produce correct memory allocation with this :
char * posini;
*posini = 0;
And then the following would pass forward the reference to the variable
leertabla(fichero, posini, lectura);

But it doesn't work, it has to be (for memory allocation and then to pass the reference to the variable):
char posini = 0;
leertabla(fichero, &posini, lectura);

I don't know if it is C like that or it's just cc65.

I wasn't trying to get this kind of function output in many places in the code and so it was pretty much running fine until I encountered this disk issue.

Posted By

siz
on 2023-03-23
10:23:54
 Re: cc65 and disk access

> I don't know if it is C like that or it's just cc65.
I'm pretty sure it's cc65. Normally You don't assign absolute values to pointers, the code You wrote (char *posini=0;) should mean that the pointer's value is NULL.

But I'm not an expert C programmer and never used cc65.

edit: I found the NULL reference on this page.

Posted By

SukkoPera
on 2023-03-23
10:30:03
 Re: cc65 and disk access

Nope, it's standard C. When you do:


char * posini = 0; // This means posini is a pointer to memory location 0
/* ... */
while (nivel < maxnivel)
{
*posini = vecposini[nivel]; // This writes the value of vecposini[nivel] into memory location 0, which I doubt is what you want happy


The right thing to do is the one from your last post, i.e.: keep the variable in some location chosen by the compiler and pass its address to functions that need to alter it.

Posted By

Harry Potter
on 2023-03-23
13:45:58
 Re: cc65 and disk access

If you're only using cc65 and especially CBM targets, I have some ways to make your code more efficient. Somebody on the AtariAge forum also told me about another site explaining other ways to optimize c65 code. Are you interested?

Posted By

javierglez
on 2023-07-05
03:41:12
 Re: cc65 and disk access

Although this was a noob like mistake, actually after fixing it, and pending to retest it on real hardware, this game is finished.
To make it responsive I rewrote the graphics routines in assembler ca65.
I'm not specially interested to cc65 but I most say, I was impressed that the code compiled right out of the box on turbo C for XT class machines (apart form the graphics).
Next time I'd like to give inufuto's C a shot. As a collector his list of 40 targets makes me drool.

For the record, I had to drop fgetc and fputc for fread and fwrite because sometimes the load would interrupt and the table would load from the beginning up to some cell before reaching the end. Then the user would have to recognize the situation and reload the table.

Instead of

char a = fgetc(file);
*valor = a;

for ( i = 0; i < 8; i++ )
{
for ( j = 0; j < 8; j++ )
{
a = fgetc(file );
tabla[ i + 8*j ] = a;
}
}


I eventually used this

char buffer[65];
fread(buffer, 1, 65, file);
*valor = buffer[0];
for ( i = 0; i < 8; i++ )
{
for ( j = 0; j < 8; j++ )
{
tabla[ i + 8*j ] = buffer[ j + i *8 + 1];
}
}

This issue didn't show up on the VIC20.

Posted By

Harry Potter
on 2023-07-05
07:39:12
 Re: cc65 and disk access

I recommend that you use cc65's CBM functions for disk access, as they are specifically designed for CBM computers and require less overhead. I also have some libraries you might like that greatly decrease the amount of RAM needed, but the reply was filtered out as SPAM. sad I ask for permission to SPAM about them here. happy

Posted By

javierglez
on 2023-07-05
12:30:25
 Re: cc65 and disk access

I had compiled this source code for IBM PC XT with Turbo C changing the display routines and it ran OK, even with the bug covered in the first part of this thread present (previously there was another bug preventing it, but this would be another topic). I may release it in the future, if I can finish some details.
There's not much documentation regarding cc65 and their excuse is that it's pretty much standard and TBH that's the point of using C, that you can compile code for different platforms.
I rewrote a few parts of the code concerning display in ca65, but that's because it was critical.

Posted By

MMS
on 2023-07-05
16:50:26
 Re: cc65 and disk access

@Csabo: this is EXACTLY what I meant about the C data types, especially pointers happy



Back to topReply to this topic


Copyright © Plus/4 World Team, 2001-2024