10. Channel Tables

In our procedure PSI_CLS, we use a channel number in SuperBasic. In assembler, this is no use to us as all internal operations that require a channel (CLS, PAPER etc) require a channel id which is a 32 bit long number which bears no resemblance (or only coincidentally) to a SuperBasic channel number.

In QDOS there is a channel table - for the entire system, and there is the SuperBasic channel table which is used to convert channel numbers into channel ids which is what we require. SuperBasic keeps us away from nasty things like internal representations - assembler does not.

The routine we used above, channel_id, is all that is required to convert a channel number to a channel id. It looks at the SuperBasic channel table and for each channel that has been opened (even if it is now closed) there will be an entry in the channel table. Each entry is $28 bytes long (40 bytes) and has the following format :

Table 7.5. SuperBasic Channel Table Definition

OffsetSizePurpose
$00LongQDOS internal channel id.
$046 bytesGraphics cursor X position (Floating Point format).
$0A6 bytesGraphics cursor Y position (Floating Point format).
$106 bytesTurtle angle (Floating Point format).
$16BytePen status (0 = up or 1 = down).
$20WordCharacter position on line for PRINT and INPUT etc.
$22WordWidth of the channel. Set by WIDTH command in SuperBasic but defaults to 80 when OPEN is called.
$24LongSpare - currently unused.

When a channel is opened in SuperBasic, an entry is created (or reused) in this table. At startup channels #0, #1, and #2 are pre-created and that is all. If you now open #4, a new entry will be created for it. If you open channel #10, then blank entries are created for all the 'in-between' channels (5 to 9) and entry 10 is then created and initialised on top.

A channel that has never been opened can therefore still have an entry in this table - channels 5 to 9 in the above example. All of these use memory so it is advisable to start with 3 and work upwards opening channels as you go, rather than opening #100 or something similar which needlessly wastes 40 bytes of memory for each unused channel.

A channel that is closed, or has never been opened, has a QDOS channel id which is negative

In the Basic variables area in QDOS (to be covered in a later issue - and by the way, I refer to the variables that hold information about SuperBasic, and not variables you create in SuperBasic !) BV_CHBAS holds the offset from A6 to the first entry in the table (ie channel #0) and BV_CHP holds the offset from A6 to the first byte AFTER the last entry in the channel table. Don't forget that these are offsets and that everything in SuperBasic is relative to A6 - simply because by doing this the base address for the job (SuperBasic is just another job in the machine) is held in A6. If everything else is stored as an offset then moving the job in memory is simple as only the A6 register has to be updated.

Take a look at the code for channel_id again and note how we are using addresses that are relative to A6. Make sure that you understand because all fiddling in the bowels of SuperBasic requires that you understand relative addressing.

Most of the time you will only be interested in the conversion from SuperBasic channel number to QDOS channel id.