1

Topic: Load a TAP file from Variable

So, I have the following BASIC snippet:

10 LET T$="RockOn.TAP"
20 .TAPEIN T$

However this gets me a "No such FILE or DIR, 20:1" message

Modifying to try semicolon trick from the "Topic: String variable in save*/load* commands" thread leave the BASIC as:
10 LET T$="RockOn.TAP"
20 .TAPEIN ;T$

This gets the error of "Invalid FILENAME, 20:1"

I guess at this point I have a few questions:

1) Is there a proper/generic way to pass variables to dotcommands or is it something that is handled at the dotcommand implimentation / source level?
2) If it's option 2 above, is there some reference docs so I can look at writing my own .TAPEIN inside of my own RAM based app (not a dotcommand, ideally with z88dk)

-Thanks in Advance
Dx

2 (edited by Alcoholics Anonymous 2018-05-01 02:18:48)

Re: Load a TAP file from Variable

Xalior wrote:

I guess at this point I have a few questions:

1) Is there a proper/generic way to pass variables to dotcommands or is it something that is handled at the dotcommand implimentation / source level?
2) If it's option 2 above, is there some reference docs so I can look at writing my own .TAPEIN inside of my own RAM based app (not a dotcommand, ideally with z88dk)

The command line is the responsibility of the dot command.  At the moment, (all) dot commands treat the command line like a sequence of ascii characters so they are not parsing it as if it is part of a basic statement.

In z88dk the command line is optionally parsed into argc,argv also assuming it's an ascii sequence.

I'm looking at changing this now (I am a dev at z88dk) so that there is an option to use basic's expression evaluator to parse the command line.  So there will be a way to do what you want in your dot commands in the future.

I do not have documentation for the tapein functions in esxdos but I do have them for NextOS and it would be simple to replace the existing .tapein with a new one that did basic expression command line parsing later on.  Or as you suggest, it's also easy to access the .tapein functionality from your own c or asm code.

Once I've finished the NextOS api I will update the esxdos api to the same level and ask Miguel for more information where needed.

3

Re: Load a TAP file from Variable

Alcoholics Anonymous wrote:

The command line is the responsibility of the dot command.  At the moment, (all) dot commands treat the command line like a sequence of ascii characters so they are not parsing it as if it is part of a basic statement.

This was my eventual conclusion, and thanks for confirming it.

Alcoholics Anonymous wrote:

In z88dk the command line is optionally parsed into argc,argv also assuming it's an ascii sequence.

Much like "Vanilla C" then. I've done a fair whack in the embedded Linux side, that bodes well...

Alcoholics Anonymous wrote:

I'm looking at changing this now (I am a dev at z88dk) so that there is an option to use basic's expression evaluator to parse the command line.  So there will be a way to do what you want in your dot commands in the future.

That's a fabulously generic solution at a CRT/libs level is, of course, the best possible outcome.... So, this is wonderful. Thank you.

Alcoholics Anonymous wrote:

I do not have documentation for the tapein functions in esxdos but I do have them for NextOS and it would be simple to replace the existing .tapein with a new one that did basic expression command line parsing later on.  Or as you suggest, it's also easy to access the .tapein functionality from your own c or asm code.

If I could only find some better documents I'd happily do it myself.

I've got myself some working dotcommands out of z88dk that speak to the esxdos API* but find the sparceness of esxdos.h to be limiting... for example there's a esxdos_disk_info, which takes an uchar as a device identifier, but no way to know what devices (and thus uchars) my local speccy has...

Alcoholics Anonymous wrote:

Once I've finished the NextOS api I will update the esxdos api to the same level and ask Miguel for more information where needed.

That sounds great! Thanks again!

To be honest, I'd happily try to tackle it myself, both inband in my own app, and to try and write a new .tapein if I wasn't quite so document hindered...  I'm struggling to find much to integrate with esxdos at a "userland" level... and in that regard if you can point me documentation more than this forum, and the esxdos.h from z88dk itself that would be a MASSIVE leg up in my universe...

...maybe I could make my own .tapein hack while I wait for your more elegant solution... because currently I have a lot of "if T$" statements going on before deciding which hardcoded .TAPEIN to use... :-l :-o

-Dx

