File Loading Question Using Z88DK

If you like transforming your statements into code, this is the place for you

Moderator: Programming Moderators

Bagpuss
Posts: 27
Joined: Tue Jun 06, 2017 9:13 pm

File Loading Question Using Z88DK

Post by Bagpuss » Tue May 01, 2018 9:04 pm

Hi, I'm trying to get file loading to work via esxdos.
I've been using Stefan's Layer 2 library as a basis. What I am finding is that I can't seem to load files. I've take the code and made a test case:

Code: Select all

/*

zcc +zxn  -subtype=sna -startup=1  -SO2 -clib=new --c-code-in-asm --list -lzxnext_layer2 -lzxnext_sprite testFile.c -Cz"--clean"   -o testFile      -create-app


*/

#include <arch/zxn.h>
#include <stdio.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <malloc.h>
#include "defines.h"
#include <stdbool.h>

#include <errno.h>
#include <arch/zxn/esxdos.h>

#include <zxnext_layer2.h>
#include <zxnext_sprite.h>

void rhload_sprite_patterns(const char *filename,
                          const void *sprite_pattern_buf,
                          uint8_t num_sprite_patterns,
                          uint8_t start_sprite_pattern_slot)
{
    uint8_t filehandle;
    char driveletter;
    struct esxdos_dirent* dirlist;
    char handle;
    
    dirlist = malloc (50 * 25);

   // esxdos_m_setdrv(ESXDOS_DRIVE_CURRENT);
      
    if ((filename == NULL) || (sprite_pattern_buf == NULL) ||
        (num_sprite_patterns == 0) || (start_sprite_pattern_slot > 63))
    {
        printf("XXXXXXBAD PARAMETERS\n");
        return;
    }

    errno = 0;
    filehandle = esxdos_f_open(filename, ESXDOS_MODE_R | ESXDOS_MODE_OE);
    if (errno)
    {
        printf("XXXXXXFILE OPENING FAILED\n");
        return;
    }

    set_sprite_slot(start_sprite_pattern_slot);

    while (num_sprite_patterns--)
    {
        esxdos_f_read(filehandle, (void *) sprite_pattern_buf, 256);
        if (errno)
        {
        printf("XXXXXXREAD FAILED\n");
            break;
        }
        set_sprite_pattern(sprite_pattern_buf);
    }

    esxdos_f_close(filehandle);
}
unsigned char buffer[2048];

    int *SpritePatternBuff;

    
void main()
{
        SpritePatternBuff = malloc(256);
      rhload_sprite_patterns("/spriteBank1.dat",SpritePatternBuff,64,0);
      printf("TESTED\n");
}

I've compiled it using :
zcc +zxn -subtype=sna -startup=1 -SO2 -clib=new --c-code-in-asm --list -lzxnext_layer2 -lzxnext_sprite testFile.c -Cz"--clean" -o testFile -create-app

and launched it in cspect using : cspect -s14 -zxnext -mmc="C:\NextRaiders\" testFile.sna

I have put the file spriteBank1.dat in C:\NextRaiders

I have also tried the following:
- with and without the forward slash.
- Using ./
- adding in the line esxdos_m_setdrv(ESXDOS_DRIVE_CURRENT); to set current drive to *

What I'm trying to work out is where the dufus mistake is in what I'm doing given other demos load files fine.
Part of me is thinking is it because I'm using new lib rather than sdcc_iy?
I have also copied the zxnext_sprite and layer 2 libraries into corresponding directories so I don't need to explicitly specify the paths with -L

Alcoholics Anonymous
Posts: 517
Joined: Mon May 29, 2017 7:00 pm

Re: File Loading Question Using Z88DK

Post by Alcoholics Anonymous » Tue May 01, 2018 10:24 pm

I'll see if I can try your specific example later tonight.

One thing you could try is see if it's a problem with cspect. Put both testFile.sna and spriteBank1.dat into cspect's directory. Use "spriteBank1.dat" as the filename instead of "/spriteBank1.dat". Launch cspect with "cspect -s14 -zxnext -mmc=.\ testFile.sna". I don't think the root dir (leading slash) has any meaning in cspect.

The next thing I would try is to compile with zsdcc to check if there is a problem in the api for sccz80:

zcc +zxn -subtype=sna -startup=1 -SO2 -clib=sdcc_iy --c-code-in-asm --list -lzxnext_layer2 -lzxnext_sprite testFile.c -Cz"--clean" -o testFile -create-app

But you have to make sure the headers and library files you are using "zxnext_layer2" and "zxnext_sprite" are compiled for sdcc_iy and not sccz80.

User avatar
SevenFFF
Posts: 222
Joined: Mon Jun 05, 2017 5:30 pm
Location: USA

Re: File Loading Question Using Z88DK

Post by SevenFFF » Tue May 01, 2018 11:46 pm

