Re: [cc65] CBM disk write problems

Date view Thread view Subject view

From: Ullrich von Bassewitz (uz_at_musoftware.de)
Date: 2003-12-17 11:57:38


Hi!

On Wed, Dec 17, 2003 at 12:20:43AM +0100, Johan Kotlinski wrote:
> Well, I tried scratching aswell, but the same problem... Then I tried
> writing it in assembler, and it worked. So this suggests there is a problem
> with the wrapper after all. If you are interested, here are the two (in my
> eyes equavilent) routines...

There are several problems with your save routines:

  1. Using '@:' is dangerous with all single drive units. Because of bugs in
     the ROM code, you may loose all your data on that disk. With
     "scratching", I did not mean to use '@:' but 's:', that is, a separate
     scratch command.

  2. Disabling interrupts for an unknown time is a bad idea and may lead to
     problems with fast loaders.

  3. The capital letters are probably not accepted by the drive. Use lower
     case letters for file names.

  4. You are using the command channel (15) as secondary address. This will
     not work, because the command channel is used to send commands, not data.
     Since you're also doing this in your assembler code, I'm really wondering
     how this should have worked.

A still incomplete but working piece of code would look like this:

	void save_highscores()
	{
	    /* Scratch */
	    cbm_open (1, 8, 15, "s:kidgrid.hiscores");
	    cbm_close (1);

	    /* Write */
	    cbm_open (1,8,1,"kidgrid.hiscores");
	    cbm_write (1,(char*)0x1190,180);
	    cbm_close (1);
	}

While this works better than your code, there are still problems:

  1. You will have to check the return code for the cbm_open calls to see if
     there were any problems (drive not present or similar).

  2. You will have to open the command channel to the drive and read it after
     the open, to check if there were drive related any problems.

If you're not doing these two things, errors may go unnoticed. For example
with your erroneous code (writing to the command channel), reading the command
channel from the drive would have given "syntax error". You wrote the
kidgrid.hiscores data to the command channel, but the drive was not able to
make any sense from it, when it tried to interpret it as a drive command.

If all this sounds like a lot of work for just a simple task, then there's
good news for you: If you use C file I/O, the C library will do most of these
things for you. All you have to do is to check the return codes:

	void save_hiscores ()
	{
	    FILE* F = fopen ("kidgrid.hiscores", "wb");
	    if (F == NULL) {
	   	/* Error */
	    }
	    if (fwrite ((const char*)0x1190, 1, 180, F) != 180) {
	   	/* Error */
	    }
	    if (fclose (F) != 0) {
	   	/* Error */
	    }
	}

In fact, for normal file operations, there's usually no reason to use CBM file
I/O instead of C file I/O. The latter increases program size by a few hundred
bytes, but this is often negligible. Advantages are: Easier use, since the
operations are more high level, and easily portable (works also on other
platforms).

Regards


	Uz


-- 
Ullrich von Bassewitz                                  uz_at_musoftware.de
----------------------------------------------------------------------
To unsubscribe from the list send mail to majordomo_at_musoftware.de with
the string "unsubscribe cc65" in the body(!) of the mail.


Date view Thread view Subject view

This archive was generated by hypermail 2.1.3 : 2003-12-17 11:58:14 CET