Why is DS$ broken???

Started by hydrophilic, August 12, 2007, 03:32 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

hydrophilic

This has been bugging me for years so maybe somebody here knows?  Sometimes the BASIC system variables DS / DS$ go bonkers for no reason I have yet determined.  It may be related to the way that BASIC (and indirectly the KERNAL) access the drive(s), as I was reminded recently by wte,

Quote from: wteThe C128 has the CLC/SEC option in the kernal. Closing a file with channel 15 and Carry Set  will not close the channel on disk.
This is because the disk commands of BASIC 7.0 use channel 15 and the user should also be able to work with the command cannel.
The best example I can think of is this
OPEN 15,8,15
OPEN 2,8,2,"#"
IF DS THEN PRINT DS$:STOP

If the disk drive reports 70,NO CHANNEL then BASIC / DS / DS$ goes bonkers!!
Instead of reporting the real error, the program will crash with a DEVICE NOT PRESENT ERROR.  At which point you can issue ?DS$ and it will respond 00,OK (so the device is still responding).

This problem does not occur if you use the old method of BASIC 2.0 like this
OPEN 15,8,15
OPEN 2,8,2,"#"
INPUT#15,KE,KE$,KT,KS
IF KE THEN PRINT KE$:STOP

This old method correctly reports the error.

I don't have any examples, but the DS / DS$ problem gets even worse when your program uses two (or more) disk drives.

There are plenty of other problems with the DOS interface of BASIC 7.0 which I understand but this one has been annoying me for years now! :mad:  Anybody have a clue??

wte

I understand your problem, but it is easy to explain (you should have a look into the rom listing ;))

First a notice to your code mixing BASIC 2 and BASIC 7 in your first example.
DS/DS$ does not know that you work with drive #8 if you use BASIC 2 to open a file. But, you are lucky, #8 is the Default!
Using the command sequence OPEN 15,9,15:DS$ will give you the Drive Status of Drive #8.
Or using DIRECTORY U9:OPEN 15,8,15:DS$ will give you the Drive Status of Drive #9.
DS/DS$ gets its device information from $011C (like all dos commands do).
BASIC #2 updates only $ba (168) - like a C64.

Now for your special question... The problem is the kind of error: "no channel"!
If you get a no channel error in your first example using OPEN... then you try to open an additional one (using DS$ first clears DS/DS$ and than opens a channel on the disk drive!). This results in an i/o-error #5 in the CHKIN-routine (during TALK). i/o-error #5 is "device not present" which means "does not respond". So BASIC stops with an error message and ds/ds$ is empty. I don't know if this very special channel behavior is a problem of the TALK-routine of the C128 or of the floppy (may be the floppy is running out of channel pointers in the floppy zeropage).
In your second example no additional channel is opened, so getting the error info using INPUT# gives you the correct error info from the disk drive.

learning lessons:
1. always use BASIC 7 commands (to determine the unit) if you want to use DS/DS$
2. if you use BASIC 2.0 dos commands use INPUT# to inspect the error channel

Hope this was a little bit helpful - WTE

hydrophilic

Yes that's extremely helpful.  Normally I would just use the BASIC 7 commands and not mix with the old commands, but as I understand it, you HAVE to use the old OPEN for direct drive (buffer#) channels.

I guess that means I also HAVE to use the old INPUT# methods too.

That's a real bummer but at least now I know.  Thanks again!

airship

When is someone going to release ROM images for the C128 that fix all these known bugs? Aren't they all pretty well documented by now?
Serving up content-free posts on the Interwebs since 1983.
History of INFO Magazine

wte

Quote from: airshipWhen is someone going to release ROM images for the C128 that fix all these known bugs? Aren't they all pretty well documented by now?
Which bugs?

Quote from: hydrophilicYes that's extremely helpful.  Normally I would just use the BASIC 7 commands and not mix with the old commands, but as I understand it, you HAVE to use the old OPEN for direct drive (buffer#) channels.

I guess that means I also HAVE to use the old INPUT# methods too.

That's a real bummer but at least now I know.  Thanks again!
1. Yes, that's right, you HAVE to use the old OPEN for direct drive (buffer#) channels. DOPEN wouldn't work.
2. You can apply a simple trick to use DS/DS$ together with BASIC 2.0: If you have two drives and you want to switch to drive #9 with direct commands use DCLOSE U9 as the first command followed by the "normal" OPEN15,9,15... This will fill $011C with the correct device number. But this will work correctly only if you don't have any open files on drive #9 :ironisk: But you can use DCLOSE#X on U9 (X=non used file number) to switch $011c without closing any file. :)
3. Keep in mind: closing a file with SA=15 will close all files on the disk drive unit.
4. Try another trick: change your code in example#1 to the following and let us know if the problem reappears - I hope it will not!
DCLOSE U8: REM preset $011c with the correct unit number
DE=DS: REM this will open a file with FN=0, SA=15 and allocate a drive channel
OPEN 15,8,15
OPEN 2,8,2,"#"
IF DS THEN PRINT DS$:STOP

May be using DE/DS$ once before the problem with "no channel" occurs fix the problem (but don't forget 3.).

Regards WTE

hydrophilic

Those are some interesting things to try.  It will be a while before I can get back to C128 disk programming...