Problem with Spin 0.7s +3 file I/O

edited March 2010 in Emulators
I'm currently trying the +3 disk functions in z88dk. I've based my work upon the simple snippet Winston posted a while ago, but doing the contrary. His code wrote to a file in a +3 Disk, mine attempts to read an image to screen. Here is my code:
#include <stdio.h>
#include <stdlib.h>

void main() {
    FILE *stream;
    unsigned char *pointer;
    unsigned char c;
    
    pointer = (unsigned char *) 16384;

    printf("\x1B[2JTest of file IO\n");
    
    stream=fopen("scr", "r");

    if(!stream) {
        printf("Failed\n");
        return;
    }
    
    fread (pointer, 6912, 1, stream);
    fclose(stream);
}

Which compiles with
zcc +zxansi -vn -O2 -preserve -DPLUS3 -c -o main.o main.c
zcc +zxansi -vn -O2 -preserve -DPLUS3 -o test.bin main.o -lp3

I've created a +3 DISK with three files in it:

LOADER, is a simple loader written in BASIC which sets RAMTOP to 32767, loads the binary code compiled from the above source at 32768 and runs it.
TEST, is the binary compiled from the code above as explained.
SCR, is a 6912 bytes file containing an image.

I've uploaded the DSK file here: http://www.mojontwins.com/warehouse/work.dsk

The problem is that it works flawlessly in Spectaculator from the LOADER option in the main menu and loading it manually from +3 BASIC, but it doesn't work in Spin either way. I get a "Failed" message meaning that a NULL is returned to fopen when it attempts to open the file for reading.

Furthermore, I've found strange behaviour as well when I just type CAT without parameters in +3 BASIC. The emulator goes to full speed (like pressing F1). Using CAT "A:" works, though.

Any pointers?
Post edited by na_th_an on
«1

