Re: [cc65] cc65 and $ba again, sorry

Date view Thread view Subject view

From: Ullrich von Bassewitz (uz_at_musoftware.de)
Date: 2003-10-17 20:45:51


Hi!

On Fri, Oct 17, 2003 at 07:53:24PM +0200, carlos wrote:
> I see your arguments, but there should be any possibility to find out which
> drive has been accessed the last time or something like this, because i
> don't want to have a program running only on drive 8.
> The natural thing is, that you use the drive, from where the program has
> been loaded.

That's ok, but you cannot rely on a compiled program that uses file I/O not
touching the kernal variable used for the drive number. Someone suggested to
initialize _curunit with the drive number from where the program was loaded.
Until this is available, you can use this module to do something similar:

----------------------------------------------------------------------------
       	.constructor    saveunit, 32
  	.export		_savedunit
.code
saveunit:
     	lda	$ba
     	sta	_savedunit
     	rts
.bss
_savedunit:	.res 	1
----------------------------------------------------------------------------

It is used like this:

----------------------------------------------------------------------------
#include <stdio.h>

extern unsigned char savedunit;

int main (void)
{
    printf ("Saved unit: %d\n", savedunit);
    return 0;
}
----------------------------------------------------------------------------

> The second thing is, that there are kernal variables $9a/$9b for stdin
> stdout. This is where the drive
> output/input device number goes when doing a cmd ... from the c64 basic
> prompt.
> So i don't understand why to mess up $ba, which is at the moment the only
> possibility to get drive from where the program has been loaded.

The library is "messing" with $ba because it is opening files. And when doing
so, it uses the kernal OPEN entry point, which in turn will overwrite the $ba
variable. Please note that it is not the library that is overwriting $ba, it
is the ROM kernal of the C64!

$9a/9b don't change anything, because stdin and stdout are files and are
therefore using standard C file handles. Even if $9a/$9b would be used (which
is difficult, because the file code is the same for all CBMs and $9a/$9b are
C64 specific), stdin/stdout and stderr would still have to be opened. If you
don't want the library to open any files, then don't use file I/O - it's
really simple.

> If there would be another way instead of using kernal variables directly, i
> would appreciate.

You do have two choices:

  1. If you want to use kernal file variables without the library messing with
     them, don't use file I/O in your program. PLEASE NOTE: This includes
     printf/fprintf/puts/putc/...

  2. If you find that you need to use C file I/O, you can still use kernal
     variables, but stop complaining about the library using them, too. After
     all, it's your program that is causing the library to do so. Instead, you
     will need to understand what the library does and find a way to cooperate
     with the library code. One way to do that is shown above. You may run
     into difficulties with this approach if the library implementation
     changes. But no one can prevent this.

Above choices are not only limited to cc65, they are - in a similar way -
inherent in all APIs, where a higher level API uses a lower level one. As a
programmer, you should only use one API. If you don't do that, you will have
to live with restrictions at best. If you are using C file I/O together with
POSIX file I/O under Linux or Windows, you will get unexpected results.

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-10-17 20:49:02 CEST