Re: [cc65] Re: readdir bug

From: Spiro Trikaliotis <>
Date: 2012-09-14 16:39:59

* On Fri, Sep 14, 2012 at 01:01:18PM +0200 Ullrich von Bassewitz wrote:
> Olivers test program does not only read the directory, but does also open and
> close each file.


In fact, I did not notice that Oliver's program opens the file. Thus, I
did not understand why setting the file type could change the behaviour
so dramatically. Thus, I thought the write went wrong, and something
else were overwritten. My thoughts were wrong.

> This triggers the error somehow as can be seen by taking
> Olivers program and commenting out the lines that open/close the file. What is
> also interesting is that it fails with true drive emulation in VICE but works
> otherwise. At least here with my version of VICE.

This is a known error (at least, know to me, as I had fallen into the
trap before) of the 1541 ROM (and, most probably, also of 157x):

Look at this program:

100 open 1,8,0,"$0"
110 n$=chr$(0)
120 rem load address
130 get#1,a$,b$
140 nl=4
200 rem new line
210 get#1,a$,b$
220 ifa$+b$=""thenend
230 rem line number
240 get#1,a$,b$
250 print asc(a$+n$)+asc(b$+n$)*256;" ";
260 get#1,a$:ifa$<>""thenprinta$;:goto260
270 print
280 li=li+1:if li<nl goto 200
290 li=0

300 open2,8,2,"test,p,r"
310 close2
320 goto200

If you set nl in line 140 big enough (more than there are lines in the
dir), the directory is read and output correctly.

As it is, though, (assuming the program "test" exists on the disk), the
behaviour is exactly what you see in the test program: After opening and
closing the file, the dir channel returns erroneous values. I believe
that the 1541 overwrites some pointers which confuse it completely, but
I have not tested it yet.

Note that you will see parts of the header line repeated again. This is
*exactly* the behaviour I have seen in my cc65 tests with my test
program (output of "buffer").

If you change 300 to

300 open2,8,15

it seems to look even worse. (I see that your _close implementation also
tries to read the error channel, that's why I am mentioning it).

The dir file is not real file. Instead, it is implemented somehow
"hacky" in the 1541. As normally, it is LOADed into RAM, this bug does
not happen as LOAD reads the dir byte after byte, without any
intervening actions. BUT: The test programs (Oliver's as well as mine)
do other operations, which trigger the bug.

> > In fact, currently, I'd think it is a compiler bug that triggers it.
> I doubt this is the case, see below.

I totally agreed in the minute you told me that Oliver's program
actually opens the file.

> > You see, I instrumented with some outputs, and I modified the case 2 by
> > making it as simple as possible.
> Please note that instrumenting the output with printf is dangerous, because
> printf does file I/O and therefore interferes heavily with the calls that read
> from the directory. Each time you call printf, the KERNAL is called to switch
> files. This is why I didn't use this method in the give case. I had used it in
> an earlier case and run into trouble.

I know that this is dangerous. However, it was the best I could come up

Perhaps, we should convince the VICE developers to add a "debugging
chip" which only outputs data to the host. That is, something like

  base+0, base+1: output string, start address
  base+2, base+3: length of string
  base+4:       bit flags to actually start the transfer

That is, the following code

  STA base+0
  STX base+1
  STA base+2
  STX base+3
  LDA #$FF
  STA base+4

should then output the bytes as label TEXT:, for example, into the log
file. This way, debugging would be much easier.

Groepaz, would you consider adding such a patch?

> I've tried adding the #if 0 to the code and compared the assembly results.

With the "#if 1", the entry type is set to "program", so that the test
program actually opens the file. With the "#if 0", it skipps it instead.

> Unfortunately this is complicated by not having a decent debugger available.
> My current version of VICE is not even able to load the label file any more.

Did you change the format of the label files?

> It reads it, but cannot find most of the symbols later. So I have to lookup
> the symbols manually in the map or debug files. Unfortuntely their values
> change with every change in the source ...

I know. That's exactly my problem, too.

Also, that's why I put readdir() into my code, so I can see it better in
the assembly listing. It makes reading the map file easier, IMHO.

Now, what about a fix? I am not sure how to proceed. The directory would
have to be read in one chunk (or, by using the offset and seekdir()? But
that would slow down the process of reading the dir extremely.)


Spiro R. Trikaliotis
To unsubscribe from the list send mail to with
the string "unsubscribe cc65" in the body(!) of the mail.
Received on Fri Sep 14 16:40:34 2012

This archive was generated by hypermail 2.1.8 : 2012-09-14 16:40:37 CEST