Comments

  • edited March 2010
    Spin, or rather the fdc765.dll file, doesn't support writing to Extended DSK format files. The compiled code for your 'fopen("scr", "r")' source is trying to open the file with exclusive read/write access so the open is failing with +3DOS error code 1 - Disk is Write Protected.

    The most compatible solution for emulators is to switch to using the older DSK format. Alternatively you could bug the Spin authors ;)

    Wouldn't the access mode be "rb" for a screen file? :)
  • edited March 2010
    Edit: wrote this before seeing Woody's reply, so probably irrelevant.

    Same with SpecEmu as well. I've had problems using disks created with Spectaculator in Spin or SpecEmu before, like the write protect tab being off in Spectaculator and on in other emulators.

    Its a long shot but try creating a blank formatted disk with SPIN disk manager, instead of Spectaculator.

    It can be downloaded directly from here,
    http://diskimagemanager.googlecode.com/files/DiskImageManager.exe
    WIP Tritone Demo
    No more html on dropbox. :(
  • edited March 2010
    So is it a disk format problem? I created mine with CPCXFS, which I've been using for ages to create blank disks, and then formatted it in Spectaculator from BASIC with a single FORMAT "A:".

    I'll try the SPIN disk manager, thanks for the pointers.

    What I don't get is why, if I'm opening the file for "reading" ("r"), I get an error if the disk is write protected. Does that mean that, on real hardware, my program won't work is the actual disk is write protected?
  • edited March 2010
    Well, I've created a blank disk using the disk manager, popped it into Spin, and when I try to format it ("FORMAT A:"), it just doesn't format it, just goes to full speed (1555Hz shows on screen). How can I format the disk?

    I don't understand why the emulator goes to full speed when trying to execute some BASIC instructions related to the disk. This is quite odd. Bug?

    Is there any way to contact the authors for bug reporting? Does Spin have a website?
  • edited March 2010
    na_th_an wrote: »
    Is there any way to contact the authors for bug reporting? Does Spin have a website?

    http://www.worldofspectrum.org/forums/showpost.php?p=407677&postcount=2
  • edited March 2010
    Hi everybody.

    This thread has been created to investigate an issue related with +3 CPC-like disk access throw I/O routines provided with the z88dk developers kit, which I asked Na_th_an for help. He decided to create this thread asking for help, too. So we could say I started this topic.

    My facts: I'm using "-zx -DPLUS -lp3" zcc compiler options to compile a simple program that emulates [LOAD "A:SCR" SCREEN$], very similar to that posted here by Na_th_an. I tried to use <stdio.h> alike functions and <fcntl.h> alike functions, but in every case the program cannot open the speficied file. There is no error nor perror altered states, so we can't know where is the problem or why.

    I'm using two emulators, ESpectrum (ftp://ftp.worldofspectrum.org/pub/sinclair/emulators/pc/windows/Espectrum0.6b2.zip) and ZXSpin v0.666 (ftp://ftp.worldofspectrum.org/pub/sinclair/emulators/pc/windows/zxspin0.666.zip). For comparison purposes, I use the +3 BASIC disk keywords along legacy +3 disk software, namely The Art Studio (http://www.secarica.ro/html/art_studio_for_plus3.html).

    I know that ZXSpin v0.666 has a problem due it does not manage the disks's write protection explicitely, so it can always read but it cannot write at all (neither formatting, writting, renaming nor deleting allowed; always "disk protected" error #1). Na_th_an reports that ZXSpin v0.7 is even worst! But v0.666 *SHOULD* read a file, at least.

    ESpectrum correctly manages the protect tab of the disks explicitely, and it can full read and write disk in either native +3 and +3a, both native and Spanish ROMs, and both thru +3BASIC and Art Studio.

    So I assume that, at reading level, both emulators works well. But the [LOAD "" SCREEN$] equivalent program compiled with z88dk always fail to open in both emulators.

    There are reports saying that the program runs OK with Spectaculator, but I suspect that it runs for lucky. I suspect that +3 I/O routines implemented within z88dk are not refined. The actual document "z88dk/doc/fileio.txt" states: "A file i/o library has been prepared for the +3, this hasn't been tested but it should just work!". Suspicious, isn't it?

    The original +3 IO routines' source code is available (in http://z88dk.cvs.sourceforge.net/viewvc/z88dk/z88dk/libsrc/fcntl/spectrum/plus3/), so please, Are there any good soul with enough time and knowledge to review them? My skills on Z80 assembler and +3DOS are more than oxidized after 20 years... Why do you think I prefer to program the Spectrum in C language? ;-)

    Thanks in advance.
  • edited March 2010
    I've just noticed a similar topic at the z88dk forum:
    http://www.z88dk.org/forum/viewtopic.php?id=2776

    and resolution:

    http://www.worldofspectrum.org/forums/showthread.php?t=20781

    try a CLEAR 32767 before running the binary. this moves the stack below 32768 so that it isn't swapped out when the +3 DOS routines are called. That's my understanding at least as I'm not terribly familiar with the +3.
  • edited March 2010
    Thanks, Alvin, I was about to post this issue in the z88dk forums :) I'll take a glance there as well.
  • edited March 2010
    I think this will probably fix things. +3 DOS swaps something into the top 16k (presumably, please look it up to be sure) while it does its dos thing so the stack can't be up there. z88dk places the binary by default at 32768 and up so the stack was moved below 32768 so as not to conflict with that. But maybe you don't want the stack to be in contended ram so a better location might best be found.

    Also +3 DOS needs to know what memory page to be paged back in before returning. I assume that if you do any memory paging on the +3 you will need to keep some system variable up to date with current paging info in order for +3 DOS to return properly.
  • edited March 2010
    :oops:

    Sorry, I forgot to mention that I already realize about the CLEAR 32767 issue posted by Winston. This time is a different issue, I suspect.

    I hope to find some help in z88dk forums. Thanks to Na_th_an again!
  • edited March 2010
    Slightly off-topic, I'm taking notes about the paging. Currently we do this, I believe $5B5C is the correct address to the system variable used to keep track of the current page?
    void SetRAMBank() {
    #asm
    	.SetRAMBank
    		ld	A, ($5B5C)
    		and	F8h
    		or	B
    		ld	BC, $7FFD
    		ld	($5B5C), A
    		out	(C), A
    #endasm
    }
    
  • edited March 2010
    dom wrote the +3 DOS stuff and you will find him at the z88dk forum. I was going to start a thread there for you until I spotted this other one but as you're headed that way I will let you start it instead.
  • edited March 2010
    na_th_an wrote: »
    Slightly off-topic, I'm taking notes about the paging. Currently we do this, I believe $5B5C is the correct address to the system variable used to keep track of the current page?
    void SetRAMBank() {
    #asm
    	.SetRAMBank
    		ld	A, ($5B5C)
    		and	F8h
    		or	B
    		ld	BC, $7FFD
    		ld	($5B5C), A
    		out	(C), A
    #endasm
    }
    

    Edit: I had a look at the FAQ http://www.worldofspectrum.org/faq/reference/128kreference.htm . The +3 paging is the same as the 128s' in normal mode. If you want RAM in the bottom 16k you can go to special mode by OUTing to port $1ffd. The system variable at $5b67 needs to be kept up to date with this value. The FAQ also mentions this "RAM banks 1,3,4 and 6 are used for the disc cache and RAMdisc, while Bank 7 contains editor scratchpads and +3DOS workspace." which seems to suggest +3DOS can require a whole lot of RAM but I'm sure that's tied to the number of open files and something a bit more refined will help nail down what areas of memory you need to stay away from.
  • edited March 2010
    na_th_an wrote: »
    Well, I've created a blank disk using the disk manager, popped it into Spin, and when I try to format it ("FORMAT A:"), it just doesn't format it, just goes to full speed (1555Hz shows on screen). How can I format the disk?
    Go back to using Spin 0.666 and goto Tools/Disk Options. You can create a new formatted disk here that works fine in Spin and other emulators (except write protect is wrong way). FORMAT "a:" gives me error 'Missing address mark' in 0.666 and 0.7.

    I was told to use SPIN disk manager when I needed to create a new disk by somebody. Just tried it myself and my new disk has errors. Do I have to manually add a +3DOS boot sector or something?
    I don't understand why the emulator goes to full speed when trying to execute some BASIC instructions related to the disk. This is quite odd. Bug?
    You have accelerated disk access in options selected?

    Edit:
    FORMAT "a:" gives me 'Missing address mark' error with your work.dsk and new disks created with Spin 0.666, in SpecEmu and Spin.
    I cannot see any solution other than to use only Spectaculator when working with +3 disks. And enable write protect in Spectaculator if you want to let Spin or SpecEmu be able to write to the disk.
    WIP Tritone Demo
    No more html on dropbox. :(
  • edited March 2010
    Nope. The problem is that the task is not performed (apparently) and the emulator continues in full-speed mode until I press F1 to de-activate it.
  • edited March 2010
    ESpectrum emulator creates blank DSK files right well, and also format them thru +3BASIC, while you emulate +3 models. It doesn't deal DSK files with "protected data", but you can explicitely set when a given emulated disk is protected or not. That is, it emulates the protection tab, which is in fact an external device of the floppy, not related with the data in itself.

    Up to date, ZX Spin has some +3 disks related issues and bugs, that may be improved and fixed in future releases.

    But please keep in mind that ultimately the problem is the code generated by zcc compiler of the z88dk suite, and not certain emulator's behaviours.
  • edited March 2010
    Currently there's a thread in WOS about +3 IO topic (http://www.z88dk.org/forum/viewtopic.php?id=2776), but it is last updated in 2007!

    The following is adressed to both Na_th_an and Alcoholic Anonymous: Did you already open a new thread there in WOS? Or are you mutually waiting the other do the job first?:razz: Sorry to humour you...
  • edited March 2010
    :oops:
    The thead is in z88dk forums, not WOS's...
  • edited March 2010
    POKE 36891,1 before the RANDOMIZE USR.
  • edited March 2010
    And what the rationale behind is??? :-?
  • edited March 2010
    *gives up*
  • edited March 2010
    Well, I believe in magic too, but currently I'm more interested in science, knowledge, rational thinking and the like, you know...

    So, What the hell that POKE actually does? Tell me, please, tell me, tell me, tell me, please daddy, please, please, tell me, tell me...:razz:
  • edited March 2010
    It fixes the problem already given in the first reply:
    "The compiled code for your 'fopen("scr", "r")' source is trying to open the file with exclusive read/write access so the open is failing with +3DOS error code 1 - Disk is Write Protected"

    Of course it's not a real solution, more just the proof of the fault!

    nathan: it would (or certainly should) fail on a real write-protected disk.
  • edited March 2010
    The following is adressed to both Na_th_an and Alcoholic Anonymous: Did you already open a new thread there in WOS? Or are you mutually waiting the other do the job first?:razz: Sorry to humour you...

    Actually yes I was waiting for nathan to do it. Anyway topic reopened at http://www.z88dk.org/forum/viewtopic.php?id=2776

    Did Woody's patch work or no? If so, he's done all the hard work already and fixing up the z88dk driver will be that much easier :-)
  • edited March 2010
    In Z80 terms at least, it's setting C to 3 rather than 1 for the call, so selecting exclusive read-write rather than only exclusive-read.
  • edited March 2010
    Actually yes I was waiting for nathan to do it. Anyway topic reopened at http://www.z88dk.org/forum/viewtopic.php?id=2776

    Did Woody's patch work or no? If so, he's done all the hard work already and fixing up the z88dk driver will be that much easier :-)

    Sorry, I was really busy yesterday and then went home where I don't have a working Internet connection right now. Thanks for doing it.

    It seems that the solution (at least, in z88dk) is on the way :) . Anyway, what strikes me is why does it work in Spectaculator (with an unprotected disk) and not in ESpectrum (where you can unprotect the disk as well).

    I looks like the +3/DSK emulation/support is quite unstable accross different emulators and systems.
  • edited March 2010
    Target!

    The POKE works, so the "A:SCR" file now it is opened and readed in both emulators ESpectrum and ZXSpin v0.666. In Spectrum it is opened even with "protected" disk.

    Yeh, the problem is fixed at that level, so I'm waiting for a z88dk update right now! ;-)

    But about the open mode, in ANSI C "r" denotes "read only" and "r+" denotes "read and write" for "fopen()" function. How many flags actually supports the z88dk +3 file I/O? Indeed, Does +3DOS support full "read/write" simultaneous access for a file?

    The <fcntl.h> file in z88dk only has

    #define O_RDONLY 0
    #define O_WRONLY 1
    #define O_APPEND 256

    flags for the low level "open()" function. Doesn't it support standard "_O_RDWR" flag? Or this mean that full R/W is not allowed?
  • edited March 2010
    Please, move Woody's cure:
    Woody wrote: »
    In Z80 terms at least, it's setting C to 3 rather than 1 for the call, so selecting exclusive read-write rather than only exclusive-read.

    to the z88dk forum so the fix can be done.

    Thank you everybody.
  • edited March 2010
    Woody wrote: »
    In Z80 terms at least, it's setting C to 3 rather than 1 for the call, so selecting exclusive read-write rather than only exclusive-read.

    That would correspond to this line in the original source:
    	ld	c,3		;exclusive read/write - who cares?
    

    which is applied no matter what the open file mode was. Enforcing of read/write mode is then done at the C interface level and not at the +3 DOS level.
    Target!

    But about the open mode, in ANSI C "r" denotes "read only" and "r+" denotes "read and write" for "fopen()" function. How many flags actually supports the z88dk +3 file I/O? Indeed, Does +3DOS support full "read/write" simultaneous access for a file?

    The <fcntl.h> file in z88dk only has

    #define O_RDONLY 0
    #define O_WRONLY 1
    #define O_APPEND 256

    flags for the low level "open()" function. Doesn't it support standard "_O_RDWR" flag? Or this mean that full R/W is not allowed?

    The z88dk driver seems to support read or write or append but not read/write (it will exit with error if this is tried). I'm not sure what +3 DOS is capable of but that commented line above seems to suggest it can do r/w to a single file handle. If so I am wondering if there is another reason that r/w is being weeded out as an error.

    The fix seems to be quite easy but I'd prefer dom did it since he knows the +3 and wrote the original code. z88dk has nightly builds now so you should be able to pick up a new copy of the affected library file the night after the fix is applied.

    Regarding stability :- this isn't really a stability issue. Because the driver always opens files in r/w mode, opening a file for read access only will fail on a real machine using a disk with its write protect tab set. If emulators have an option to emulate the write protect tab, it will fail on them too unless the option is unset. All other cases would have to be an emulation issue. Everything the z88dk driver is doing is through +3DOS calls.
  • edited March 2010
    I agree with everything AA says.
Sign In or Register to comment.