"Correct" way to tell if a Tube transfer is complete?

bbc/electron apps, languages, utils, educational progs, demos + more
Post Reply
User avatar
Mince
Posts: 103
Joined: Thu Sep 05, 2019 11:25 pm
Location: Cambridge, UK
Contact:

"Correct" way to tell if a Tube transfer is complete?

Post by Mince »

I have an OSWORD call that hooks USERV to provide a call to transfer blocks of data across the Tube - this works fine. The "problem", however, is that the transfer is asynchronous, so control returns to the parasite while the transfer is still going on.

This wouldn't be a problem except I'm transferring from a buffer that then gets overwritten again by the code in the parasite. On a fast parasite (in my case, a RPi 3B+ running the native ARM7 CPU), it overwrites it before the host has managed to complete the transfer, giving garbled data. I can solve this by putting something like 'dummy%=TIME' in my ARM7BASIC program, which I assume is making a call to OSWORD 1 across the Tube and so will be held up until it's free again.

I was wondering if there's a "correct" way to do this, though (perhaps avoiding the overhead of such a call) — I can't find anything in the Tube Application Note or Advanced User Guide, but I might not be looking properly. I could write some code to claim and then immediately release the Tube, but that seems a lot of hassle to do manually.

Thanks in advance!
User avatar
BigEd
Posts: 3933
Joined: Sun Jan 24, 2010 10:24 am
Location: West Country
Contact:

Re: "Correct" way to tell if a Tube transfer is complete?

Post by BigEd »

By what means is the data transferred?

In the case of filesystem actions, I get the impression that the filesystem call does not return until the transfer is done, but the transfer itself is done asynchronously, on a different channel, and indeed is initiated by the host. If you were doing things that way, your OSWORD would not complete until the host has done the transfer, and the transfer would be initiated by the host in response to the OSWORD call.

But another possibility: I wonder if an Event is the way to do it?

(I've never fully understood what claiming the tube means, or what it is meant to be used for, so I'd like to hear about that from someone who knows.)
Coeus
Posts: 2095
Joined: Mon Jul 25, 2016 12:05 pm
Contact:

Re: "Correct" way to tell if a Tube transfer is complete?

Post by Coeus »

Mince wrote:
Mon Jul 27, 2020 10:53 pm
I was wondering if there's a "correct" way to do this,...
I am not sure if there is a single correct way but the Z80 client ROM does something that sounds very similar to what you're doing. The standard set-up is that parasites issue OS calls to the host and all the big transfers are initiated from the host, generally as a result of filing system calls. The Z80 ROM uses host memory to implement a directory cache for CP/M, i.e. cache of the track(s) that contain the directory. As the single-byte OSWORD to read/wrote I/O memory would be too slow it installs an OSWORD handler in the I/O processor to transfer blocks of memory between the two processors. As the transfer is initiated by an OSWORD, the code for waiting on completion is already part of the OSWORD mechanism.

JGH has disassembled the Z80 client ROM - see ClienttZ80 on http://mdfs.net/Software/Tube/Z80/

I also have a version of this converted to use a different assembler in which the 6502 assembler appears as source rather than a binary blob at: https://github.com/SteveFosdick/Z80/blo ... entZ80.asm Check out lines 510-559 and 1754-1917.
User avatar
Mince
Posts: 103
Joined: Thu Sep 05, 2019 11:25 pm
Location: Cambridge, UK
Contact:

Re: "Correct" way to tell if a Tube transfer is complete?

Post by Mince »

@BigEd — sorry, I didn't make it clear: I mean by driving the Tube directly, using calls to &406 to claim/release the Tube and then reading/writing to &FEE5 (BBC) or &FCE5 (Electron), as described on page 338 of the New Advanced User Guide.

Actually, thinking about this over my morning cuppa with a Rich Tea, it occurred to me that the reason for this is probably because my OSWORD call (&E0) has 0 for the number of parameters returned (paramblock?1=0), so presumably the Tube client doesn't need to wait for it to complete and it can continue. If I set this to 1, then presumably it must wait for the OSWORD to finish, so it can receive the reply. I don't know if this is documented.

Testing this, that seems to be correct: if I set it to 0, the data is corrupted, but setting it to 1 (even though I'm not actually returning any useful data after the sent parameters) stops the corruption (it's easy to spot as I'm actually generating a Mandelbrot set on the ARM7 side and then using the transfer OSWORD to send blocks of 8 lines to the host to be displayed on the screen: the corruption shows up as one block mixed with the next). It also slows the program from about 1.6s to 1.9s. So maybe this is the simple solution.

The only downside is if you wanted to do something asynchronously, before overwriting the buffer: that would need an explicit check.

I assume 'claiming' the Tube is because only one thing can use it at a time and you need to get exclusive control over it. If you use normal OS calls, I assume that this is all done for you: you only need it if you're driving it directly by calling &406 and reading/writing &FEE5/&FCE5. I've never tried not doing it, but I assume it gets in a right mess, if something else comes along.

@Coeus — I'll check that code you linked to later, thanks.
User avatar
BigEd
Posts: 3933
Joined: Sun Jan 24, 2010 10:24 am
Location: West Country
Contact:

Re: "Correct" way to tell if a Tube transfer is complete?

Post by BigEd »

(Thanks!) And interesting project!
User avatar
jgharston
Posts: 4336
Joined: Thu Sep 24, 2009 12:22 pm
Location: Whitby/Sheffield
Contact:

Re: "Correct" way to tell if a Tube transfer is complete?

Post by jgharston »

Yes, you known when *you* have stopped using the Tube when *you* stop using the Tube. No more, no less. What you have discovered, though, that if you instruct the Host that your client expects nothing back from an OSWORD call, then yes the client will not wait for anything back from the OSWORD call, while your client code wanders off and does something else while your host code is still shoving stuff over via the Data protocol.

The standard layout for &80+ OSWORD calls is XY+0=send, XY+1=receive, and a convention has built up that +2 and +3 are command and subcommand/result, so:
XY+0 size of sent block (min 2, max 128)
XY+1 size of received block (min 2, max 128)
XY+2 command
XY+3 subcommand/result
XY!4 data
XY!8 data
XY!12 data
etc.
See http://beebwiki.mdfs.net/Allocations

Also, see http://beebwiki.mdfs.net/OSWORDs to avoid clashing with existing OSWORDs.

Code: Select all

$ bbcbasic
PDP11 BBC BASIC IV Version 0.36
(C) Copyright J.G.Harston 1989,2005-2020
>_
Post Reply

Return to “8-bit acorn software: other”