Note: Ive only done basic testing on these two commands. They did exactly what they were supposed to for my purposes, so I left it at that! However, bugs or no bugs, these commands should be used with great care!

It appears that different device drivers implement iof.load and differently. In particular, these commands are unlikely to work on original QL platforms! See Warnings, below, for further details.

                Load or Save bytes from/to memory

While LBYTES/SBYTES are useful for copying binary data between files and
memory, sometimes it is inconvenient that this is restricted to the same
block of memory or in contiguous portions of a file in memory.
CH_SBYTES/CH_LBYTES makes it possible to circumvent that restriction by
using a channel.

SMSQ/E & Qdos *, ** compatible (but see warnings, below!)


Usage: Save bytes from memory to an open non-console channel

er = CH_SBYTES(#ch; base, length)

      ch      is the S*BASIC number of a writeable channel
      base    is the address where to save the data **
      length  is the expected length of the data (odd or even ok)

Error returns in er: file/medium errors
Parameter errors are "hard", ie they stop program execution


Usage: Load bytes from an open non-console channel into memory

er = CH_LBYTES(#ch; base, length)

      ch      is the S*BASIC number of an open non-console channel
      base    is the address where to load the data **
      length  is the expected length of the data (odd or even ok)

Error returns in er: OR, file/medium errors (but no EOF!)
Parameter errors are "hard", ie they stop program execution


Some very basic checking is done, like to see that the address is not
zero or negative. However, it is the user's responsibility to ensure
that the length to be loaded doesnt exceed the memory block or overwrite
your operating system or other vital bits and pieces!

* These commands are unlikely to work as intended on original QL harware,
and may crash the system spectacularly if you try them there!

** Odd base addresses are not possible with all drivers! These commands
have tested OK with odd base addresses on current versions of major
platforms: Q-emulator V3.22 with Qdos JS and Minerva 1.98; on SMSQmulator
V2.32 and QPC2 V5.x, both with SMSQ/E 3.3x.

For both the above:

The channel parameter is obligatory (no default).

Minimal error checking is done on the parameters you give to allow maximum
freedom to mess with memory if you know what you are doing. For those who
dont know, or if you make a mistake: BEWARE!

You should also note that only system with CPUs >= MV68020 support odd
memory addresses. However, both lengths and offsets set here can be odd,
as demonstrated by this contrived example:

110 al = 20
120 bl = 10
130 a = ALCHP(100)
140 b = ALCHP(100)
150 FOR i = 0 TO 19: POKE a + i, (i MOD 10) + 48
160 FOR i = 0 TO 9: POKE b + i, i + 65
170 ch = FOP_OVER("ram1_tst_txt")
180 ERT CH_SBYTES(#ch; a + 1, 19)
190 ERT CH_SBYTES(#ch; b + 1, 9)
200 BPUT#ch; 10
220 CLS
230 PRINT PEEK$(a, 20)
240 PRINT PEEK$(b, 10)
250 ch = FOP_IN('ram1_tst_txt')
260 INPUT#ch; l$: PRINT l$
270 GET#ch\ 19
280 ERT CH_LBYTES(#ch; a + 3, 7)
290 GET#ch\ 0
300 ERT CH_LBYTES(#ch; b + 3, 7)
320 PRINT PEEK$(a, 20)
330 PRINT PEEK$(b, 10)

rem Now fiddle addresses and offsets above to try it out! *, **

Software status

V0.02, pjw, 2021 Jul 09
V0.03, pjw, 2021 Oct 03, changed error checking
V0.03, pjw, 2021 Oct 18, added warnings to this text

Conditions and DISCLAIMER as per