You might want to try 8+3 filenames, too. Only the NextOS API supports long filenames, esxDOS doesn't. It's possible CSpect supports them, but the machine isn't going to.
Robin Verhagen-Guest
SevenFFF / Threetwosevensixseven / colonel32
NXtel Spectron 2084blog

Alcoholics Anonymous
Posts: 517
Joined: Mon May 29, 2017 7:00 pm

Re: File Loading Question Using Z88DK

Post by Alcoholics Anonymous » Wed May 02, 2018 5:36 am

I've been installing Stefan's sprite and layer2 code to run your program and I noticed that Stefan almost has the library in a form that can be automatically managed by z88dk-lib.

You can find Stefan's original libraries on github:

https://github.com/stefanbylund/zxnext_sprite
https://github.com/stefanbylund/zxnext_layer2

The newlib has three different versions of libraries and three different headers to accommodate the requirements of three different compilers. If you are using a 3rd party library, you have to make sure you are using the right header and lib file in your compile for the compiler you are using.

So, for example, your compile:

zcc +zxn -subtype=sna -startup=1 -SO2 -clib=new --c-code-in-asm --list -lzxnext_layer2 -lzxnext_sprite testFile.c -Cz"--clean" -o testFile -create-app

is using sccz80 as compiler (clib=new) so the libraries "zxnext_layer2.lib" and "zxnext_sprite.lib" and the header files your are including for these libraries must be made for sccz80. Stefan has versions of his library built for all compile scenarios and he supplies instructions on where to manually put the files to have z88dk locate the right versions of these files automatically.

This is a bit of a pain for people who want to distribute 3rd party library code so there is a tool in z88dk "z88dk-lib" that will install, uninstall and list 3rd party library code inside z88dk. It takes care of everything automatically, as long as the libraries are distributed with the right directory structure.

I fixed up the directory structure for Stefan's libraries in this zip:
https://drive.google.com/file/d/1XoGNHR ... sp=sharing

Unzip this to a temporary location. All the necessary files for the "zxnext_layer2" library are in the "zxnext_layer2" subdirectory and likewise for the "zxnext_sprite" library. Open a command console or shell in this directory.

To install the "zxnext_layer2" library, run this:

Code: Select all

z88dk-lib +zxn -f zxnext_layer2
To install the "zxnext_sprite" library run this:

Code: Select all

z88dk-lib +zxn -f zxnext_sprite
The "-f" option will cause z88dk-lib to overwrite any files of the same name without confirmation (for example if you update the library it will replace the older version).

You can list what third party libraries are installed for the zx next target with this:

Code: Select all

z88dk-lib +zxn
On my install this shows:

Code: Select all

Z88DK-LIB vMSC build-20180429
Third Party Library Installer

Target: zxn

Installed Libraries:

..newlib hdr sccz80 "zxnext_layer2.h" 29165 bytes
..newlib hdr sccz80 "zxnext_sprite.h" 13331 bytes
..newlib hdr sdcc "zxnext_layer2.h" 29165 bytes
..newlib hdr sdcc "zxnext_sprite.h" 13331 bytes
..newlib hdr clang "zxnext_layer2.h" 29165 bytes
..newlib hdr clang "zxnext_sprite.h" 13331 bytes
..newlib lib sccz80 "zxnext_layer2.lib" 77414 bytes
..newlib lib sccz80 "zxnext_sprite.lib" 9843 bytes
..newlib lib sdcc_ix "zxnext_layer2.lib" 58372 bytes
..newlib lib sdcc_ix "zxnext_sprite.lib" 7730 bytes
..newlib lib sdcc_iy "zxnext_layer2.lib" 58696 bytes
..newlib lib sdcc_iy "zxnext_sprite.lib" 7772 bytes
The includes are included like this:

Code: Select all

#include <lib/zxn/zxnext_layer2.h>
#include <lib/zxn/zxnext_sprite.h>
and the link line on the compile line is a little different too:

Code: Select all

zcc +zxn .... -llib/zxn/zxnext_layer2 -llib/zxn/zxn_sprite ...
You can uninstall 3rd party libraries like this:

Code: Select all

z88dk-lib +zxn -f -r zxnext_layer2
z88dk-lib +zxn -f -r zxnext_sprite
Entering "z88dk-lib" on its own will list options.

There are limitations to z88dk-lib that we are aware of. For example, 3rd party libraries must consist of one .lib file and one header .h. In the future we'd like to change that.

In the above, Stefan's zxnext_registers.h file ( https://github.com/stefanbylund/zxnext_ ... egisters.h ) has been omitted and is not installed in the above.

