Your Spectrum
Issue 5, July 1984 - Channels & Streams
Home Contents KwikPik

See also the second half of this article:
Issue 7"Spectrolysis: Channels & Streams"



big title YS's own Mr Fix-it, Ian Beardsmore, guides you through the rapids of channels and streams. For theory, philosophy, bugs and fixes - write to Ian c/o Spectrolysis, Your Spectrum, 14 Rathbone Place, London W1P 1DE. space routines is a giveaway to the true nature of streams and channels. In the other three cases it's often said that somehow that channel is the printer - it's not. Instead, in the case of Channel 3 for example, it's the suite of routines that control the printer. The same idea applies to the two-screen area, where instead we are dealing with display routines. Perhaps somewhere down in the deep inky-blackness of your minds, a vague glimmer of awareness is starting to develop. Can streams and channels be used to access your own machine code routines? After all, it does seem as though streams and channels are used to place machine code between Basic and a peripheral? Why indeed? And yes, this is where channels and streams do come into their own.


Now is the time when those who are impatient to rush to their computers and after a quick glance at the manual, smugly begin POKEing the RAM - so as to extend the channel area. After that, a quick trip into the stream data and ... Bob's your uncle. Only he isn't! If only you could get rid of those pesky error codes, and if only the predefined channel specifiers worked. Sadly, you're stuck with playing around with the lower screen, upper screen and printer; and of course, not being a noddy user, you want the thing to point to your own routines, not those of the ROM. Now that you've calmed down I have to tell you that setting up a new channel
can only be done from machine code.
Just as a reference try 10 OPEN #2, "P". RUN this and then try to PRINT something. It prints on the printer, not the screen. So what use are such silly games? Well, just to point out that the '#' commands really do only recognise certain specifiers in Basic.
As long as you stick to what the computer gives you, then you can open every stream and channel, except that they'll be the same. Another aspect of channels is that they can be used to send data in both directions - and the fact we can play silly games actually belies the real potential of using channels. It really is useful to keep in mind that a channel is a set of routines and not a peripheral as such - and a stream is just a path. Its performance lies in the fact that it simply goes from one place to another. No controls are needed; all that has to be done is for the route to be attached to its destination.
Try entering the example program (which if you look closely gives you a two- for- one bargain). It is very simple, just a series of PEEKs into the STRMS area and the CHANS area. However, you'll probably find the information very useful because it shows clearly how Sinclair Research uses streams and channels. One note, however - you should get your address for the start of the channels area by PEEKing the systems variable. I've used a Spectrum without the interface and gone straight in with the start address. Please remember to do as I say, not as I do. By the way,
"Open Channel D." And with that Napoleon Solo and Ilya Whatshisname go steaming into another exciting adventure. Those of you in the over twenty-five bathchair brigade will recognise the Man From Uncle television series as the source of this famous quote. As for those of you too young to remember the series, well ... why worry. After all, you have an all- singing, all-dancing Speccy computer - and yes, you too can "Open Channel D" - well, '4' actually. Or can you?


In fact, channels and streams seem to be the cause of a disproportionate amount of confusion - certainly they seem mis- understood and misrepresented. Many people have been disappointed that simply entering OPEN #4 doesn't give them a new channel. Perhaps one major reason for this is the fact that all the '#' commands are, in fact, stream commands! Despite various attempts to explain what actually happens, this is a commonly held and quite fundamental misunderstanding.
At its simplest, a channel is a routine (or suite of routines) in machine code. A stream is the path by which the channel is joined to or is accessed by the user in Basic. Perhaps the first thing that needs clarifying is the relationship between the channel and the hardware peripheral with which it's commonly associated. This is certainly the place where channels were intended for use by Sinclair Research, but what's that got to do with it? Your Spectrum wouldn't exist if the Speccy was only used for what it was intended. Anyway, of the three channels we can use on the normal Spectrum minus Interface 1, all are hardware orientated (dealing as they do with the upper and lower screen and the printer). It's interesting that the one you can't get at deals with creating workspace.
This use of a channel to access work-

The Streams And Channels Routine

[see separate listing section below]


The Streams And Channels Routine

   4 LET v=-3
   6 PRINT " #  L Byte     H Byte     OFFSET": PRINT "   addr  v
al  addr   val  (addr)"
   7 PRINT
  10 FOR w=1 TO 38 STEP 2
  20 LET a=23567+w
  30 LET b=a+1
  40 IF v>-1 AND v<10 THEN  PRINT ;" ";
  50 PRINT v;TAB 4;a;"  ";PEEK a;: PRINT TAB 15;b;"  ";PEEK b;
  60 PRINT TAB 27;PEEK a+PEEK b*256
  65 LET v=v+1
  70 NEXT w
 100 STOP
 200 LET a=23734
 300 FOR y=1 TO 4
 400 FOR z=1 TO 2
 450 LET b=a+1
 500 PRINT a;" ";PEEK a;TAB 11;: PRINT b;" ";PEEK b;
 550 PRINT TAB 22;PEEK a+PEEK b*256
 600 LET a=a+2
 700 NEXT z
 800 PRINT a;" ";PEEK a;"  -";CHR$ PEEK a;"-"
 900 LET a=a+1
 950 PRINT
1000 NEXT y
1100 PRINT a;" ";PEEK a
1300 STOP

Output From The Streams Program

