--- title: "OPEN #, CLOSE #, Channels & Streams – A Tutorial" type: "article" slug: "open-close-channels-streams-a-tutorial" url: "http://localhost/article/open-close-channels-streams-a-tutorial/" markdown_url: "http://localhost/article/open-close-channels-streams-a-tutorial.md" published_at: "2020-10-27T17:13:51+00:00" modified_at: "2026-07-26T12:20:32+00:00" featured_image: url: "http://localhost/wp-content/uploads/2022/04/20230809-041332.jpg" excerpt: "Let’s delve into the mysterious realm of channels and streams and those two odd tokens OPEN # and CLOSE #. These two commands are extremely powerful and have many uses and yet there is nothing at all about them in the TS2068 User Manual except to say that “these and other commands like FORMAT, MOVE,…" category: - name: "Update Magazine" slug: "update-magazine" taxonomy: "category" url: "http://localhost/category/periodicals/update-magazine/" post_tag: - name: "Best of Timex/Sinclair 2068 Articles and Documents" slug: "ts2068best" taxonomy: "post_tag" url: "http://localhost/tag/ts2068best/" - name: "TS 2068" slug: "ts2068" taxonomy: "post_tag" url: "http://localhost/tag/ts2068/" - name: "Tutorial" slug: "tutorial" taxonomy: "post_tag" url: "http://localhost/tag/tutorial/" - name: "Type-in program" slug: "type-in-program" taxonomy: "post_tag" url: "http://localhost/tag/type-in-program/" model: - name: "Timex/Sinclair 2068" slug: "ts-2068" taxonomy: "model" url: "http://localhost/model/ts-2068/" indiv: - name: "Bob Mitchell" slug: "bob-mitchell" taxonomy: "indiv" url: "http://localhost/indiv/bob-mitchell/" publication: "Update Magazine" publication_r: id: 10283 title: "Update Magazine" type: "periodical" url: "http://localhost/periodical/update-magazine/" authors: "Bob Mitchell" authors_r: - name: "Bob Mitchell" slug: "bob-mitchell" taxonomy: "indiv" url: "http://localhost/indiv/bob-mitchell/" issues_articles: - id: 26511 title: "Update October 1988" type: "issue" url: "http://localhost/issue/ts-2068-up-date-october-1988/" pages: "36-39" pubdate: "October 1988" archive_link: false volumeissue: "vn" --- # OPEN #, CLOSE #, Channels & Streams – A Tutorial Let’s delve into the mysterious realm of channels and streams and those two odd tokens OPEN # and CLOSE #. These two commands are extremely powerful and have many uses and yet there is nothing at all about them in the TS2068 User Manual except to say that “these and other commands like FORMAT, MOVE, CAT etc will be used with future peripherals”. Well, by now we know that many of these are indeed used with the disk drive interfaces. But, long before DOSs came along, it was apparent that OPEN # and CLOSE # did have a role to play with the basic machine. Much of this has to do with the opening and closing of channels and streams with respect to the TS2040 printer and the TS2068 keyboard and screen. The TS2068 communicates with peripheral devices with the aid of the channel information area which lies between the system variables and the BASIC program. This area starts at address 26688 and ends at 26708, just short of the program area which starts, normally, at 26710. A short program given in the listing below will print out all the information on channels and streams. Part of its output is shown below as Table 1 (with some explanatory notes); the code has been divided into 5-byte blocks, each block representing one channel. ## Table 1 — Channel Information Area | Address | Chan | Value | Notes | | --- | --- | --- | --- | | 26688 | K | 0 | 1st 2 bytes = ROM add.1280d | | 26689 | | 5 | (5*256+0): ROM PRINT routine. | | 26690 | | 14 | 2nd 2 bytes = ROM add.3086d | | 26691 | | 12 | (12*256+14): get input key. | | 26692 | | 75 | Code for letter “K”. | | 26693 | S | 0 | 1st 2 bytes same as for “K”. | | 26694 | | 5 | | | 26695 | | 191 | 2nd 2 bytes = add. 4543; | | 26696 | | 17 | input routine called. | | 26697 | | 83 | Code for letter “S”. | | 26698 | R | 231 | This block is reserved for | | 26699 | | 10 | use by the computer and | | 26700 | | 191 | is not available to the | | 26701 | | 17 | user. | | 26702 | | 82 | Code for letter “R”. | | 26703 | P | 0 | 1st 2 bytes also point to | | 26704 | | 5 | 1280d: ROM Print routine. | | 26705 | | 191 | Input routine called; | | 26706 | | 17 | (see explanation below). | | 26707 | | 80 | Code for letter “P”. | | 26708 | | 128 | Stop byte. | When the TS2068 is switched on, 21 bytes are copied from address 4522d in the ROM to the channel info area where they may be altered by the user. In the fourth block (Channel “P”), addresses 26703 and 26704 point to the ROM PRINT routine at 1280d (0500h). These are often changed to point elsewhere (eg. in the Aerco prcode, they are changed to <5> and <251> respectively which equates to 64261 (the start of the prcode routine). Once these two bytes have been changed, all printing will go via Channel “P” to the routine. To get back to the TS2040, these two bytes must be restored to <0> and <5> respectively. In Spectrum these 21 start-up bytes are in ROM 5551d and are copied to the Spectrum channel info area which resides at 23734 to 23754. Addresses 23749 and 23750 equate to 26703 and 26704 in the TS2068. Summing up, each block represents a channel and contains five bytes: the first two represent the address of the called output routine (normally in the ROM); bytes 3 and 4 represent the address of the called input routine; finally, byte 5 is the code of the character representing the channel. Channel “S” stands for “screen” and handles the output to the monitor or TV display. Channel “P” stands for the “printer” and handles output to this peripheral. Channel “K” stands for the keyboard but handles both output and input; it inputs from the keyboard but also outputs to the lower part of the screen display. When the PRINT command is used, the output goes through channel “S” to the main (upper) part of the screen. By careful use of the OPEN # command, the output can be made to go through any other channel. Streams are associated with a specified channel and there are 16 streams available (0 to 15). Using the PRINT command normally sends the output through stream “2” to channel “S”. To make the PRINT command go to channel “P”, it is only necessary to open stream 2 to channel “P”. This is done by the command . Note that this instruction has two arguments, the former first tells the computer which stream is being altered and the latter identifies the single character of the channel to which the stream is to be directed. If you type then , the PAUSE 0 command prevents the input routine being called which would print an error report (bytes at addresses 26705 and 26706 call the ROM routine at address 4543). Without the PAUSE 0, the printing would be immediately erased. At switch on, only four of the 16 streams are opened. ``` Stream 0 points to channel "K" Stream 1 points to channel "K" Stream 2 points to channel "S" Stream 3 points to channel "P" ``` When a stream has been opened to a different channel, it will continue to do what it has been directed to do until told otherwise. A channel may be closed by the command where n is any number from 0 to 15. Also, a channel may be closed by pointing the stream to its start up channel. For example, if stream 3 has been opened to channel “S”, it may be closed by the command . This example would send all LPRINT and LLIST commands to the screen until it is told to revert to normal. This is particularly useful to the programmer during the debugging process to look at the results of the LPRINT commands on the screen rather than waste printer paper. When a stream has been opened to the printer, the edit line (lower screen area) is unaffected; in fact, any PRINT #0 or PRINT #1 commands will continue to display on the lower screen. Use of the hash symbol <#> followed by a <0> or <1> changes the print stream to the lower screen. PRINT, LIST, INPUT and INKEY$ may all have their output affected this way; their default value is stream 2 (the upper screen); that is to say, PRINT #2 is the same as PRINT and PRINT #3 is the same as LPRINT, etc. Type in the following listing and save it; then use it anytime you want to check the current status of channels and streams. ## BASIC Listing ``` 3 REM This program works in either TS2068 or Spectrum 5 REM ======================== 6 REM Use GO TO 10 for info on channels & streams. 7 REM Use GO TO 200 to PEEK stream info in system variables. Use GO TO 220 to PEEK channel info area up to start of program area. 9 REM ======================== 10 LET a=PEEK 23631+256*PEEK 23632: LET b=a 20 IF PEEK a=128 THEN GO TO 70 30 PRINT "CHANNEL ";CHR$ (PEEK (a+4)) 40 PRINT "Output Address=";PEEK a+256*PEEK (a+1) 50 PRINT "Input Address=";PEEK (a+2)+256*PEEK (a+3) 60 PRINT : LET a=a+5: GO TO 20 70 FOR a=23574 TO 23605 STEP 2 80 PRINT "Stream ";(a-23574)/2;TAB 10; 90 IF PEEK a+256*PEEK (a+1)=0 THEN PRINT "CLOSED": NEXT a: STOP 100 LET c=(PEEK a+256*PEEK (a+1))+b+3 110 PRINT "points to Channel ";CHR$ PEEK c: NEXT a 120 STOP 130 RANDOMIZE USR 100: SAVE "chans.B1" LINE 10 140 STOP 200 FOR i=23568 TO 23605: PRINT i,PEEK i: NEXT i 210 STOP 220 LET prog=PEEK 23635+256*PEEK 23636 230 FOR i=b TO prog-1: PRINT i,PEEK i;TAB 20;CHR$ PEEK i AND PEEK i>=32 AND PEEK i<=90: NEXT i ``` The annotations printed in the right-hand column beside the listing: | Line | Note as printed | | --- | --- | | 10 | start of CHANS from sys variables | | 20 | last byte in table | | 30 | channel letter | | 40 | output address | | 50 | input address. | | 80 | stream number. | | 90 | closed channel | | 100 | channel letter | | 130 | Larken SAVE routine | | 200 | addresses of channels attached to streams. | | 220 | start of prog area | | 230 | examines chan info area up to start of prog area | The FOR…NEXT loop in line 200 will display a copy of 38 bytes in the system variables area containing the address of channels attached to streams. Each stream holds two bytes which accounts for 32 bytes and the extra 6 are used by the internal editor and automatic listing routines. Each two bytes contains a relative displacement, from the byte before the channel info area, to the channel that is pointed to. A zero means that the stream is closed. For Larken users, note the extensive use of OPEN # in the extended BASIC commands available and particularly note that when any or all windows or large printer channels are opened, 38 bytes (total) of memory are added to the channel information area. This changes the location of the start of the program area and can cause a problem if there is machine code in a REM statement in the first program line. (This problem can be avoided by PEEKING the start of the prog area and then using this value plus 5 as the call address for the machine code routine in the REM statement; eg, ). In these 38 bytes which you can examine by using line 220 of the listing, you will find that new channels have been set up at the beginning of what was the start of the program area. An interesting and illuminating exercise is suggested for Larken users: - ,ie, the listing above. - Open some of the Larken extended BASIC channels. - Try . - Then . - Then . - Then . - Now use the listing above to look at what has happened. Try doing the same thing with the Spectrum emulator in place, if you have one. I’ll leave the heavy thinking to you at this point. What I have written will pose some other questions and I look forward to someone else expanding on this theme in some future issue.