z88dk defines everything already - all registers, io ports, constants - for the zx next in the header "#include <arch/zxn.h>" ( https://github.com/z88dk/z88dk/blob/mas ... arch/zxn.h ) so it's preferable to use this for zx next related defines. Stefan wrote his before this was in z88dk.

In particular there are special macros ( https://github.com/z88dk/z88dk/blob/mas ... zxn.h#L701 ) that map to the special z80-zxn instructions "nextreg reg,val" "nextreg reg,a" "mmun a" so when changing the memory map or setting nextreg state, using these macros will produce smaller code than doing the long way of outing to $243b then $253b.

While compiling should you ever see a report "... is not a library file", this will mean the a library supplied by a 3rd party is behind in version number from your current z88dk install. In this case, I'd uninstall the library then reinstall it after updating the .lib file. You can update the .lib file with "zobjcopy" (see https://github.com/z88dk/z88dk/wiki/Tool-zobjcopy ). "zobjcopy" can also alter a library's section assignments, so eg, you could use it to change which memory banks Stefan's code is placed in. But that's a discussion for another time :)

Alcoholics Anonymous
Posts: 517
Joined: Mon May 29, 2017 7:00 pm

Re: File Loading Question Using Z88DK

Post by Alcoholics Anonymous » Wed May 02, 2018 6:18 am

The problem is the 8.3 filename in cspect. I changed the filename from "spriteBank1.dat" to "sprite.dat" and it worked.

Code: Select all

/*

zcc +zxn  -subtype=sna -startup=1  -SO2 -clib=new --c-code-in-asm --list -llib/zxn/zxnext_layer2 -llib/zxn/zxnext_sprite testFile.c -Cz"--clean" -o testFile -create-app

*/

#include <arch/zxn.h>
#include <stdio.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <malloc.h>
//#include "defines.h"
#include <stdbool.h>

#include <errno.h>
#include <arch/zxn/esxdos.h>

#include <lib/zxn/zxnext_layer2.h>
#include <lib/zxn/zxnext_sprite.h>

void rhload_sprite_patterns(const char *filename,
                          const void *sprite_pattern_buf,
                          uint8_t num_sprite_patterns,
                          uint8_t start_sprite_pattern_slot)
{
    uint8_t filehandle;
    char driveletter;
    struct esxdos_dirent* dirlist;
    char handle;
    
    dirlist = malloc (50 * 25);

   // esxdos_m_setdrv(ESXDOS_DRIVE_CURRENT);
      
    if ((filename == NULL) || (sprite_pattern_buf == NULL) ||
        (num_sprite_patterns == 0) || (start_sprite_pattern_slot > 63))
    {
        printf("XXXXXXBAD PARAMETERS\n");
        return;
    }

    errno = 0;
    filehandle = esxdos_f_open(filename, ESXDOS_MODE_R | ESXDOS_MODE_OE);
    if (errno)
    {
        printf("XXXXXXFILE OPENING FAILED\n");
        return;
    }

    set_sprite_slot(start_sprite_pattern_slot);

    while (num_sprite_patterns--)
    {
        esxdos_f_read(filehandle, (void *) sprite_pattern_buf, 256);
        if (errno)
        {
        printf("XXXXXXREAD FAILED\n");
            break;
        }
        set_sprite_pattern(sprite_pattern_buf);
    }

    esxdos_f_close(filehandle);
}
unsigned char buffer[2048];

    int *SpritePatternBuff;

    
void main()
{
      SpritePatternBuff = malloc(256);
      rhload_sprite_patterns("sprite.dat",SpritePatternBuff,64,0);
      printf("TESTED\n");
}
As SevenFFF mentioned, real esxdos can only do 8.3 filenames. This is also true of cspect because it only simulates some of the esxdos api rather than running actual Next code. esxdos under NextOS can do long filenames. zesarux emulates NextOS so it will also be fine with long filenames.

User avatar
SevenFFF
Posts: 222
Joined: Mon Jun 05, 2017 5:30 pm
Location: USA

Re: File Loading Question Using Z88DK

Post by SevenFFF » Wed May 02, 2018 3:08 pm

CSpect also doesn't like directories named with full 8+3 names like DIRECTOR.Y01, so avoid those too for greatest compatibility.

only idiots like me would even think of doing it like that, of course!

Image
Robin Verhagen-Guest
SevenFFF / Threetwosevensixseven / colonel32
NXtel Spectron 2084blog

User avatar
SevenFFF
Posts: 222
Joined: Mon Jun 05, 2017 5:30 pm
Location: USA

Re: File Loading Question Using Z88DK

Post by SevenFFF » Wed May 02, 2018 3:30 pm

Also try and avoid using any capital letters with the esxDOS API. Files can be named how you like on the card, but the esxDOS ROM is sensitive to how you pass the name to the call in the IX/HL buffer.

Calls that return filenames and paths return them in caps, but they can fail when you provide them in caps. It seems to intermittently fail on the Next board for some files or directories created with mixed case on NTFS partitions and then copied to the sd card FAT32 partition. For files that fail, specifying them in completely lower case seems to always work.

(Confusingly, in my screenshot above I'm specifying them in lower case, but using an upper-case-only font for pure Robotron authenticity; so I have to convert them to upper case before displaying any error messages!)
Robin Verhagen-Guest
SevenFFF / Threetwosevensixseven / colonel32
NXtel Spectron 2084blog

Bagpuss
Posts: 27
Joined: Tue Jun 06, 2017 9:13 pm

Re: File Loading Question Using Z88DK

Post by Bagpuss » Wed May 02, 2018 6:13 pm

Woo hoo. Thanks everyone. Put it together using all the above. There were 2 problems in the end:
1) Use 8.3 filenames (and lowercase). After 25 years of VMS, Unix, Windows NT and the like I just got used to long filenames
2) launching with mmc of .\ sorted out the rest