Output From The Channels Program

 #  L Byte     H Byte     OFFSET
   addr  val  addr   val  (addr)
-3  23568 1    23569  0    1
-2  23570 6    23571  0    6
-1  23572 11   23573  0    11
 0  23574 1    23575  0    1
 1  23576 1    23577  0    1
 2  23578 16   23579  0    16
 3  23580 16   23581  0    16
 4  23582 0    23583  0    0
 5  23584 0    23585  0    0
 6  23586 0    23587  0    0
 7  23588 0    23589  0    0
 8  23590 0    23591  0    0
 9  23592 0    23593  0    0
10  23594 0    23595  0    0
11  23596 0    23597  0    0
12  23598 0    23599  0    0
13  23600 0    23601  0    0
14  23602 0    23603  0    0
15  23604 0    23605  0    0
23734 0    23735 240  61440
23736 1    23737 33   8449
23738 239  - LOAD -
23739 28   23740 205  52508
23741 123  23742 0    123
23743 34  -"-
23744 186  23745 92   23738
23746 201  23747 12   3273
23748 0  -?-
23749 1    23750 0    1
23751 0    23752 0    0
23753 80  -P-
23754 128



small title

the two programs are separate and I've just put them together for convenience.


The first STREAMS program gives a breakdown of the 38 bytes that hold the offset addresses for attaching the streams to channels. This offset number is all-important. Stream 2, for example, is for the normal screen display and a glance at the second printout will show that the screen channel data starts at the sixth byte. Surprise, surprise, the offset number for the second stream is '6'. If we were to change this, for example to 16, then Stream 2 would address the printer channel. In effect this is what you were doing when you entered OPEN #2, "P" earlier - attaching Stream 2 to the printer channel. Anything on that stream will then go to the printer. From here you can see that to open Stream 4 and attach it to Channel 4, address 23582 in the stream data will have to carry 21. This, when added to the base address of the CHANS area, will give you the first byte of the data related to Channel 4 - in our case 23754. At the moment this is holding 128, which is the end marker byte for the CHANS area.
The printout alongside shows just how much can be stored in a set-up like this. Of the five bytes allocated to each channel, the first two are the address of the 'Output' routine, the next two the 'Input' routine and the last byte is the specifier. Even if the specifier is not a true description of what the channel is, it'll still have to be there. Again like the streams in the previous paragraph, inserting your own address is far more than a question of simply POKEing, and I'd advise you to take great care you don't overwrite the Spectrum's own routines. It strikes me as one of the annoying quirks that channels cannot be extended from Basic. Perhaps Sinclair Research wanted to keep down the amount of access that the average user could gain of outside devices - a pity.
In point of fact more than one routine is needed if the new channel is to be opened and used. Besides the routine to actually link the new stream with the new channel, you need to open a space to store the necessary data of the new channel. There's no point going to these lengths if there's no 'Input' or 'Output' routine to be addressed - without these the path to wonderland is useless. By next month I hope to have all that sorted, along with a suitable listing for you. But for those getting impatient, here's a brief run through of the code you need to do the job.
First, HL and BC need to be loaded with the base value of the CHANS variable and the offset respectively. With this you can call the Spectrum's own ROM routine CALL 1655 (Hex). This is a 'make room' routine and it'll be used to create the extra space for the channel data. Coming out of this, HL is holding the address of the start of the new space, and BC the end; swap them around. Use HL to load in the various values you want in the five bytes (remember that you start with the specifier at the highest address). Lastly comes what's probably the trickiest part of the job. Although you've managed to set up your new channel, at the moment it's in limbo with no stream connecting it. It means being careful not to lose the offset while you set up the string. The one advantage is that at least it's a single byte number, and the best bit is that, when this last section of code has been completed, that's it; you can now open a stream to your new channel. Just what the new channel will do is another subject - or perhaps I should say, other subjects. Any ideas?


C R Hall from Mill Hill, London NW7 has written about the 'Tuning-up' article. He says it works fine, and goes on to disclose a piece of information about the BBC Micro (excuse the bad language) showing a 10pF capacitor wired from the modulator to a nearby resistor. He wants to know if the same can be done on a Speccy.
The answer is yes, though the detail is different. On the Spectrum you need a 200µF capacitor wired between the case of the output socket and the earth point on the modulator. The earth point is the wire coming out of the modulator nearest the back and identified by the brown ceramic lead (see diagram).



Digging around some time ago, I came across this little routine. It's rather fun - fun, that is, if you get kicks from wrecking the displays of Spectrums in your local WH Smiths, or causing GBH to migraine sufferers.
Enter as a direct command:
CLEAR 64000

Follow this with another direct command:
POKE 64001,66

Nothing spectacular so far, but a line is needed. Enter:
110 CLOSE #4

and then RUN it. You now have 23.4 seconds of blank screen in which to make yourself scarce.
There seem to be several interesting oddities, and so far no other CLEAR number I have found works - though I suspect there are some which I've not had a chance of looking into at the time of writing. One thing, the number POKEd into 64001 is important (which caused some initial surprise). Other numbers you could use are 3, 5, 80 and 168, though I was amazed when some numbers in the 60s failed to work and just caused a complete crash, minus the pretty effects.
Having blatantly pandered to the intellect of my readers already this month, I'll not insult your intelligence by telling you the common factor of these values. Nevertheless, I hope to have more on this for you next month, either as a product of my own grey matter, or of yours.
Home Contents KwikPik