* Oh, and emulation of a DIVMMC, Classic Speccy, on FUSE is PAINFUL... Do you know if it normal to have to reflash the emulated EPROM on the MMC every time you restart FUSE? :-(

4 (edited by Luzie 2018-05-01 14:01:31)

Re: Load a TAP file from Variable

Xalior wrote:

* Oh, and emulation of a DIVMMC, Classic Speccy, on FUSE is PAINFUL... Do you know if it normal to have to reflash the emulated EPROM on the MMC every time you restart FUSE? :-(

Can you try Windows Emulators or only *nix ones? I prefer Windows-Emulator SpecEmu (Download: https://1drv.ms/u/s!AmOOhLw8lDDygQzgACzb-YoUa2fp ) where divIDE-ROM can be set within INI-File. Or ZEsarUX (where also an *nix version exists): ( https://sourceforge.net/projects/zesarux/ ) which can set divMMC or divIDE-ROMs via commandline or .INI-File.

5

Re: Load a TAP file from Variable

Xalior wrote:

To be honest, I'd happily try to tackle it myself, both inband in my own app, and to try and write a new .tapein...

I recommend you to get in touch with ub880d, who wrote the last version (=v0.3) of .tapein:
http://sindik.at/~ub880d/2016/03/3-drob … a-tapeout/
to discuss this with him. Thanks!

6 (edited by Xalior 2018-05-01 14:14:50)

Re: Load a TAP file from Variable

Luzie wrote:

Can you try Windows Emulators or only *nix ones? I prefer Windows-Emulator SpecEmu (Download: https://1drv.ms/u/s!AmOOhLw8lDDygQzgACzb-YoUa2fp ) where divIDE-ROM can be set within INI-File. Or ZEsarUX (where also an *nix version exists): ( https://sourceforge.net/projects/zesarux/ ) which can set divMMC or divIDE-ROMs via commandline or .INI-File.

I have Ubuntu, and Windows 10 on my desk, just I develop daily at MacOS - I have tried this in Fuse for MacOS (1.4.1) and Fuse from brew (updated to 1.5.3 this morning)

FUSE has both these options, and it does work, with INI file or command line parsing, but you have to reflash the EPROM (load the ESXMMC.TAP / ESCIDE.TAP) each time you restart the emulator... 

For example I have to use

fuse  --divmmc  --divmmc-file /u/ZX/media/esxdos-mmc.hdf --machine plus3 /u/ZX/esxdos085/ESXMMC.TAP

to start the emulator, load the firmware for the DivMMC, and then use the menu to navigate to my own TAP file and load that accordingly.   This does, obviously, slow down debugging code massively, and prevents me doing any automated testing of my software...

I shall give this a try with Zesarus, thanks, because my app is designed for classic and next, so I need to get around to moving to that as an emulator platform anyway.... thanks!

-Dx

7

Re: Load a TAP file from Variable

Luzie wrote:

I recommend you to get in touch with ub880d, who wrote the last version (=v0.3) of .tapein:

Yeah... That was my first thought smile Thanks for suggesting it however!

But the lack of contact information available, or source code at all, on ub880ds website left me a little disheartened so I thought to post here first, where communication seems to be more encouraged... ;-)

-Dx

8 (edited by Alcoholics Anonymous 2018-05-01 19:11:34)

Re: Load a TAP file from Variable

Xalior wrote:
Alcoholics Anonymous wrote:

I'm looking at changing this now (I am a dev at z88dk) so that there is an option to use basic's expression evaluator to parse the command line.  So there will be a way to do what you want in your dot commands in the future.

That's a fabulously generic solution at a CRT/libs level is, of course, the best possible outcome.... So, this is wonderful. Thank you.

Yes it will be transparent to both c and asm dot commands.  You can choose to get an address of the line as esxdos passes it, you can receive the command line as argc/argv (this is the default - handling quoting is is still on the to-do) and the third option will be argc/argv after basic's expressions are applied.

The choice is controlled at compile time by a pragma, which is how z88dk communicates options to the crt.  The pragmas are collected as defines in the file "zcc_opt.def" and then this file is included into the crt to control what is in there.

The crt does:

* store state for basic (primarily SP, HL', IY)
* initialize
* call _main
* cleanup
* restore state for basic
* return to esxdos

There are two types of dot commands for esxdos.  One is the normal dot selected with "-subtype=dot" on the compile line.  You're restricted to around 7k.  The other is the extended dot selected with "-subtype=dotx" on the compile line.  This one splits the dot command into two halves - the first is in the usual location 8k-16k and is limited to 7k size as always and the second half is in main ram at a pragma-defined org (32768 by default).  So this is a method to run large dot commands > 7k but it does take up main memory to do so.  The crt will load the dotx command into memory for you but it does a ramtop check to make sure it is safe to load.

At one time we were considering dot commands that occupy several divmmc pages so that no basic memory was used but I thought that would be more trouble than it is worth.

If I could only find some better documents I'd happily do it myself.

I've got myself some working dotcommands out of z88dk that speak to the esxdos API* but find the sparceness of esxdos.h to be limiting... for example there's a esxdos_disk_info, which takes an uchar as a device identifier, but no way to know what devices (and thus uchars) my local speccy has...

esxdos_disk_info(), esxdos_disk_read() and esxdos_disk_write() are dealing with the media directly so it would be unusual to use them.  esxdos_disk_read() and esxdos_disk_write() look like they may be used to quickly stream raw data from disk.  nextos has a streaming facility that looks similar.

Anyway all the documentation I have for esxdos can be found in the asm functions themselves:
https://github.com/z88dk/z88dk/tree/mas … esxdos/z80

esxdos.h is hardly commented and only documents through function prototypes how the c api is wrapped on top of those asm functions:
https://github.com/z88dk/z88dk/blob/mas … x/esxdos.h

There are some comments in z88dk's esxdos configuration:
https://github.com/z88dk/z88dk/blob/mas … _esxdos.m4
and numbers instead of symbols:
https://github.com/z88dk/z88dk/blob/mas … e.inc#L517

As you can see, I only know about some of the api but that subset is also what's needed 99% of the time.

When a dot command starts, the program is handed a pointer to a sequence of ascii chars.  The pointer could be 0 (in which case there is no command line) otherwise the ascii sequence ends in 13,':' or 0.

z88dk's crt code for forming argc,argv shows how it is handled:
https://github.com/z88dk/z88dk/blob/mas … dos.inc#L1
https://github.com/z88dk/z88dk/blob/mas … rse.asm#L9

On exit from a dot command, esxdos expects this:
https://github.com/z88dk/z88dk/blob/mas … sm.m4#L239

In z88dk, the exit status is in HL (to be consistent with return,exit,abort,etc) with HL=0 for ok, HL<255 for a canned esxdos error message (https://github.com/z88dk/z88dk/blob/mas … os.m4#L103) or HL>=256 to point to a custom error message in a string terminated with last char having bit 7 set.

To be honest, I'd happily try to tackle it myself, both inband in my own app, and to try and write a new .tapein if I wasn't quite so document hindered...

Parsing the command line using basic's expression evaluator requires a little dancing.  Since the rom is not visible while your dot command runs, you must use esxdos's rst$18 hook to call rom routines.  "rst 0x18; defw nnnn".  My intention is to write the resulting strings on the stack as argc/argv so that there is a place for the program to refer to them but you could do a bespoke thing and just parse a specific line as you go.

I'm struggling to find much to integrate with esxdos at a "userland" level... and in that regard if you can point me documentation more than this forum, and the esxdos.h from z88dk itself that would be a MASSIVE leg up in my universe...

Hopefully the above can give you at least some more info.  Another source is nextos's esxdos api starting on page 20:
https://github.com/z88dk/techdocs/raw/m … os_api.pdf

nextos extends the api a bit, but for the functions it has in common things should be compatible with esxdos.  Some of the information comes from disassembling existing dot commands and you can compare to what we have above for esxdos to verify that it looks the same.  The nextos esxdos api does document the TAPEIN, TAPEOUT functions and I expect it's the same for esxdos but I can't say for sure.

* Oh, and emulation of a DIVMMC, Classic Speccy, on FUSE is PAINFUL... Do you know if it normal to have to reflash the emulated EPROM on the MMC every time you restart FUSE? :-(

At the moment I am using zesarux and writing files into a divmmc image containing esxdos using IMDisk for windows.  Not totally perfect because you have to exit zesarux and restart to guarantee it can see changes to the image, and zesarux is farily slow on my machine but it is adequate for testing.  It also has an esxdos handler that can read PC files instead of using the mmc image but the esxdos api has many bugs if you go past the very simple.

9 (edited by aowen 2018-05-28 23:26:39)

Re: Load a TAP file from Variable

Alcoholics Anonymous wrote:

At the moment, (all) dot commands treat the command line like a sequence of ascii characters so they are not parsing it as if it is part of a basic statement.

Actually that's not true. The .PLAY command parses the line using the BASIC editor. You have to do a bit of juggling but you can get BASIC to parse strings (T$ and so on). However, you can't get BASIC to parse a line containing numeric variables because when you enter a line in BASIC the values are added (but hidden) in the line, and that doesn't happen when esxDOS passes a line to the dot command handler.

10

Re: Load a TAP file from Variable

Cheers Andrew.  I would have run into that and wondered wtf was going on smile