I've included the code here as a sample in case anyone else in the future hits similar problems in dev.

Code: Select all

/*

Compile with
zcc +zxn -subtype=sna -startup=1 -SO2 -clib=sdcc_iy --c-code-in-asm --list -llib/zxn/zxnext_layer2 -llib/zxn/zxn_sprite  testFile.c -Cz"--clean" -o testFile -create-app
Or
zcc +zxn -subtype=sna -startup=1 -SO2 -clib=new --c-code-in-asm --list -lib/zxn/lzxnext_layer2 -llib/zxn/zxnext_sprite testFile.c -Cz"--clean"   -o testFile      -create-app

Run with

cspect -s14 -zxnext -mmc=.\ testFile.sna

*/

#include <arch/zxn.h>
#include <stdio.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <malloc.h>

#include <errno.h>
#include <arch/zxn/esxdos.h>

#include <lib/zxn/zxnext_layer2.h>
#include <lib/zxn/zxnext_sprite.h>>

void rhload_sprite_patterns(const char *filename,
                          const void *sprite_pattern_buf,
                          uint8_t num_sprite_patterns,
                          uint8_t start_sprite_pattern_slot)
{
    uint8_t filehandle;
    char driveletter;
    struct esxdos_dirent* dirlist;
    char handle;
    
    dirlist = malloc (50 * 25);

   // esxdos_m_setdrv(ESXDOS_DRIVE_CURRENT);
      
    if ((filename == NULL) || (sprite_pattern_buf == NULL) ||
        (num_sprite_patterns == 0) || (start_sprite_pattern_slot > 63))
    {
        printf("XXXXXXBAD PARAMETERS\n");
        return;
    }

    errno = 0;
    filehandle = esxdos_f_open(filename, ESXDOS_MODE_R | ESXDOS_MODE_OE);
    if (errno)
    {
        printf("XXXXXXFILE OPENING FAILED\n");
        return;
    }

    set_sprite_slot(start_sprite_pattern_slot);

    while (num_sprite_patterns--)
    {
        esxdos_f_read(filehandle, (void *) sprite_pattern_buf, 256);
        if (errno)
        {
        printf("XXXXXXREAD FAILED\n");
            break;
        }
        set_sprite_pattern(sprite_pattern_buf);
    }

    esxdos_f_close(filehandle);
}
unsigned char buffer[2048];

    int *SpritePatternBuff;

    
void main()
{
        SpritePatternBuff = malloc(256);
      rhload_sprite_patterns("sprb1.dat",SpritePatternBuff,64,0);
      printf("TESTED\n");
}



Stefan123
Posts: 102
Joined: Mon Jun 05, 2017 9:38 pm

Re: File Loading Question Using Z88DK

Post by Stefan123 » Wed May 02, 2018 8:38 pm

I will soon update the zxnext_layer2 and zxnext_sprite libraries and remove the header file zxnext_registers.h and its usage in favor of Z88DK's register definitions. This should make them compatible with the z88dk-lib tool.

I haven't done anything on the zxnext_layer2 and zxnext_sprite libraries for a while but I plan to revisit them at some point before the official Spectrum Next release. There are several things I would have done differently today that I would like to fix. The main thing would be to rewrite all drawing functions to only require a single user-specified 8K MMU slot; not requiring the top 16K RAM or the specially mapped layer-2 memory at the bottom 16K.

Bagpuss
Posts: 27
Joined: Tue Jun 06, 2017 9:13 pm

Re: File Loading Question Using Z88DK

Post by Bagpuss » Fri May 04, 2018 8:37 pm

One thing that may be worth looking at is the line drawing algorithms. I did similar ones to you in Z80, but I found what greatly helped was checking for horizontal/vertical lines, then doing a straight line for them or using the algorithms you have used only for diagonals.

The other thing I was looking at in my routines was doing a check for line length on horizonal/vertical and going for dma routines depending on length.

Post Reply