QL5BQLboot ŌØc @ @$P@ €‚„†ˆŠŒŽ ƒ…‡‰‹‘’’’’’’’’’’’’’’’’’’’’ųųż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’                           !000@PPPPPPPP``````pppppppp€€                 °°°°°°ĄĄĄĄĄĄĄĄĄĄ Ą Ą Ą Ą ĄĄĄĄĄĄĄĄĄĄĄĄŠŠąąąąšöööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööö                                  ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 80000@@@@@@@@@@ @ @ @ @ @@@@@@@@@@@@@@@PPPPPPPPPP P `````pppppp€€€€€€      !"#$%&'()*+,-./01öööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööö23456789:;<=>?@ABCDEF                        °°°°°°°°°° ° ° ° ĄĄĄĄĄĄĄĄĄĄ Ą Ą Ą Ą ĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄĄ Ą!Ą"Ą#Ą$Ą%Ą&Ą'Ą(Ą)Ą*Ą+Ą,Ą-Ą.Ą/Ą0Ą1Ą2Ą3Ą4Ą5Ą6Ą7Ą8Ą9Ą:Ą;Ą<ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’öööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööö’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’żöööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööö’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’ż’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’ööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööÓBOOTUignore moveq #1,d0 cmp.l d0,d3 ; =1 ? beq.s disysd ; -> SIG_DFööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööpossible to test it against every other piece of software or hardware. Please let us know if you discover any incompatibilities so that we can try to sort them out.3. BRIEF DESCRIPTION OF THE NEW COMMANDSABS_POSITION - Set file position absolute.BYTES_FREE - How much free memory is left, in bytes.CHECK - Test to see if a machine code PROC/FN exists.DEV_NAME - Scan the Directory Device list, returning the next name.DISPLAY_WIDTH - How many bytes are used to hold one , floatThe given float value is converted to the internal QDOS format for floating point numbers and those 6 bytes are sent to the given channel number. The full range of QL numbers can be sent including all the negative values. GET_FLOAT will return negative values correctly (unless an error occurs).PUT_LONG #channel, longThe long value given is sent as a sequence of four bytes to the channel. Negative values can be put and these will be returned correctly by GET_LONG unless any errors occur. /N¹üj.P ¼0Ž€ KR‹H€HĄ,¼¼0m¼¼9oʼ¼.f† K100 REMark QL BOOT 110 PRINT #0,"Loading QL BOOT" 120 PRINT #0,"Loading TK2" 130 base=RESPR(16348): LBYTES flp1_tk2_ext,base: CALL base 140 TK2_EXT 150 PRINT #0,"Loading Pointer Environment" 160 LRESPR flp1_ptr_gen 170 LRESPR flp1_wman 180 LRESPR flp1_hot_rext 190 PRINT #0,"Loading DJTK" 200 LRESPR flp1_djtoolkit_bin 210 PRINT #0,"Loading TTK" 220 LRESPR flp1_turbo_tk_code 230 PRINT #0,"Loading Env. Variables" 240 LRESPR flp1_env_bin 250 PRINT FILLMEM_W SCREEN_BASE(#0), 16 * 1024, 0or this :-1020 FILLMEM_L SCREEN_BASE(#0), 8 * 1024, 0and the screen will change to all black. Note how the second parameter is halved each time, this is because there are half as many words as bytes and half as many longs as words.The fastest is FILLMEM_L and the slowest is FILLMEM_B. When you use FILLMEM_W or FILLMEM_L you must make sure that the start_address is even or you will get a bad parameter error. FILLMEM_B does not care about its start_address being #0,"Loading Path" 260 LRESPR flp1_pth_rext 270 PRINT #0,"Loading QLib Runtimes" 280 LRESPR flp1_qlib_run_336mod 290 PRINT #0,"Loading Signal Ext." 300 LRESPR flp1_sigext30_rext 310 PRINT #0,"Done Loading Boot" Ą¼gF ®\’¶fR®’n`. ®L’¶g ®T’¶f"T®’n Ą¼€gpX`pxS… E€S… E¼0-E’r .’䐅-@’Ą`ˆ¼`ˆ¼ˆ¼` ˆ¼ˆ¼ Ą¼f-|’Äp///.’Ä/ Hn’:Hn’jHn’ĄN¹ś¬Oļ" Ё-@’®`  X€*€ @YHS…"EØ`b X€*€ @YH*f*<éV Ą¼f //N¹ FX" Ё` /.’ÄHx/N¹óOļ -@’äf Š®’Ä even or not.FILLMEM_B truncates the value to the lowest 8 bits, FILLMEM_W to the lowest 16 bits and FILLMEM_L uses the lowest 32 bits of the value. Note that some values may be treated as negatives when PEEK'd back from memory. This is due to the QL treating words and long words as signed numbers.FLUSH_CHANNEL #channelThis procedure makes sure that all data written to the given channel number has been 'flushed' out to the appropriate device. This means that if a power cut occurs, then no data willöööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööö be lost.MOVE_MEM source, destination, lengthThis procedure will copy the appropriate number of bytes from the given source address to the destination address. If there is an overlap in the addresses, then the procedure will notice and take the appropriate action to avoid corrupting the data being moved. Most moves will take place from source to destination, but in the event of an overlap, the move will be from (source + length -1) to (destination + length -1).This procedure tries to do the moving a-@’ä`S… E«’’ .’䐅-@’ĄB®’v-n’Ą’z-E’~B®’jB®’n-|’®B®’ŖAī’^-Hvrm1qdf0”Ā%F&X- DJToolkit, page nnn -DJTOOLKITWRITTEN BY NORMAN DUNBAR, 1993-94This has been produced at the suggestion of Dilwyn Jones in an effort to provide QLiberator users with some of the file & memory handling utilities, direct file access (in internal format) & positioning commands that are found in the Turbo Toolkit and Toolkit 2 etc. In addition, there are a few routines not (yet) found in any other toolkit.All of s fast as possible and checks the addresses passed as parameters to see how it will do this as follows :-1. If both addresses are odd, move one byte, increase the source & destination addresses by 1 and drop in to treat them as if both are even, which they now are !2. If both addresses are even, calculate the number of long word moves (4 bytes at a time) that are to be done and do them. Now calculate how many single bytes need to be moved (zero to 3 only) and do them.3. If one address is odd and the othe procedures and functions in this toolkit can be compiled by QLiberator, but one of the functions, DEV_NAME, cannot be compiled by Turbo or Supercharge as it modifies its parameter as well as returning a string.This toolkit may be supplied as part of a commercial or shareware or public domain program which has been QLiberator compiled. It should be supplied linked to the object program, not loaded by a BOOT program.To link this toolkit into a QLiberator compiled program, use the following compiler dither is even the move can only be done one byte at a time, this is quite a lot slower than if long words can be moved.The calculations to determine which form of move to be done adds a certain overhead to the function and this can be the slowest part of a memory move that is quite small.MOVE_POSITION #channel, relative_positionThis is a similar procedure to ABS_POSITION, but the file pointer is set to a position relative to the current one. The direction given can be positive to move forward in thrective somewhere near the start of the program to be compiled. The drive name is where the compiler can find the toolkit file.110 REMark $$asmb=FLP2_DJToolkit_BIN,0,121. COPYRIGHT NOTICE AND DISCLAIMERThis software is Copyright  Norman Dunbar 1993-94 and may be freely copied as QL freeware.You can make backup copies using whatever method you have and normally use (e.g. WCOPY from Toolkit 2). DJToolkit is not copy protected (except by copyright law).While all reasonable care has been taken to ee file, or negative to move backwards. The channel must of course be opened to a file on a directory device. If the position given would take you back to before the start of the file, the position is left at the start, position 0. If the move would take you past the end of file, the file is left at end of file.After a MOVE_POSITION command, the next access to the given channel, whether read or write, will take place from the new position.POKE_FLOAT address, valueThis procedure will poke the 6 bytnsure that this program and its manual are accurate and do not contain any errors, neither the author nor publisher will in any way be liable for any direct, indirect or consequential damage or loss arising from the use of, or inability to use, this software or its documentation. We reserve the right to constantly develop and improve our products.2. QUESTIONS ABOUT THE TOOLKITWHAT IS A TOOLKIT?A toolkit is a set of BASIC extensions, new commands and functions which add to the number of "words" underes that the QL uses to represent a floating point variable into memory at the given address. The address can be odd or even as the procedure can cope either way.POKE_STRING address, stringThis procedure simply stores the strings contents at the given address. Only the contents of the string are stored, the 2 bytes defining the length are not stored. The address may be odd or even.If the second parameter given is a numeric one or simply a number, beware, QDOS will convert it to the format that would stood by the QL's BASIC language. These new extensions greatly add to the power and versatility of SuperBASIC, by adding the facility to perfrom new actions, or by simplifying a task which is difficult to program at the momentCAN I USE THE TOOLKIT IN MY OWN PROGRAMS?Yes, you can use these commands both in interpreted BASIC programs and compiled BASIC programs, but see the note above regarding use with Turbo.DOES IT WORK WITH OTHER TOOLKITS?We have tried to ensure that there is no clash, but it is imbe seen if the number was PRINTed before storing it at the address. For example, 1 million would be '1E6' which is arithmetically the same, but characterwise, very different.PUT_BYTE #channel, byteThe given byte is sent to the channel. If a byte value larger than 255 is given, only the lowest 8 bits of the value are sent. The byte value written to the channel will always be between 0 and 255 even if a negative value is supplied. GET_BYTE returns all negative values as positive.PUT_FLOAT #channelw_many, valueThese procedures are provided so that a quick and simple way to fill up areas of memory is available to DJToolkit users. The 3 variations stuff bytes, words or long words into memory as required.Note that the second parameter is the count of how many bytes, words or long words you want to put into the memory area starting at 'start_address'.For example, the screen memory is 32 kilobytes long. To fill it all black, try this :-1000 FILLMEM_B SCREEN_BASE(#0), 32 * 1024, 0or this :-1010whether the negative result is a valid long or float, or if an error occurred.Functions that return strings, for example DEV_NAME, cannot return an error code, so if any errors occur in them, they will act in a similar way to procedures and cause the program to stop with an appropriate error message.Any function can cause an error that will stop your program from running if something goes wrong when the function tries to fetch its parameters, in this case the function will simply 'fall over' and QDOS wiscreen line ?DJ_OPEN - Opens a file, returns error or channel id.DJ_OPEN_IN - Ditto, similar to OPEN_IN.DJ_OPEN_NEW - Creates a file, returns channel id or error.DJ_OPEN_OVER - Overwrites a file, returns error or channel idDJ_OPEN_DIR - Opens a device directory for access.DJTK_VER$ - Return the toolkit version number as a string.FETCH_BYTES - Get some bytes from a channel.FILE_BACKUP - Get the backup date for a specific file.FILE_DATASPACE - Get the fPUT_STRING #channel, stringThe string parameter is sent to the appropriate channel as a two byte word giving the length of the data then the characters of the data. If you send a string of zero length, LET A$ = "" for example, then only two bytes will be written to the file. See POKE_STRING for a description of what will happen if you supply a number or a numeric variable as the second parameter. As with all QL strings, the maximum length of a string is 32kbytes.PUT_WORD #channel, wordThe supplile's dataspace.FILE_LENGTH - Get the file's length.FILE_POSITION - Get the current position in the file.FILE_TYPE - Get the file's type.FILE_UPDATE - Get the file's update date.FILLMEM_B - Fill memory with a byte value.FILLMEM_L - Fill memory with a long value.FILLMEM_W - Fill memory with a word value.FLUSH_CHANNEL - Flush the data on a channel to a device.GET_BYTE - Fetch one byte from a channel.GET_FLOAT - Fetch 6 bytes from a channel.ied word is written to the appropriate channel as a sequence of two bytes. If the word value supplied is bigger than 65,535 then only the lower 16 bits of the value will be used. Negative values will be returned by GET_WORD as positive.RELEASE_HEAP addressThe address given is assumed to be the address of a chunk of common heap as allocated earlier in the program by RESERVE_HEAP. In order to avoid crashing the QL when an invalid address is given, RELEASE_HEAP check first that there is a flag at addressGET_LONG - Fetch 4 bytes from a channel.GET_STRING - Fetch a QDOS string from a channel.GET_WORD - Fetch 2 bytes from a channel.KBYTES_FREE - How much free memory is left in Kbytes.LEVEL2 - Test whether level 2 drivers are present on a channel.MAX_CON - Returns the absolute limits of a SCR or CON channel.MAX_DEVS - Counts the number of directory devices. See DEV_NAME.MOVE_MEM - Move memory around.MOVE_POSITION - Set a file position rel-4 and if so, clears the flag and returns the memory back to the system. If the flag is not there, or if the area has already been released, then a bad parameter error will occur.It is more efficient to RELEASE_HEAP in the opposite order to that in which it was reserved and will help to avoid heap fragmentation.SET_XINC #channel, incrementSET_YINC #channel, incrementThese two functions change the spacing between characters horozontally, SET_XINC, or vertically, SET_YINC. This allows slightly morative to its current one.PEEK_FLOAT - Read 6 bytes from memory into a float variable.PEEK_STRING - Get bytes from memory into a string.POKE_FLOAT - pokes a floating point variable into memory.POKE_STRING - Store the string in memory at a given address.PUT_BYTE - Send 1 byte to a channel.PUT_FLOAT - Send 6 bytes to a channel.PUT_LONG - Send 4 bytes to a channel.PUT_STRING - Send a QDOS string to a channel.PUT_WORD - Send 2 bytes to a channele information to be displayed on the screen. SET_XINC allows adjacent characters on a line of the screen to be positioned closer or further apart as desired. SET_YINC varies the spacing between the current line of characters and the next.By choosing silly values, you can have a real messy screen, but try experimenting with OVER as well to see what happens. Use of the MODE or CSIZE commands in SuperBasic will overwrite your new values.USE_FONT #channel, font1_address, font2_addressThis is a procedure.QPTR - Is the Pointer Environment available ?READ_HEADER - Read the header for a file into a buffer.RELEASE_HEAP - Remove some space allocated with RESERVE_HEAP.RESERVE_HEAP - Get some Common Heap space for a program to use.SCREEN_BASE - Find out where the screen memory starts for a channel.SCREEN_MODE - Returns the current screen mode, 4 or 8.SEARCH_C - Look in memory for a string, case is considered.SEARCH_I - Ditto, but case is ignored.SET_HEAD that will allow your programs to use a character set that is different from the standard QL fonts. The following example will suffice as a full description :-1000 REMark Change the character set for channel #11010 :1020 REMark Reserve space for the font file1030 size = FILE_LENGTH('flp1_font_file')1040 IF size < 01050 PRINT 'Font file error ' & size1060 STOP1070 END IF1080 :1090 REMark Reserve space to load font into1200 font_address = RESERVE_HEAP(size)1210 IF font_address < 01220 PER - Set the header for a file.SET_XINC - Change horozontal spacing between characters.SET_YINC - Change vertical spacing between lines of characters.SYSTEM_VARIABLES - Find out where the system variables are.USE_FONT - Change the fonts used by a channel.WHERE_FONTS - Find the addresses of the two fonts used on a channel.In the following descriptions, all parameters must be supplied as there are no defaults, in addition, when a channel number is being passed, eitRINT 'Heap error ' & font_address1230 STOP1240 END IF1250 :1260 REMark Load the font1270 LBYTES flp1_font_file, font_address1280 :1290 REMark Now use the new font1300 USE_FONT #1, font_address, 0.......Rest of program9000 REMark Reset channel #1 fonts9010 USE_FONT #1, 0, 09020 :9030 REMark Release the storage space9040 RELEASE_HEAP font_addressIn the above example, only one font has been changed for the channel, there are usualy 2 fonts in use on each channel. The procedure allows you ther as a number or as a variable, it must be preceded by a hash (#).4. THE NEW PROCEDURESThe following section gives details of all the new procedures, (not functions) in more detail. In the event of an error occurring in the procedures your program will stop with an error message.ABS_POSITION #channel, positionThis procedure will set the file pointer to the position given for the file attached to the given channel number. If you attempt to set the position for a screen or some other non-directoo change 1 or both depending upon the application and to reset them back to the standard fonts at any time. The value of zero for any of the addresses will switch to the standard font found in the QL's ROM.Many QL programs come with a number of font files, however, do not try to use the special type of fonts that come with many drawing or desk top publishing programs, such as Page Designer. These can sometimes be recognised by the file name which will include something like '_hires' or '_hdf' in the name.ry device channel, you will get a bad parameter error, as you will if position is negative.If the position given is 0, the file will be positioned to the start, if the position is a large number which is greater than the current file size, the position will be set to the end of fileand no error will occur.After an ABS_POSITION command, all file accesses will take place at the new position.FILLMEM_B start_address, how_many, valueFILLMEM_W start_address, how_many, valueFILLMEM_L start_address, ho Ordinary QDOS font files as supplied with Digital Precision's Lightning can be loaded and used, as can the normal font files from Page Designer and the like.5. THE NEW FUNCTIONSThe following section gives details of the new functions. Note that all functions which return a numeric value may also return a QDOS error code. This is usually a negative number. However, you should be aware that the functions GET_LONG and GET_FLOAT can return negative values as a valid result. There is no way to determine urn the exact number of bytes required to step from one line of pixels to the next. Never assume that QDOS programs will only ever be run on a QL. What will happen when new Graphics hardware arrives ? This function will still work, assuming that the unit uses standard QDOS channel definition blocks etc.For the technically minded, the word at offset $64 in the SCR_ or CON_ channel's definition block is returned. This is called SD_LINEL in 'Tebby Speak' and is mentioned in Jochen Merz's QDOS Reference Manuaame as FETCH_BYTES(#channel, GET_WORD(#channel)).WARNING - JM and AH ROMS will give a 'Buffer overflow' error if the length of the returned string is more than 128 bytes. This is a fault in QDOS, not DJToolkit. The demos file has a 'fix' for this problem.word = GET_WORD(#channel)The next two bytes are read from the appropriate file and returned as an integer value. This is equivalent to CODE(INKEY$(#channel)) * 256 + CODE(INKEY$(#channel)). See the caution above for GET_BYTE as it applies here as wl and the QL Technical Manual by Tony Tebby et al. Andrew Pennel's book, the QDOS Companion gets it wrong on page 61, guess which one I used first !v$ = DJTK_VER$This simply sets v$ to be the 4 character string 'n.nn' where this gives the version number of the current toolkit. If you have problems, always quote this number when requesting help.channel = DJ_OPEN('filename') [open existing file for exclusive use]channel = DJ_OPEN_IN('filename') [open existing file for shared use]channell. Any negative numbers returned will always be an error code.memory = KBYTES_FREEThe amount of memory considered by QDOS to be free is returned rounded down to the nearest kilo byte. See BYTES_FREE above also. The value in KBYTES_FREE may not be equal to BYTES_FREE/1024 as the value returned by KBYTES_FREE has been rounded down.present = LEVEL2(#channel)If the device that has the given channel opened to it has the level 2 drivers, then present will be set to 1, otherwise it will be set to 0ll stop your program with an error. This should actually never happen, but then again ...I have tried to make the functions as friendly as possible so that an error code is returned whenever possible, but if something does go wrong while fetching the parameters, who knows what state the maths stack is in and so it is best to let QDOS handle the problem.oops = CHECK('name')If name is a currently loaded machine code procedure or function, then the variable oops will be set to 1 otherwise it will be the amount of dataspace that that program requires to run, if the file is not an EXEC'able file, the result is undefined, meaningless and probably zero. If the result is negative, there has been an error and the QDOS error code has been returned.fl = FILE_LENGTH(#channel)fl = FILE_LENGTH('filename')The actual file length is returned, as above, the file may be open, in which case simply supply the channel number, or closed, supply the filename in quotes. If the returned value is negative, then it isset to 0. This is a handy way to check that an extension command has been loaded before calling it. In a Turbo'd or Supercharged program, the EXEC will fail and a list of missing extensions will be displayed, a QLiberated program will only fail if the extension is actually called.memory = BYTES_FREEThis simple function returns the amount of memory known by the system to be free. The answer is returned in bytes, see also KBYTES_FREE below. For the technically minded, the free memory is consider a QDOS error code.where = FILE_POSITION(#channel)This function will tell you exactly where you are in the file that has been opened, to a directory device, as #channel, if the result returned is negative it is a QDOS error code. If the file has just been opened, the result will be zero, if the file is at the very end, the result will be the same as calling FILE_LENGTH(#channel) - 1, files start at byte zero remember.ft = FILE_TYPE(#channel)ft = FILE_TYPE('filename')This function returns the ed to be that between the addresses held in the system variables SV_FREE and SV_BASIC.device$ = DEV_NAME(address)This function must be called with a floating point variable name as its parameter. The first time this function is called, address must hold the value zero, on all other calls, simply pass address UNCHANGED back. The purpose of the function is to return a directory device name to the variable device$, an example is worth a thousand explanations.1000 addr = 01010 REPeat loop1020 PRfiles type byte. The various types currently known to me are :0 = BASIC, CALL'able machine code, an extensions file or a DATA file.1 = EXEC'able file.2 = SROFF file used by linkers etc, a C68 Library file etc.3 = THOR hard disc directory file. (I think !)4 = A font file in The Painter5 = A pattern file in The Painter6 = A compressed MODE 4 screen in The Painter11 = A compressed MODE 8 screen in The Painter255 = Level 2 driver directory or sub-directory file, Miracle hard disc directory file.TherINT "<" & DEV_NAME(addr) & ">"1030 IF addr = 0 THEN EXIT loop: END IF1040 END REPeat loopThis small example will scan the entire directory device driver list and return one entry from it each time as well as updating the value in 'addr'. The value in addr is the start of the next device driver linkage block and MUST NOT BE CHANGED except by the function DEV_NAME. If you change addr and then call DEV_NAME again, the results will be very unpredictable.The check for addr being zero is done as this is te may be others.fu = FILE_UPDATE(#channel)fu = FILE_UPDATE('filename')This function returns the date that the appropriate file was last updated, either by PRINTING to it, SAVING it or editing it using an editor etc. This date is set in all known QLs.byte = GET_BYTE(#channel)Reads one character from the file attached to the channel number given and returns it as a value between 0 and 255. This is equivalent to CODE(INKEY$(#channel)). BEWARE, PUT_BYTE can put negative values to file, for ehe value returned when the final device name has been extracted, in this case the function returns an empty string for the device. If the test was made before the call to DEV_NAME, nothing would be printed as addr is zero on entry to the loop.Please note, every QL has at least one device in the list, the 'MDV' device and some also have a device with no name as you will see if you run the above example (not the last one as it is always an empty string when addr becomes zero).The above example will only xample -1 is put as 255, GET_BYTE will return 255 instead of -1. Any negative numbers returned are always error codes.float = GET_FLOAT(#channel)Reads 6 bytes from the file and returns them as a floating point value. BEWARE, if any errors occur, the value returned will be a negative QDOS error code. As GET_FLOAT does return negative values, it is difficult to determine whether that returned value is an error code or not. If the returned value is -10, it could actually mean End Of File, this is about tshow directory devices, those that can have DIR used on them, or FORMAT etc, such as WIN, RAM, FLP, FDK etc, however, it cannot show the non-directory devices such as SER, PAR or NUL, if you have Lightning, as these are in another list held in the QL.From version 1.14 of DJToolkit onwards, there is a function that counts the number of directory devices present in the QL. See MAX_DEVS below for details.bytes_in_a_line = DISPLAY_WIDTHThis function can be used to determine how many bytes of the QL'she only error code that can be tested for.long = GET_LONG(#channel)Read the next 4 bytes from the file and return them as a number between 0 and 2^32 -1 (4,294,967,295 or HEX FFFFFFFF unsigned). The returned value is equivalent to the following fragment of SuperBasic code :2100 REMark Get a long word from the open channel2110 long = 02120 FOR x = 1 TO 42130 IF EOF(#channel) THEN EXIT x: END IF2140 long = long * 256 + CODE(INKEY$(#channel))2150 END FOR xBEWARE, the same problem with ne memory are used to hold the data in one line of pixels on the screen. Note that the value returned has nothing to do with any window width, it always refers to the total screen display width.Why include this function I hear you think ? If you run an ordinary QL, then the result will probably always be 128 as this is how many bytes are used to hold a line of pixels, however, many people use Atari ST/QLs and these have a number of other screen modes for which 128 bytes is not enough. This function will retgatives & error codes applies here as well as GET_FLOAT.a$ = GET_STRING(#channel)Read the next 2 bytes from the file and assuming them to be a QDOS string's length, read that many characters into a$. The two bytes holding the string's length are NOT returned in a$, only the data bytes. The subtle difference between this function and FETCH_BYTES is that this one finds out how many bytes to return from the channel given, FETCH_BYTES needs to be told how many to return by the user. GET_STRING is the shis is a fault with QDOS and not with DJToolkit. See the demos file for a 'fix' to this problem.bk = FILE_BACKUP(#channel)bk = FILE_BACKUP('filename')This function reads the backup date from the file header and returns it into the variable bk. The parameter can either be a channel number for an open channel, or it can be the filename (in quotes) of a closed file. If the returned value is negative, it is a normal QDOS error code. If the value returned is positve, it can be converted to a string bs function, the contents of the buffer will be as follows :Buffer + 0 file length 4 bytes long (see FILE_LENGTH)Buffer + 4 file access 1 byte long - currently zeroBuffer + 5 file type 1 byte long (see FILE_TYPE)Buffer + 6 file dataspace 4 bytes long (see FILE_DATASPACE)Buffer + 10 unused 4 bytes longBuffer + 14 name length 2 bytes long, size of filename Buffer + 16 filename 36 bytes longDirectory devices also have the following additionae calling DATE$(bk). In normal use, a files backup date is never set by QDOS, however, users who have WinBack or a similar backup utility program will see proper backup dates if the file has been backed up.ds = FILE_DATASPACE(#channel)ds = FILE_DATASPACE('filename')This function returns the current dataspace requirements for the file opened as #channel or for the file which has the name given, in quotes, as filename. If the file is an EXEC'able file (See FILE_TYPE) then the value returned will be l data :Buffer + 52 update date 4 bytes long (see FILE_UPDATE)Buffer + 56 reference date 4 bytes long - see belowBuffer + 60 backup date 4 bytes long (see FILE_BACKUP)Miracle Systems hard disc's users and level 2 users will find the files version number stored as the the 2 bytes starting at buffer + 56, the remaining 2 bytes of the reference date seem to be hex 094A or decimal 2378 which has no apparent meaning, this of course may change at some point !This function returns an eel = DJ_OPEN_NEW('filename') [create a new file foe exclusive use]channel = DJ_OPEN_OVER('filename') [overwrite an existing file]channel = DJ_OPEN_DIR('filename') [open device directory or sub-directory]All of these functions return the SuperBasic channel number if the channel was opened ok. If any error occurred, the channel number will be negative. You can use this to check whether the open was successful or not. The filename must be supplied as a variable name, file$ for example, or in quotes,. The level 2 drivers allow such things as sub_directories to be used, when a DIR is done on one of these devices, sub-directories show up as a filename with '->' at the end of the name. Gold Cards and later models of Trump cards have level 2 drivers. Microdrives don't.error = MAX_CON(#channel%, x%, y%, xo%, yo%)If the given channel is a 'CON_' channel, this function will return a zero in the variable 'error'. The integer variables, 'x%', 'y%', 'xo%' and 'yo%' will be altered by the function, to retu 'flp1_fred_dat'.They all work in a similar manner to the normmal SuperBasic OPEN procedures, but, DJ_OPEN_DIR is new.I am grateful to Simon N. Goodwin for his timely article in QL WORLD volume 2, issue 8 (marked Vol 2, issue 7 !!!). I had been toying with these routines for a while and was aware of the undocumented QDOS routines to extend the SuperBasic channel table. I was, however, not able to get my routines to work properly. Simon's article was a great help and these functions are based on that artrn the maximum size that the channel can be WINDOW'd to.'x%' will be set to the maximum width, 'y%' to the maximum depth, 'xo%' and 'yo%' to the minimum x co-ordinate and y co-ordinate respectively.For the technically minded reader, this function uses the IOP_FLIM routine in the pointer Environment code, if present. If it is not present, you should get the -15 error code returned. (BAD PARAMETER).how_many = MAX_DEVSThis function returns the number of installed directory device drivers in your QL.icle. Thanks Simon.The OPEN routines work as follows :1000 REMark open our file for input1010 :1020 chan = DJ_OPEN_IN('filename')1030 IF chan < 01040 PRINT 'OOPS, failed to open "filename", error ' & chan1050 STOP1060 END IF1070 :1080 REM process data in file here ....DJ_OPEN_DIR is a new function to those in the normal QL range, and it works as follows :-1000 REMark read a directory1010 :1020 INPUT 'Which device ';dev$1030 chan = DJ_OPEN_DIR(dev$)1040 IF chan < 01050 PRINT 'Ca It can be used to DIMension a string array to hold the device names as follows :-1000 REMark Count directory devices1010 :1020 how_many = MAX_DEVS1030 :1040 REMark Set up array1050 :1060 DIM device$(how_many, 10)1070 :1080 REMark Now get device names1090 addr = 01100 FOR devs = 1 to how_many1110 device$(devs) = DEV_NAME(addr)1120 IF addr = 0 THEN EXIT devs: END IF1130 END FOR devsAs there is a secondary check to ensure that we don't exceed the list of devices, line 1120, you can, if yonnot open ' & dev$ & ', error ' & chan1060 STOP1070 END IF1080 :1090 CLS1100 REPeat dir_loop1110 IF EOF(#chan) THEN EXIT dir_loop1120 a$ = FETCH_BYTES(#chan, 64)1130 size = CODE(a$(16)): REMark Size of file name1140 PRINT a$(17 TO 16 + size): REMark file name1150 END REPeat dir_loop1160 :1170 CLOSE #chan1180 STOPIn this example, no checks are done to ensure that the device actually exists, etc. You could use DEV_NAME to check if it is a legal device. The data being read from u wish, DIM the array slightly larger than required. The above routine will let you fill up the array DEVICE$ with the names of all the currently installed directory devices. (FLP, RAM etc). Note that on some (all ?) QLs there seems to be a device with a null name.value = PEEK_FLOAT(address)This function returns the floating point value represented b y the 6 bytes stored at the given address. BEWARE, although this function cannot detect any errors, if the 6 bytes stored at 'address' are not a proper fa device directory file must always be read in 64 byte chuncks as per this example.Each chunk is a single directory entry which holds a copy of the file header for the appropriate file. Note, that the first 4 bytes of a file header hold the actual length of the file but when read from the directory as above, the value if 64 bytes too high as it includes the length of the file header as part of the length of a file.The above routine will also print blank lines if a file has been deleted from the directorloating point value, the QL can crash. The crash is caused by QDOS and not by PEEK_FLOAT. This function should be used to retrieve values put there by POKE_FLOAT mentioned above.a$ = PEEK_STRING(address, length)The characters in memory at the given address are returned to a$. The address may be odd or even as no word for the length is used, the length of the returned string is given by the length parameter. This is the opposite to the POKE_STRING command described above and equivalent to the followiy at some point. Deleted files have a name length of zero.Note that if you type in a filename instead of a device name, the function will cope. For example, you type in 'flp1_fred' instead of 'flp1_'. You will get a list of the files on 'flp1_' if 'fred' is a file, or even, if 'fred' is not on 'flp1_'. If, however, you have the LEVEL 2 drivers (see LEVEL2 below), and 'fred' is a sub-directory then you will get a listing of the sub-directory as requested.a$ = FETCH_BYTES(#channel, how_many)This functng SuperBasic function :2700 DEFine FuNction PEEK_STRING(address, length)2720 LOCal x, result$2730 result$ = ''2740 FOR x = 0 TO length - 12750 result$ = result$ & CHR$(PEEK(address + x))2760 END FOR x2770 RETurn result$2780 END DEFine PEEK_STRINGPE_Found = QPTR(#channel)This function returns 1 if the Pointer Environment is loaded or 0 if not. The channel must be a SCR_ or CON_ channel, if not, the result will be 0. If a silly value is given then a QDOS error code will be returion returns the requested number of bytes from the given channel which must have been opened for INPUT or INPUT/OUTPUT. It will work on CON_ channels as well, but no cursor is shown and the characters typed in are not shown on the screen. If there is an ENTER character, or a CHR$(10), it will not signal the end of input. The function will not return until the appropriate number of bytes have been read.WARNING - JM and AH ROMS will cause a 'Buffer overflow' error if more than 128 bytes are fetched, tned instead.error = READ_HEADER(#channel, buffer)The file that is opened on the given channel has its header data read into memory starting at the given address (buffer). The buffer address must have been reserved using RESERVE_HEAP, see below, or some similar command. The buffer must be at least 64 bytes long or unpredictable results will occur. The function will read the header but any memory beyond the end of the buffer will be overwritten if the buffer is too short. After a successful call to thi letters.If the address returned is zero, the string was not found, otherwise it is the address where the first character of what_for$ was found, or negative for any errors that may have occurred. An example :1000 PRINT SEARCH_C(0, 48 * 1024, 'sinclair')1010 PRINT SEARCH_I(0, 48 * 1024, 'sinclair')1020 :1030 PRINT SEARCH_C(0, 48 * 1024, 'Sinclair')1040 PRINT SEARCH_I(0, 48 * 1024, 'Sinclair')The above fragment, on my Gold Card JS QL, prints :0 at line 1000 - case must match exactly, no capitaln9MnVMnW”MoėMoģMoķMpMp ŌMpŻMpŽ2MqMqMq2,Mq^2MqMqŸMq YMqłMqśMqūMrMrŪMsņMsóĻMtĀMtĆMtÄMtßMtą!MvMvMvMvMvüMwMwMwM 'S'47314 at line 1010 - case ignored47314 at line 1030 - 'Sinclair' found exactly47314 at line 1040 - case ignore againLooking into the ROM at that address using PEEK_STRING(47314, 21) gives :Sinclair Research Ltdwhich is part of the copyright notice that comes up when you switch on your QL.If the string being searched for is empty ("") then zero will be returned, if the length of the buffer is negative or 0, you will get a 'bad parameter' error (-15). The address is considered to be unsignedw4Mw5›MxŠMxŃMxŅ.MyMyųMyłMyśMz‰MzŠĖM{UM{VM{WM{XM{mM{n„M|M|$M|8M|?M|XM|_M|xM|M|žM|„!M|ĘM|ŌM|ņ&M}*M}BM}TM}UuM~ŹM~ĖM~Ģ, so negative addresses will be considered to be very large positive addresses, this allows for any future enhancements which will allow the QL to use a lot more memory than it does now !error = SET_HEADER(#channel, buffer)This function returns the error code that occurred when trying to set the header of the file on the given channel, to the contents of the 64 byte buffer stored at the given address. If the result is zero then you can assume that it worked ok, otherwise the result will be a negatiM~éM~ź‰M€sM€tM€u#M€˜M€™@MŁMŚ2M‚ M‚$M‚8M‚W5M‚ŒM‚M‚³M‚ĻM‚ŠM‚ŃM‚ŅM‚ķM‚īßMƒĶMƒĪMƒĻ'MƒöMƒ÷M…üM…ż>M†;<M†w<M†³AM†ō,M‡ ?M‡_-M‡ŒMrror code if something went wrong while attempting to read the file header or zero if everything went ok. It can be used as a more efficient method of finding out the details for a particular file rather than calling all the various FILE_XXXXX functions. Each of these call the READ_HEADER routine.To extract data, use PEEK for byte values, PEEK_W for the filename length and version number (if level 2 drivers are present, see LEVEL2 above), or PEEK_L to extract 4 byte data items.The filename can be extr5M5M5<M5=rM6ÆM6°ÉM7yM7zM7{1M7¬M7­³M8`M8a4M8•M8œ,M8Č*M8ņM9(M9+ M98 M9DM9K,M9w'M9žM9·+M9ā M9ļ M9ūM:M:)M:EM:L!M:m"M:M:M:§M:Øacted from the buffer by something likef$ = PEEK_STRING(buffer + 16, PEEK_W(buffer + 14)).buffer = RESERVE_HEAP(length)This function obtains a chunk of memory for your program to use, the starting address is returned as the result of the call. Note that the function will ask for 4 bytes more than you require, these are used to store a flag so that calls to RELEASE_HEAP, see above, do not crash the system by attempting to deallocate invalid areas of memory. If you call this function, the returned add#M:ĖM:āM:é&M;M;.M;/`M<M<ĻM>_M>`M>aM>bM>xM>y–M@M@ąM@šM@ń)MBMB MC&MC'MC(MC)MC?MC@MDŻMDŽMDßMDōMDõ$MFMFMFMF8MF9^Mress is the first byte that your program can use. It can be used as follows to reserve a buffer for READ_HEADER, described above.1000 buffer = RESERVE_HEAP(64)1010 IF buffer < 01020 PRINT 'ERROR allocating buffer, ' & buffer1030 STOP1040 error = READ_HEADER(#3, buffer).....do something with buffer contents here2040 REMark Finished with buffer2050 RELEASE_HEAP bufferscreen = SCREEN_BASE(#channel)This function is handy for Minerva users, who have 2 screens to play with. The function retG—MG˜MG¦MG·(MGß*MH MHMHnMIMIŽ'MJµMJ¶ķMK£MK¤MLæMLĄ›MM[MM\MM]!MM~MMMNMN‚oM PńMPņcMRUMRVMRWMRgMRh»MS#MS$MS%LMSqIMSŗKMTBMTGNurns the address of the start of the screen memory for the appropriate channel.If the returned address is negative, consider it to be a QDOS error code. (-6 means channel not open & -15 means not a SCR_ or CON_ channel.)SCREEN_BASE allows you to write programs that need not make guesses about the whereabouts of the screen memory, or assume that if VER$ gives a certain result, that a Minerva ROM is being used, this may not always be the case. Regardless of the ROM in use, this function will always reMT•MT–<MUŅMUÓfMV9MV:šMWŌMWÕ$MWłMWś$MXMX%#MXHMXY?MX˜ MX„ MX±MXø(MXąMXįZMY;MY<MYYMY` MY€MYžMYÆ8MYē MYō MZMZ MZMZ%(MZM#MZp;MZ«3Mturn the screen address for the given channel.current_mode = SCREEN_MODEThis function can help in your programs where you need to be in a specific mode. If you call this function you can find out if a mode change needs to be made or not. As the MODE call changes the mode for every program running in the QL, use this function before setting the appropriate mode. The value returned can be 4 or 8 for normal QLs, 2 for Atari ST/QL Extended mode 4 or any other value deemed appropriate by the hardware beiZŽMZ÷MZžM[ M[M[śM\M\PM]eM]f•M]ūM]ü‘M_M_ŽM_&M_µM_¶¦Ma\Ma]ÄMb!Mb"Mb#Mb?Mb]Mb^1MdMdMd‘Md°!MdŃMdŅęMføMf¹MfŗMfÖMfōMfõßng used. Never assume that your programs will only be run on a QL ! (Graphics Card anyone ?)1000 REMark Requires MODE 4 for best results so ...1010 IF SCREEN_MODE = 81020 MODE 41030 END IF1040 :1050 REMark Rest of program ....address = SEARCH_C(start, length, what_for$)address = SEARCH_I(start, length, what_for$)Both of these functions search through memory looking for the given string. SEARCH_C searches for an EXACT match whereas SEARCH_I ignores the difference between lower & UPPER caseMgŌMgÕMgÖ!Mg÷MgųuMimMinMioMi‰Mi„Mi¦YMi’MjFMjFMjZ<Mj–/MjÅMjä"Mk.Mk4/MkcXMk»Mk¼MkŃMkŅMkÓMkļMl MløMlĘMlĒMlČMlćMläSMn7Mn8MĀMįMāMć!MMMMŚM÷MųVMNMOMP*Mz*M¤*MĪMĻÄM“M”•M)M*WMM‚-MÆM° M»M¼-MéMź MõMö,M"M#³MÖM×÷MĪMĻN^Nu/N¹MšXOR€/N¹MŽ(XOfp`Ų.ƒ/N¹KōJ¹R¢g/N¹‰J®Cś 4xN’Nu». RELEASE_HEAPR ABS_POSITIONF MOVE_POSITION|PUT_BYTEtPUT_WORDlPUT_LONGd PUT_FLOATČ PUT_STRING POKE_STRING@MOVE_MEMü FLUSH_CHANNEL >USE_FONT lSET_XINC dSET_YINC œ POKE_FLOAT" FILLMEM_B FILLMEM_W FILLMEM_Lœü DJTK_VER$SYSTEM_VARIABLES SCREEN_MODE4 SCREEN_BASEŗ RESERVE_HEAPv SET_HEADERd READ_HEADER“LEVEL2Ø FILE_POSITIONŠ FILE_LENGTH„FILE_DATASPACEn FILE_TYPEn FILE_BACKUP\ FM īM ļM šM!M! ĮM!ŹM!ĖM!Ģ&M!ņM!ó„M#˜M#™‘M$*M$+¢M$ĶM$ĪĻM%M%ž™M&7M&8«M&ćM&äM&å+M'M'ėM(üM(żƒM)€M)M)‚M)M)žÄM*bM*cM*dM*MILE_UPDATEšGET_BYTE’GET_WORDŠGET_LONG‚ GET_FLOAT GET_STRING2 FETCH_BYTES’ PEEK_STRING 6SEARCH_I .SEARCH_C DEV_NAMEņ KBYTES_FREEą BYTES_FREE CHECKņ DISPLAY_WIDTH źQPTR @ WHERE_FONTS LDJ_OPEN F DJ_OPEN_IN < DJ_OPEN_NEW 2 DJ_OPEN_OVER & DJ_OPEN_DIR Ź PEEK_FLOAT \MAX_DEVS œMAX_CONa ōgpńNura<=¼˜-¼1.15˜-IXxpNua Ģgrń`a ö"t` a ¶grń`pr’t’NAtJfr` JH` D~d`~2a ŒtS@fa Œfrń` Žrń` ŌNupa ~föt 6˜kča 4fp 2v’EśNNCJ€g"`< G2g6/pNA"‚’’’*‚ÄM+FM+G)M,pM,qM,rM,‹M,ŒM-«M-¬M-­M-ČM-É,M.õM.öM.÷M/M/®M/æM/ĄM/ĮM/ŽM/ß¼M1›M1œM1M1¶M1·öM2­M2®M2ÆM2ÅM2ʰM4vM4w‡M4žM4’M ‚104e’’HAHĮ`Thanks Ralf !!"<€t` f"0pNua śtS@grń` Rrń` HNupa ņföt"6˜očZa g"` üNDhp"t` a “S@f(pa ¼f"&1čRƒƒYƒ C NDhpf BpNAp`pńNu~B`~Ca zU@gpńNua xgöpa xfš 6˜a 2fę"6˜ BfJkŌv’NC €’’’öfpNu~` ~`~`~a (U@gpńNua &gö f$Kėpa fę*6˜Óü&MPpa fŠ`pa üfĘ*6˜Óü a ®f“4v’ nr’GŅĮNDpNCNua ŗU@gpńNua øgöKėpa “fģ.6˜&MKėpa ¢fŚ41čmŅ a XfĢTBv’NDpNCNua pU@gpńNua nföpKėa jfģ.6˜&MKėpa XfŚ$G41čgŅkĪ`ńčve QDOS error code. On normal QLs, the three dates at the end of a file header cannot be set.sys_vars = SYSTEM_VARIABLESThis function returns the current address of the QL's system variables. For most purposes, this will be hex 28000, decimal 163840, but Minerva users will probably get a different value due to the double screen. DO NOT assume that all QLs, current or future, will have their system variables at a fixed point in memory, this need not be the case.address = WHERE_FONTS(#channel, 1_‡<M‡ÉM‡Ź?Mˆ 9MˆB?MˆMˆ‚#M‰„M‰¦GMŠķMŠī¹M‹§M‹Ø@M‹č4MŒMŒMŒMŒ=MŒ>MŽCMŽDMŽcMŽv3MŽ© M޶%MŽŪ,M!M(MAMBMC McMd­MMŽM M”Nor_2)This function returns a value that corresponds to the address of the fonts in use on the specified channel. The second parameter must be 1 for the first font address or 2 for the second, there are two fonts used on each channel. If the result is negative then it will be a normal QDOS error code. The channel must be a CON_ or a SCR_ channel to avoid errors.6. QDOS ERROR CODESMany of the above functions return a valid result, such as an address, or a negative error code. The QDOS error codes arM‘ļM‘šM‘ńM’ M’M”M”4M”RM”jM”y M”…M”Œ!M”­M”®M”Æ.M”Ż.M• M• ¾M•ŹM•ĖĖM––M–—.M–Å.M–óM–ś.M—(.M—VM—W4M—‹M—Œ9M—Å"M—ē.M˜'M˜<M˜=JM˜‡Me listed below for reference.-1 Not complete-2 Invalid job-3 Out of memory-4 Out of range -5 Buffer overflow -6 Channel not open -7 Not found -8 File already exists -9 In use -10 End of file -11 Drive full -12 Bad device name -13 Xmit (transmit) error -14 Format failed -15 Bad parameter -16 File error -17 Error in expression -18 Arithmetic overflow -19 Not implemented -20 Read only -21 Bad line˜ˆM˜žM˜ŸPM˜ļM˜šŒMš|Mš}Mš~&Mš¤Mš„zMœMœ Mœ!Mœ>Mœ?\M›MœM)MĘMĒgMŸ.MŸ/MŸ0MŸ1MŸFMŸG—MŸŽMŸßMŸōM M M 4M MM gM zM —M §Ø/Aģ ļNŗŗ. UüļÜüļÜ- M:M<#M_M`MaWMøM¹ŽM—M˜ŃMiMjÖM@MA*MkMlMm$M‘M’\MīMļ£M’M“‹MMM M@MAMTMUNM£M¤*MĪMM ¼M ŠM éM”M”M”6M”JM”gM”„M”M”°M”ĮM„źM„ėM„ģM|ĆM„ńM„ńM„ńM„ńM„ńM„óUM"Mease note, every QL has at leaB%@ '1;EČ>ž Q0( HĄå€ŃĄ*hRAģ@tNŗ"6J@gp`>Nŗp U0(:HĄ2(M .M :@M zBM ¼8M ōBM 62M h<M ¤-M Ń*M ū9M4(M\/M‹2M½2Mļ2M!<M]2M1MĄ1Mń7M(1MY;ööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööM”JMŽHM&IMo'M–DMŚCM8MU@M•BM×-M.M2.M`4M”.MĀ:Mü=M9BM{DMæJM <MEDM‰/Mø.MęAM'HMo<M«7MāJM,M-M.M/ÖMMMMMööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööf*"O*Ipltv’NCJ€f8x x"nXP‹=˜N”J€fQĢ’ī"nXP"t`¤~`~`~aģW@gpńNupašfö v˜ 6˜gģ"6˜ g$fŲ g ĮS€fśNu0ĮS€fśNuĮS€fśNu-IX/8*g8<ҁiSD*p"į”i˜@*ā@fņ"g 0xN"nX“ß-IX#…č3„čxpNu-IXHē`J‚g "4xN’"nXLß“Ā=˜xp-IXNuJ€k Ąü(Š®0°®4l vJ¶kp`pś`pńJ€Nu ‹€üNu6øNu$|4rN’Nut@v’NCJ€NupNBpNuHē`pNALßNuHēpppt’NALßJ€NuHēš 4xN’"nXLß“ĮNuN¹BžHxHmžžN¹8ōx&-`*Hx;/N¹Kv$@J€POgB/ażŌ( gü;& XOJ„f Jƒg CJfČHm’}N¹īHmžžN¹L_USE.TIP: If you want your C programs to use a different default directories to those used by Superbasic programs, then you can set any one of the DATA_USE, PROG_USE or SPL_USE environment variablesexplicitly at the SuperBasic levle.WHAT PROGRAMS USE ENVIRONMENT VARIABLESTo determine whether a program will use any environment variables, it is necessary to look at the documentation for that program.Examples of programs that are supplied as part of the C68 system that DO make use of Environment ^ŗAčx-P’ü .Ą¼’’å€ @Ńī’ü-P’ų n’ų-h’ō .’ōN^NuNV’ō`ÄPress ‘ČCś„4xŠN’pNA~ SMSQg ‚2.00m~Aś¼*|*Cśl4xN’J‡fˆ"n $n$SŠ 6Øg³Źfņ`jIśGt JRа6ØfRŠQŹ’ō¼*ˆ¼*Ø’`F$H`Āc68 ENV support v1.07 8_ENV_:SETENV ENV_LISTĢENV_DELnGETENV$Nu4xN’ CfŌx86˜ DmĘ(I":’ÜŅ„RtpNAJ€f¬,SD"H›Ķ6ČRŒ =f »üf*IĆQĢ’ęB»üg»ČfpNA`v. žˆSG$z’„µüf*H(I`^":’vgS$  =gĄgQÉ’ņ(I`.QÉ’č(I`&& –‚Sƒ¶Gfā&H(B¹ fŚQĖ’śgQÉ’ś(B`"B`¾*H z’$±üVariables are the CC, C68 and MAKE programs - refer to the documentation on each program for the details. AUTHOR(s)Original version - Dave Nash.C code modification - Dave Walker.SuperBasic interface extension - Dave Woodman.CHANGE HISTORYThis is a short summary of the changes that have been made to this document. The intention is to make it easy for users who are upgrading to find any new information.25 Apr 94 DJW - Minor changes and corrections for the 4.13 release.©°docgpNAAś’ Ķ™Ķ Œ`ö4xN’ Ce g`ą>6˜`~Īü(Ž®0¾®4lĄ vx>k¶$zžŅ(:žŅg¶S„vgpNCJ€f¦QĢ’ī`šJg”r z`āaJ€f€»Źfr›Ķ`ÕÄRŠ&J›Ź" V A4xN’"nX“Č-IX(I=Č2 TŒ`›ČRŒQÉ’ųx`”k`ŻQŹ’üB":ž,•ĮAśž* Š` pśNupżNupńNupNuNu4xN’ Cfźx86˜gā:VE…EńP-JX*zżč zżč±üg0ŃĶ:SE(ITŒ$M°6ČfRŒQĶ’ō =fJfüS`žJgÖ»Čoų$zżØ*J`ŽNuNV’lHē<`žņ`X&.($C`>µĆg8 _f2RJR’½BHn’¾/N¹J€POf .@B; :VB; :˜ G¦ G§± GX GY GZ Gy GzU GĻ GŠ Gą GįÕ G¶ G· Gø GĪ GĻ Gå Gę/ G GTGkGotGćGäAG%G&PGvGw Gx G˜ G™§ G@ GA GööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööY GZc G½ GĮ GÕ GŁp G I G M G ] G ^† G ä G åÆ G ” G •Š G  G G + G . G ; G < G =r G Æ G °‹ G ; G < G N G O^ G ­ G ®™ GG GH G] G^æ G G G7 GB R‰QŹ’ųpNua &W@gpńNupa *fö"6˜$6˜&6˜g¢“gœe S€Š“€b"$AԃS‚&B~’`$A&B~ ƒed‚’fTf g p’SŠS‹QČ’ųWƒ` fŚSƒ`WŠW‹ ƒäˆgĻü&’ÕĒ×ĒS€föü gVŠV‹Jƒg ’ÕĒ×ĒSƒföpNua ^S@gpńNua \göpa \fš 6˜a fępAv’NCNu~G`~Fa ,tU@grń` ĪNua $gņpa $fš 1č\‰a Üf 1čžjpń` / "@a "_t"` ’~`~` ~`~4`~6˜mŚr2.V gn|œÓĘ` ]-IXaJ-IX=‡˜`œ˜R‰QĻ’ų"nXpxNuaŌtS@grń`vNuaĢgņr@aüf<*paĀfę 6˜T‰azf$. pOrtv’"ENC,p INAt"G"gr`(t"` r`altS@grń`Nupajfö~>6˜očKé0`6 ŲRQČ’ö/ pr$NA"_J€g2`Z&h*h"( 03ˆ @g @ gP‹·Ķl6`č4sˆÕĮ¾2ˆfģ0/ `2ˆ “6˜f R‰RŠQČ’ģp"_J@fČr`rRG‡ŅĒt`h~`~ a“grń`aŽ"(’Ø ī©t`ž~`~atW@grń`čNuKėpaŠfņ(v˜*6˜nT‰rń`ø&MKėpajfŅr26˜Ké $V‚‚ÓĀT‰tJAgPeLhe routine putenv() can be used to give a value to an Environment variable. This will change the value if the named Environment Variable already exists, or create an new value if does not. Therefore a call of the form: putenv("TEMP=ram1_"); would set the environment variable TEMP to a value of ram1_. If you want to remove an environment variable completely then call it assigning a zero length value. i.e. putenv("NAME="); would delete the environement variable NAME (This is a slightly noSAJg$Hē@6Ų ae zb¶ŲRQÉ’ęLß Jg ae zbƒ¶5čg RŒS€lŽ(B`4Hē@ `Jg ae zbƒ¶5čf RŒRQÉ’ŽtLß0J‚gĀ" tga¤S@gpńNupaØfö 6˜g @ P`aø hHx±üg8($Hē|€"taĘ/ 4x N’"_Lß>J€fB"V gnzšÓÅ` ]-IXa„=„˜(I` Ø&ČRˆRŒQĢ’ō-IXxpNua @gpńNuagöpafš*I"vŲ$vŲ 6ŲkŽa¶fŚp%v’NCNu~&`~(aĢU@gpńNuaŹgöpaŹfšp26˜06˜kāa|fŽp 4v’EśNCNu1 pNuaŠtS@grń`,Nua‚gņpa‚fšp06˜lpń`a4g"t`žtppv’&INC"KJ€g €’’’ńfąr`ąrn-standard treatment).INHERITING ENVIRONMENT VARIABLESIf a number of c68 compiled jobs are chained together then the environment variables of each slave job are inherited from the owner. The master job will obtain its values from the settings in SuperBasic.This inheritance factor is important as it means that if a library call is used to change one of the environment variables, then this is remembered and passed on without changing the setting that is current at the SuperBasic level. STANDA`Śa,tU@grń`„Nua$gņpa$fšp>6˜06˜lt`@aŅg"t`R*Ip v’Eś0NC I"MJ€fät Gf"(*`. Gf"(.` rń`"HpNua°grńt`TaÖr hH±ügčRA P`ņaŠU@gpńNuKėpaŠfņ(v˜X‰&MPpaxfąpö˜R‰QČ’ųpNuaPS@gtrń`ØpaPgNu$v˜ra„-IXpš˜R‰QČ’ųpx"nXNuz`z`z`z`z`Credit to SNGašS@grńt`’pašgNupr’& I/ NDNB"_26˜RAŅĮJ€fH$n0r(µī4l J6Øk R@ÕĮ`ī<4xEź,N’$n4Gź(-K40-ˆØrXŠB¶ØQÉ’ų¼PØr2t`ad[@grńt`a^gņpa^gNup06˜aP‰-IXQJ€RD ENVIRONMENT VARIABLESA number of standard Environment Variables are set up automatically by the C68 system. These are PROG_USE DATA_USE SPL_USEThey contain the values for the Program, Data and Destination directories respectively. If the program has been started from Superbasic and these Environment Variables have not been explicitly set at the SuperBasic level, then these Environment Variables will have the same values as you have set up using the Toolkit 2 commands PROG_USE, DATA_USE and SPbelow as used in the C environment.Subsequently setting another value for the same variable causes the previous definition to be overwritten. Most users will set values at startup from within their boot files.You can obtain a listing of the current settings of all your Environment Variables at any time by using a SuperBasic command of the form: ENV_LIST or ENV_LIST #nThis causes all currently defined environment variables to be written to the channel specified, or #1 by default.If you decide thööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööat you wish to completely remove an Environment Variable, then this can be done by using a SuperBasic command of the form: ENV_DEL "NAME"This procedure will remove an environment variable definition completely. In many cases this will be equivalent to using the SETENV command to give a variable a null value. They are not quite the same as at the C level one will result in the getenv() call returning NULL, and the other will result in it returning a pointer to a zero length string.If you want to intB§N¹$r-@’ųHn’ųN¹ö˜$@%|’’’’ Š€r>Ą$€ ź€r?Ą%@ r ā rĄENVIRON_DOC LAST CHANGED: 25 Apr 94 INTRODUCTION This document discusses the topic of Environment variables in C68. It covers how they are set up, how they are accessed, and why you might want to use them in the first place. WHY USE ENVIRONMENT VARIABLES Environment Variables are an idea that has been adopted from the UNIX operating System. Environment variables are basically global variables that use to control certain aspects of how yourerrogate the value of a particular Environment Variable from within a SuperBasic program, then this can be done by using the function: GETENV$("NAME")This allows the environment variables to be manipulated from SuperBasic. The GETENV$ function will return the value of and environment variable, or a null string if not found. Hence, after: a$="test=debug level 1" SETENV a$PRINT GETENV$("test") would print the string "debug level 1"butPRINT GETENV$("TEST") would print a null string (since Env system will run. Typically you would set up standard values during the loading of your system, although you may modify some of them at a later date. In QDOS terms, this means that you can set up information in your BOOT file that can be later interrogated by other programs running. This can make it much easier to centralise the control of your system rather than having to tell each program separately as you run it. An important feature of Environment Variables is that they are NOT cleared if you load a nironment variable names are case sensitive).and the sequence b$ = GETENV$("TMP")IF b$ = "" THEN b$ = "RAM1_" SETENV "TMP=" & b$ENDIFSETENV "TMP_FILE=" & b$ & "WORK_TMP"will ensure that the TMP variable is set, and that another environmental variable, TMP_FILE, contains a reference to a file WORK_TMP on the same device. C68 C LEVEL INTERFACEThe Environment Variables capability interface is built into all C68 programs that are compiled with Release 2.01 or later of C68.The routine maew SuperBasic program. Thus they remain set for the duration of your session (or at least until you reset your machine). SUPERBASIC INTERFACE The SuperBasic interface is provided as four extensions to the SuperBasic interpreter, the code for which in contained within the ENV_BIN file provided with the standard C68 distribution. This file should be LRESPR'ed if you wish to make use of the facilities that it offers. The four extensions provided are as follows:- SETENV A procedure that allows you to se’ĘĄ¼š°¼@f( ®’½RJJf¾ Lī’°N^NuNV’¼Hē `ž`xx/.N¹Mšvrm1qdf0² ¶&lC68 COMPILATION SYSTEM Environment VariablesENVIRON_DOC LAST CHANGED: 25 Apr 94 Page nnnINTRODUCTIONThis document discusses the topic of Environment variables in C68. It covers how they are set up, how they are accessed, and why you might want to use them in the first place.WHY USE ENVIRONMENT VARIABLESEnvironment Variables are an idea that has been adopted from the UNIX GC= G€ G G… G†g Gķ Gī G G G G& G6 GL GR% Gw Gxœ G G G G- G.ƒ G± G²Ā Gt Gu6 G« GÆ Gµ G¶† G< G= GK GL. Gz G{_ GŚ Goperating System. Environment variables are basically global variables that use to control certain aspects of how your system will run. Typically you would set up standard values during the loading of your system, although you may modify some of them at a later date.In QDOS terms, this means that you can set up information in your BOOT file that can be later interrogated by other programs running. This can make it much easier to centralise the control of your system rather than having to tell each prŪæ Gš G G° G± G¹ Gŗę G  G” Gŗ G»> Gł Gśl Gf Gg G{ G|[ G× GŲ GŁ" Gū GüĪ GŹ IĖź Iµ I¶ I· I¹ IŁ IŚc I= I> IH IR I[ I\k IĒ Iogram separately as you run it.An important feature of Environment Variables is that they are NOT cleared if you load a new SuperBasic program. Thus they remain set for the duration of your session (or at least until you reset your machine).SUPERBASIC INTERFACEThe SuperBasic interface is provided as four extensions to the SuperBasic interpreter, the code for which in contained within the ENV_BIN file provided with the standard C68 distribution. This file should be LRESPR'ed if you wish to make uČč I° I± I²) IŪ I܂ I^ I_Ļ I. I/ I1 I< I= I[# I~/ I­ I® IÆ Læ LĄØ Lh IiH I± I" I" IQ Ivrm1qdf0" F&l£  0rm1qdf0Qö&r that program.e!XB T. '1;E "se of the facilities that it offers.The four extensions provided are as follows:- SETENV A procedure that allows you to set the value of an environment variable ENV_LIST A procedure to list the settings of your current environment variables to a channel (usually the screen)ENV_DEL A procedure to delete an existing environment variableGETENV$ A function that returns the value of a specific environment variable.USING THE SUPERBASIC INTERFACEThe first thing that you are likely to ',16;@E "',16;@EM  IXO¼¹RBf¤#ģ6RB`˜J¹Rņg/aż.J€XOg‚p’°¹RFf8HyŒ]/9e†N¹BJ€POg//9e†N¹J€POfp`p#ĄRFp°¹RFf¬ G"Mp "ŲQČ’ü2Ų/ /N¹J€POfR G (°­fF (°­f< °•f60(°mf,0(°mf" (°­f (°­f ("°­"fp`pJ€g4J¹R¦gHyŒ:/9e‚N¹ ĢPOøƒg/N“XO/N“.…N“p`ż¢HxN¹MŽ$@J€XOg/N¹MšXOR€/N¹MŽ$€XOf gžx/ N“XO`žn//N¹Kō%C%E%n’č yRź Š%yRźBŖpЊ#ĄRźR¹e¢¼¹RBf#ŅRBPOøƒg’n/`’fNV’ųHē &.want to do is to set the value of one or more environment variables. This is done by using SuperBasic statements of the form: SETENV "NAME=VALUE"This sets up an environment variable NAME, and gives it the value VALUE. For instance, the command SETENV "TMP=ram1_" gives the environment variable TMP the value of ram1_. It is worth noting that the VALUE part may be null, ie SETENV "TMP=" will assign a null string to the variable TMP. This should be contrasted with the putenv() usage, öööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööö This allows the environment variables to be manipulated from SuperBasic. The GETENV$ function will return the value of and environment variable, or a null string if not found. Hence, after: a$="test=debug level 1" SETENV a$ PRINT GETENV$("test") would print the string "debug level 1" but PRINT GETENV$("TEST") would print a null string (since Environment variable names are case sensitive). and the sequence b$ = GETENV$("TMP") IF b$ = "" THEN b$ = "RAM1_" SETENV "TMP=" & b$ ENDIF SETENV "TMP_FILEŁQŹ’üCķ’ž`ĄSAlŅ`,SŒRA°g ,fUAm ;@ŠĄ$HTˆ*HÜQÉ’ü ; g0BaX@3Lß1NuHē~ą|pžĄi @ g @ f|xzNŗžņ"+ģNŗtf$'Bģ$Y‚m²·(fögæĪo X„/$anÖopžßÄLß~J€Nut‘Ča*g& €’’’’fNŗ|gīNŗŠaNŗ†g €’’’žfpJ€Nup|Hē@@vNCLßJ€NuHēXĄ(.tpNAJ€gJ—gšr`ģCč o YJūf JPg Nŗ~g`JPg JfŹpłJ„fĀ$LßJ€NuHēq@@ĒN@&pNA4HC2(r hx0åH 0m0"@¶if(&)RB“An0åH 0mš"@¶©fč )0 @p`płFĒLߎJ€NuNŗVg"H@J@fH@Ć@1NŗtĮAY cp`płNuHz(0üN¹ ß Ā Ć ĮBXpNuHēóĀ//$Æ (MśT"_)>) JQ=" & b$ & "WORK_TMP" will ensure that the TMP variable is set, and that another environmental variable, TMP_FILE, contains a reference to a file WORK_TMP on the same device. C68 C LEVEL INTERFACE The Environment Variables capability interface is built into all C68 programs that are compiled with Release 2.01 or later of C68. The routine main() is now passed an additional parameter at program startup that points to the environment variables (if any) that are currently set up. The syntax of main() is nog2r’Nŗ”v’JQm pzrtNCp NCJjp|rżNC2g Nŗ"`p|ržNCprtv|~ @"@NÖLßCĻNuHē HĮ(nJprtv’NCNŗ÷P4pNCtžĀ"Or2ü32pNC. J€fHp NC$H ONŗ JPmÄ(r øm¼ė‰øn¶pNAAś*/??<"Or$<’’vNŗ&PLߐNuNŗ^`¦`JūDaemonprtNA,Hp rtNApNA*H<-’;|’’’"(’Ø t4HBģŠ(’‚gHm\*pNAJ€fR"p NAJ€f$B-3pr’v“ÉNAJ-3fģp"tNAJ€fJƒlÜp",mÜühNAp rNA;F’r’vpNANu"aōNŗ¤`ącon_512x100a0x0Hē0vAś’ęNŗĄLß NuHēšx/N”gj^€gZ€f^CśńvpNA (¬g"@ _$o$0 @b8 1_’gR@4Ą`ŁQČ’ü|_’’"H o$0w therefore: int main (int argc, char * argv[], char * argp[]) { ... where the argp variable is an array of string pointers. Each entry points to a single NULL terminated string which is in the form: STRING=VALUE and the list is terminated by a NULL pointer. A user program has a number of library routines available to manipulate environment variables: - the routine getenv() can be used to obtain the value of a specific named Environment Variable. A NULL pointer is returned if the specified EnviroŃP Pb`ŁQČ’üLßNŌLßpōNu[€_€Žü$NuHē…GśpNALß”J€Nu ŖŖČCśń€Nśņ¼(KNŗ ”f"kČNŗ ¤&L g N‘Cśņ„NŗņŖNuNŗPf"6˜l NuNŗ¾f>p Šv˜NŗŚf2Nŗ Rf(|Nŗ¦"H‚BfNŗ÷Rg 3|Nŗ÷FNŗ JfpNŗ„Nś¶Nu|` |`| `| HFNŗ`f–Hēp2EśłjNŗäf|"V0f0f06˜26˜=€˜EśņNŗ¬fZ"V=˜*Hf""pHē0NALß J€f(HpeŠ@Nŗf&`peŠ@(@Š‚Nŗ fŁČpH"LĖHNŗ.ĮMfž"VT‰0g4EńP 6,Ø’f(v˜žF@g @0b=…˜žzaę¶Ø˜R‰RŠS@nņ`$Eģ ZJūf0g @0cp0a¼š˜R‰S@nö"HAč*&Ha Aé^#H üTHG%p ĄJg © Ą Ā`p, Ąp< Ąnment Variable does not exist. i.e. getenv("TEMP"); would return a NULL if the TEMP Environment variable did not exists, and a pointer to its value if it did. Please note that the returned value may also be a zero-length string for an Environment Variable that does exist, but that has not been assigned a value. - the routine putenv() can be used to give a value to an Environment variable. This will change the value if the named Environment Variable already exists, or create an new value if does no Ćp ĄL×Nŗū¾0üNł Ģ0üJūaĘ Ip&NŗÖPĘf>p "VŠv˜Nŗ,f""H0ühiHF0ĘB˜a¦2Eś÷ģNŗ†g INŗ(( Kp'Nŗ˜ `Nŗ MNŗčŽü NśÜNu2f 2f=€˜žNu4DAŅv˜žŠA=€˜žA”@gÜHē`mŅĄEń ¶Ø˜R‰RŠSAnņ`ŅĄŅĮEń S‰SŠ¶Ø˜SAnņJDg˜BJEgšBLßNu 2f 2f 260ĮöR€SAnöpNuIė/ ĮIIś\vNŗüžXfpGtNŗtf )f $&)pNupžNś |`| HFNŗüf(p"Šv˜NŗfHFNŗņ"H2EśöŲNŗrgNŗNśęNu|`| NŗPf NŗlgmpńNu|NśšNŗZfNŗóRNśjNuNŗJfNŗņźNśZNupNŗŗfŽ.NŗšfĪ»ĖfČ/"V>6˜xNŗf“2NŗöīfžNŗf–KōNŗ2HD8)„t. Therefore a call of the form: putenv("TEMP=ram1_"); would set the environment variable TEMP to a value of ram1_. If you want to remove an environment variable completely then call it assigning a zero length value. i.e. putenv("NAME="); would delete the environement variable NAME (This is a slightly non-standard treatment). INHERITING ENVIRONMENT VARIABLES If a number of c68 compiled jobs are chained together then the environment variables of each slave job are inherited from the owner. TheEśķH"WNŗ œBENŗŹa„fvaCś¬ŅÄŅŃar` BENŗ®axavat¹Ķl>"W  g.Nŗ xg"JgaZJ†gp+r’ab"WaHDNŗnf pRf’TNŗz. GNŗźNup4ŚBŗGo:pNuBDa RE Emö`r pv’NCJ€Nuģ°ģ®ģ¬ģŖģ¢ģˆģ†ģŠģŽģ’ģNŗ fNŗ fNŗ8fNŗ`rNŗhNśNu i’üg" i’śgIé2`"/)Nŗōę(i#_`(i" JfüSŒĆŒ’ŒpNuNŗ>fNŗŖfNŗÖfpž0)HĄNŗüNś¬Nu|~Nŗf0P‹»Ėg v˜f |6˜`|’NŗųfEśńī "Nŗ.Nś¾pńNuNŗŽf Eśņ NŗNśØNuNŗŹfNŗ6fNŗbfNŗņP‹Nŗ¤fj-IXQ‹Nŗœf^26˜Eń$ RB‚26(Óv˜kBt the value of an environment variable ENV_LIST A procedure to list the settings of your current environment variables to a channel (usually the screen) ENV_DEL A procedure to delete an existing environment variable GETENV$ A function that returns the value of a specific environment variable. USING THE SUPERBASIC INTERFACE The first thing that you are likely to want to do is to set the value of one or more environment variables. This is done by using SuperBasic statements of the form: SETENV "NAM±Šf±Šf ±Jf @"`ą @»čfÖ`†J«øfBpPNŗ"6fZ'HøEč8!JAč& ü0.050ü üTHINüG$üTHG%SšAś&$ČAś†$ČpNŗ!ōf(H <ˆNŗ!äfGč8&¼THG%Eč$ĖCś¢$ÉCśø$É$ÉCśĄ$ÉBZ$ü2.29Cś’$Ł$Ł$Ł"Hp&NŗĘfĘpNAAč<"H g @H@J@fņ(Ų(ŲQŒ"Œ I`ęEśžą(KŲŚ0gCņž(É`ōIė Œ'|Hot%7|€g Cė>BYNŗ€$nL(K6xŽN“&Lf6Rf2"j R‰³źmCź$*³ĀgrNŗE=VALUE" This sets up an environment variable NAME, and gives it the value VALUE. For instance, the command SETENV "TMP=ram1_" gives the environment variable TMP the value of ram1_. It is worth noting that the VALUE part may be null, ie SETENV "TMP=" will assign a null string to the variable TMP. This should be contrasted with the putenv() usage, below as used in the C environment. Subsequently setting another value for the same variable causes the previous definition to be overwritten. Most usÖJBo7AÄ%j PėĒJkĘn˜Nu )’žf&/ Gé8Nŗ”&_gJéžfäJ)’fr4xĄNŅB)žp÷Nu/B)ž4xĀN’ _Nu(IGé8AėpNA +Ģg @Nŗ!2<’“ÉNŗ@SAlųNŗ LNś īHēpĄ@ĄN@?afCśĢ!I’śFßpLßNuaf |’«Bh’¬NuHēp€aLßNu"+Ąg ptNAJ€gāB«ĄBkĘpžNuHēxČa¢Iś6prt&“ÉNAJ€f'AĄ!K’ä0üNł Ģ\Œp0ÜU@nśLßNuNŗ `ō€`JūHOTKEYÜü`PėĘ2+ÄoNŗŠfNŗ¬QėÅgNŗĢBkĘpr’v’“ÉNA`Ņpr’vNA gŗHē8 EėoJ2f.6Nŗf ŌĮJmg –A’0BŌĆJn`JmDpLßNup÷`öHē`hNŗ¶`Hē`hNŗ“f"(I2) A’žmg Nŗ–p*Nŗ LNŗˆLßNupžers will set values at startup from within their boot files. You can obtain a listing of the current settings of all your Environment Variables at any time by using a SuperBasic command of the form: ENV_LIST or ENV_LIST #n This causes all currently defined environment variables to be written to the channel specified, or #1 by default. If you decide that you wish to completely remove an Environment Variable, then this can be done by using a SuperBasic command of the form: ENV_DEL "NAME" This procĄiP@ @b<0;Nū¢Z`fü "D * )g/NuNŗ"gųNśāNŗgīNśšpķNuHē`h$kŲSBmgNŗ>Nŗ6²gč`Jgg@NŗžfxNŗ|Nŗ,WĢ’ög*f0rNŗxf(xPSDo"a^pNA"hx"Q³čLlźÓѳčLoāLßp `p’LßNuNŗ`'kŲāpHēxų )(@fIé pNA$hLaga`ųLßNu/ pr’v“ÉNA"_Nu@ĄN@?|fg 6xąN“fJfģpFßJ€NuJga `'kŲā"kā gJfüS‰$ "@”‰pNuedure will remove an environment variable definition completely. In many cases this will be equivalent to using the SETENV command to give a variable a null value. They are not quite the same as at the C level one will result in the getenv() call returning NULL, and the other will result in it returning a pointer to a zero length string. If you want to interrogate the value of a particular Environment Variable from within a SuperBasic program, then this can be done by using the function: GETENV$("NAME") / +Ģg($kāµĄf$kАŠF@J"VČ’üg `J"WČ’üfRŠ'Jā$_pNu/ Nŗ$f% EėüŠäHEė€p`/ a$_NuEėJ2fEėpJšWČ’üfpNup÷NuHēØa&`HēØahfBB”`HēØa`HēØp’aLßNup I2 Ag(ra:f P‰NŗąQ‰gRfīpłNuHēØa `ĪHēØa`ĘJgA’a gąEśø2EėŌĮH‚0gnD@åHIėüŲĄ"T QhifpNupłNuHē`ąNŗ\rt HBNŗüLßNuHē`ųHkIéŲÜ R€€(@Nŗ0rt HB&LIśŚNŗNXLßNuHē p!a"H g"JLßNup,HēxŒAėIé“É•Ź28<˜AdŅDx/HTˆ*H` ;g ,gZ !gTĄQÉ’č`x ;@ŠĄXˆ"HTˆ*H {fpUA }g, fpNŗżä“Do4`öööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööö g: @²Ø’ųfō¼g(_v’ĶMpNAĶMpNԐü )a˜`a¾X‰Šü6xŌN“YINupłNu"hCé )a’r`Ś`Ö/ J©f ) a’^`alJ€`p÷$_NuAś’Ģ#HAśž$#H AŃ#H’ōB©Nu/) ) a’(`a6 g0$@Aź’š"(a’Jg¼gtpNAGś!K’ś|’«Bh’¬ `ĪNuAé’š`’r’v’pNA f"i`Cé$g"B°‚fö$*’ų"QpNupž`śHē` Nŗ@EīøJ‡j$g,$BCź*Nŗ$fš`$g$B²*%fōCź*Nŗ fź"JLßNupł`öHē` EśLpr4`Š2āQŹ’öLßNuaf HĄ°fpNupī`śHē0 p Eś¤¾ˆgD°gųv(’’t +g -fD‚¾ˆg, 2f BBփi"ҁiҁi ցi0րhÖpļ`SˆJBföpJ‚jDƒ"J€Lß NuHēxą02öööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööö(<’’²@n fx`0HD6EśŽr` 2“2VČ’ņ–@4HB4J@jĄ LßNuHē`ąEś\r` 0°Qf(Hē`ąEśJr³H` 2“2VČ’ņLßfpNupł`śHēĄ@r0`ūQČ’ųLßNuA’;Nu  !"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ€‚ƒ„…†‡ˆ‰Š‹¬­®Æ°±²³“µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž’Hē@`  f02ĄŚS@nś`VHē@`BQpEśnJ2nFJl8Ą(mmEśp`"Hz†Ņ`Hz’pĄę j±ź e/ 0+*ĄDH€HĄ/ r8NPO`0+*ĄDRŖ€Ą¼’ j±ź e/ `ZHOTKEY System II V2.29 THING System V0.05 <>01HOTKEY System II2.29D *K¤ŽzP™r SŽl’’mDefault drive for executable programs: if you have Toolkit II, the HOTKEY system will use the program defaultėKeyboard Stuffer HOTKEY character. This stuffs the current string in the HOTKEY stuffer buffer into the current keyboard queue. Strings are put into the stuffer buffer by QRAM and other utility prograEś@BDFHJLNPRTVXZ\_behNULL^A^B^C^D^E^F^G^HTABENTER^K^L^M^N^O^P^Q^R^S^T^U^V^W^X^Y^ZESCcs\cs]cs`csESCA’;HNužžžžžžžžžžms or by the QPTR command HOT_STUFF¦Previous string Keyboard Stuffer HOTKEY character. This is similar to the normal Keyboard Stuffer but it accesses the string defined before the current stuffer string[Stuffer buffer size: this limits the number of stuffer strings that may be held at one time€@ flp1_ üSPACEEXECLOADPICKWAKECMDKEY'Working memory allocation (kilobytes)> HOTKEY System 2 hi’ųlast line recall ś HOT_STUFF“HOT_GOŗHOT_STOP¾HOT_LIST°žžžžžžžžžžžžžžžžžžžžžžHēh(JEś Nŗ@LßNu` Nq`pńNuxa`aJ†jNuxž|~(KNŗŒfšJg»ĢgŖÉK*.Xš®\af*pń v˜f 6˜BF KGķ’ų±ĖgRFaāfQ-IX`č&LfrŚ®\-EXš‰(IajJFgb2Nŗó”fZp Š…a’fP$H4ühi4Ä\Š26Č`öČRŒQÉ’ųSFoü rҌ(A`ÜCč " ’‰$I3# 2"HNŗó$` a Sfś`|’Nśä2Nŗó¦f øifNŗš˜pNuNŗˆfžB§B§B§NŗœQĘmčn»ĖgŽNŗfŲ v˜fÖP‹6˜Nŗ $ ifPĘ`Ō pgL gg fW×g·ĶfØ uf FÆ`Ž/z’Š·Ķl‚Nŗf| Cf~/v˜/v˜P‰``Fo/z’^JEf@"VT‰ I:6ˆžŅÅp 6_˜’g ³ČgR@d Destination directories respectively. If the program has been started from Superbasic and these Environment Variables have not been explicitly set at the SuperBasic level, then these Environment Variables will have the same values as you have set up using the Toolkit 2 commands PROG_USE, DATA_USE and SPL_USE. TIP: If you want your C programs to use a different default directories to those used by Superbasic programs, then you can set any one of the DATA_USE, PROG_USE or SPL_USE environment variablesexplS‰`īŃvˆžS@Ań¼,ˆ` Rˆ¶˜ˆR‰QČ’ō·ĶlNŗŖf?v˜X‰-IXp"VLßNupń`ōHē°0ühi0ĘXˆa NŗõrpLß Nu&I06øT‹0ĄgöøöøT‹U@nņNuNŗHfBNŗōf<26˜p ŠANŗ Źf*$I"H0ühi0ĘB˜0ĮöØRŠSAnöEśń„2Nŗg INŗ¾NśŽNuNŗ“fP‹»Ėo v˜f ~6˜J€NupńNuHē xz~6øNŗ„fp VTHJv˜g†a’P‹·ĶlXčSgHG@ĒN@*NHēpĄpNA,H,tpNAJ€gp`Ø’®LßgŃĶ H@H€@&m^ @lXz @f:HÅ…Š@0;6Nū2,MFĒJ€gQ…o €’’’÷fvr’nsion - Dave Woodman. CHANGE HISTORY This is a short summary of the changes that have been made to this document. The intention is to make it easy for users who are upgrading to find any new information. 25 Apr 94 DJW - Minor changes and corrections for the 4.13 release. PO` 38ąˆRŖ€Ą¼’ j±ź e/ +$Ą„H€HĄ/ r8NPO` +$Ą„RŖ€Ą¼’ j±ź e/ +$ąˆH€HĄ/ r8NPO` +$ąˆRŖ€Ą¼’ j±ź e/ 0+(ĄDH€HĄ/ r8NPO`0+(ĄDRŖ€Ą¼’ j±ź e/ B€0+(ą€H€HĄ/ r8NPO`B€0+(ą€RŖ€Ą¼’pNAL×9Z6`„Lß9ZLß J€Nu²ęŅ~Vnpń`¾HēąAé*NŗŚg2Nŗ o@%J‡jCč*Nŗ4Cīø4xŅN’"HNŗpLßNś’€pų`ō f"nø` Nŗ”f"QpNś’d$INŗ„fNŗXNś’TNŗvf IaNś’FHē|AčaLß@NuCīø4xŌN’"HNŗĪpNuNŗBfNŗ†f ICīø4xŌN’"HpNś’Nŗ"f NŗRfNŗNśžģNŗff6Nj%i&$I"i)gJ‚g“© g )ÓĄfņpķ` / "JNŗN"_Nśž¦JAj nd o P2(HA®häˆ2` r`²nbb Š@Š@ nh pH@°hfpNupž`śJ)$jp÷J©f( )a&`p a6f!AGé’ü!KX‰Šü6xŅN“Y‰J€NugHēO^aLßzņNu/NuT—NuHēpp"4xĄN’J€LßNuHēšš4xĀN’LßNuAé2<Ā+Üę p²QfJj*)g$°+°b()gCńH`ąJgB+°"H`ŅCśżų`øLß"<€ptNAJ€gNuGčEśč&ŹEśŽ&ŹEśJ&ŹB›P‹Eśz&Ź&ü(Eś¢6Ś&Ņ|0’’6ü&üPTH0&ü&HAėp"NACś4xNŅPTH_USE:PTH_LISTČPTH_ADD’PTH_RMVPTH_USE$&PTH$a2J€fJ(HaCėH J€g:"@BF L/ 24xĪN’J€f$RFt< pNCJ€fQŹ’ņ"WCé4xŠN’J€g"_Nupr NCJ€fņ"_ J€g"@`“pńNu4xN’J€f SCfī<6˜JFmęaJ€o $@  €p JNANu<<Iė¹Ķg$Iė¹Ķf¼Kė4xN’J€f^<6˜JFm¦&MKė/a°,J€fDB26˜PA/ ptNA"_J€f.$HAč26˜0Į`ö˜R‰QÉ’ųx_ø(’’g„Rja°Cś’ņNupNuJFfųHē`"kØHDHEBCHCē‹ÓĆ$Y&ĘüÕƵŃl aöfp’`Kś56`FPointer Interface V2.01 2Ī’Ź’ŹCONppv’‘ČNCJ€g8|’pNA"h| ”’THRgĀPč„"hx"Q ‘g¬@ĒHēN@*H(mx T&hp! KNAAė’čJgpNAAė’šJgpNAAė’ųJgpNAz’R…ŗmrn oō @ (0 @pNB`äBmpIś’>zAś’\prvNBp v’"LNCp NCPŒp'NCp(NCp)NCp NCQĶ’ĘFĒLß8`|aXf\Aś'HĄpNAAč< g. @ ØASTK’ųfšQˆ'HCśž'I AėpNACś²'IĄ`PėJfb@ĒN@pNA"HpNA(pNAøf i<0mš(rpNA<9æœ"pNAFĒJFg(Cś'Iaz$€ ŠB€Nu|»Ėg4xN’f` CfZ<6˜aXIśTJFf J€g(@Iģ8TDHÄ"4xN’"nX8“ÄU‰gS‰-IX=„˜Cé`œ˜CéQĢ’ö"nXxpNuašJ€f$AėH P J€gJ†fAėHNu J€gSFg @`ņNu»ĖfahJ€f4'kD>`(a®f&:6˜ Ef*6˜…ßßß<0apNupńNua*(+>r4xN’"nX“ü"nX=¼˜-„˜xpNupNA"Eé’ĪJRg6Ič`v8 4_0gRC¶Dl `šRC8(^˜Co4”Do4ĀGņ@`ŪQŹ’ü&Nu/ hXpNB Wp(åHEī$rS*"AčCī@4xŌN’ _4xĀNŅpńNupķNuIėH (Wč]"nxJ™ AėpNACśĘ'IAÓpNAJ9æ¾`°J†l.Aśl'HĄCśę'I AėpNACśœ'IAÓpNAü’D`|@ĒN@|pNAAčH gf @ h$fņ <ßßߥØ& €FLPfą (€’’Ą @'H¼p ØSand f.rĪJ(?ŠĀ(?Ģ fCśä'I AėpNACś˜'IAÓpNAFĒNu9æ¼9æ¾p$Ąg,Rk.gpfp’Ńk@gpgp’ŃkBNuB+Æ+Fg6r0Ā9æœč ;,jJėŒm $nL+gNŗ L+Žg Nś BBÆB+ŒNu’ k¼(?Ģ(?ŠpĄĄg(Rk.ć dpgp’Ńk@ć dpgp’ŃkBNuB+Ær k¼Ā(?Ģā ;,jJėŒm $nL+gNŗĪ+Žg NśÄBÆB+ŒNu’rĄĀ8’Dg0Rk.8’@gpgp’Ńk@jüB”/ a>01 Path_Device1.02S"š’’Name this of driverPTH|»Ėo&6øg/ *KP/ 4xN’&_*_f"<6˜T‰-IXĢü(Ü®0¼®4l vh0kpNupśNuJvøk pĄ6øSf / Kė4xN’*_f\rŅv˜Ó®X`Jpńr26økBē‰Ņ®|<6Ü® r6hR8T4xN’"nXÜDS‰¶h˜S†QĢ’ōS‰B6˜pNuAč"ßßß<0 Bgpfp’ŃkBNuB+Æ+Fg4r8Ā8’@ę ;,jJėŒm $nL+gNŗJ+Žg Nś@BÆB+ŒNu’’’  f( +f / Gśa&_ā a ‚Nu pNANuHē0špNA+~pNA fJh€gRGJ(‚gTGJ(ƒgXGLčˆJ‚kd ’fąH;d æc@ üd: ßc_f Jj>`8^f4Ž`,_f ā d$`\fžŽ`č¶f pć(Ž2Lß pNu1D$#Fd46BS2@&veEcT3fgtQsV! %C'A'Pe`5wU"ueCaAb`P77w5"uaD$#Fd46BRG2@&veEcT3fgtQsV!0 bU%D$#Fd46BRG2@&vWEcT3fgtQsV!0 4C'A'Pe`5wU"ueCaAb`P77w5"uaD$#Fd46BRG2@&veEcT3fgtQsV!0 bUB€Nu2( 0_f`²PfrpńNu¼_RhrpNue the QIMI interfaceNNo’YYes’’’Cś’ü`Cś’÷po2<ßtv’‘ČNCNu0 ĄĀŁĄHB0ęHŲĄŲĄ0 ĄĆŪĄHC0ęHŚĄŚĄx8˜BpĄC*HEŚ@tÄEEčMgš6SCgčDfÄNŗb0Nŗf»ĢnR2åI”Į–ĮUEl̇a00m rĀ@äHDAŅANū *Ü*Ü*Ü*ÜQČ’öĶGaĻFŁŹŪĖQĖ’Ō`’"† F†Ą†F†‚€*ĮNu2åI0 ĄĆŁĄŲĮ0 ĄĆŪĄŚĮ”Į–ĮUElΆa00m rĀ@äHDAŅANū +$+$+$+$QČ’öĶGaĻF™Ź›ĖQĖ’Ō`0"$‡ %F‡Ą‡F‡‚€*Nuø@oTLÄ|’ąn~’JBgäoFG2åA»Ģn ”Į–Į2|`(0 ĄĆŁĄŲĮQŒ0 ĄĆŪĄŚĮY0J4@’K6A2|’üÄĶGUElĢGJDj LL`J„j ,’žHA,’’HB  蹂ƒ‚ƒ€‘‘‘‚‚ˆˆ   S(k4,€Õk.4,‚Õk@4,„ÕkBB¬‚Bl€tJ,†g tJ,‡g `J,‡gtB+ŒBÆNuJėŒmų$nL+gīNŗö+ŽgäNśģ.ŚCKEYON.ÖCKEYOFFCON__232Hē Cś’Ō4xN’pNA(Hp"<TtNAJ€fŹKčT!Md*H+|PTR2()MÄ+|@<+m<8|P;|2;|4;|6|L|M|’|.ŽpNA&hLBØLN@(H$lD "<Ąg @²Øn `ņ)HDAś’LpvrNB)JDFüJ€f.p v’EśtNC AEķč$Ų$Ų4Ų$ L$hL+J€ ‰+@„!KLr 6xÜN“$Š(JEźprx6xÜN“$Œ+IXPéB. i*XˆCķČ"Ų"Ų"ŲAķÄ(CśF+IAķööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööpNACś €+ICś¬+I$Cś l+ItCś:+IxCś +I|Aķpp NAAśō+HÄN@/pNA,H$nx"k² A&h, +kˆGė’č+KT&M"m>¾g: A"(¼g ŗf,!D`&Nŗą%H’ü–ü’ØNŗ\IčJg"(tpNA!L’¤µī|mø,_|Ų’Lß0šJ€f@Hz&'_PNŗ$ĀfźHēüpNA (Äg&@$kPIś0Č*L:r"\ÓĶNŖ RA²EmņLß?žJ€Nupś`¬Gė\p÷Ą.4fGś" EčGčdBšµĖmśPčC"HpNu€€*kXJ-Bm@PķB|P'|’’HB+NpNA.Aėh g @¾Ø’ÜfōpĄ.4@v’Nŗ"ÜNśtJ«hg"k€³īLf klAčaŅNś`Jg†×+°kÆK<+.gk.ÜFSFSg|J+OoS+OJ+Ng mS+N`R+N+PgnĄRg S+Php`öööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööö°@Pa®(KxJ,ŽfD lĄGśŒN&LxAJ+ßfx×Čg*Gś~NWĮČ&L„g|K` „g|KL« 8z’Jf Bk0B+-`Hp0+0ø+-gāHD-R@7@0€ė2R@ć dÖ@…ē dŌ@…å d–@…ć dN”@…`FJFoB"+@0+68ŲFÉĮg n…`…R@‰ĄÖDHA0+48ŲFÉĮg n…`…R@‰ĄŌDĖ+J+Żg$Aėą“Xl4(’ž¶Xl6(’ž“Xo4(’ž¶Xo6(’žH« 8` |J+Rkj"+<pNu~’J—Nur p` 46˜T‰pND/v’NC&J€Nu@ĄN@?ÓĪa “ĪööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööVĄFßJNuHēĄpRˆR‰°`aa “VČ’ųLßNuĆH ae zc €e ‹bANupńNuHBHC6)’ģ4(’ģ2(8²BmÉA”A–A0)’č2(’čŠi’ģŅh’ģ²@m2’DNux”NśčRHēCėt•Ź )’ųgCņJ)nša f`źpLßNuJ)m"i’ųŅü0Jnd+ܰ)fZJ)m"i’ųŅü0 )’ōŠ©’š°kōn°«ņo |Pé`TLé’šŅ‚ I•Ź (’ųg6AņJ(nš+ܰ(fęNŗ0fąJ)f"Jk IrNŗ÷2f|€` J)g|pNuao TˆaUˆop`HAHBp’NuHAHB0(’ō²@oŠh’š°BNuHē€ p$kF²ü@lÓÉÓÉ"r˜ fCś’`J€f Jf0"@p`ŌLßNu/p@åHP€Nŗf0<@0Ą'HFBXS@B˜QČ’üpLßNupń`*pł`&/ +Fgō$@JAk20*’ž²@ööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööseful for emulation of FLP etc. PTH_USE$ function to return current name of PTH device. PTH_ADD [n,]name add a new path to the list at position n if given, or at the end of the list if n is not supplied. Entries in the list after n are moved down to make room for the new path. PTH_RMV n remove the nth item in the list. May be extended later to allow PTH_RMV \name. There are also two 'special' paths. *d is the current data default, and *p is the current program default. The driver only checks the fir` +hrĀ.4$@²*g fō"AźNŗš ANŗaJ,Ig l\a Aģ’ŠaLß0šNu4xĀNŅ ,gJ,gHēpš @pNALßNuTˆaUˆoHAHB0(²@oŠh°BNuNŗjŠü0 qgęB(J.3fJ+,k |gJ(jp’`ŅNu @bXØ(H(f(h’ųŲü0Iģ’ü¹ėhfŠJ+Pf J+NnÄxaź|P(k€Iģp¹īLfŽ(k„IšČ-LL`~ @zl @rg @olāJ+Pndg +’PmZ|”P`R fJBf:Hēą(k`$+<”¬pšH@Ā"<҂€Ҭ H@°kņmHĀažźLßoJ+Nn’$x”aH @llp @-fJmaZgp"(&`Ö g4 f2B+RJ(CnNŗ ŗ`H§`pa Nŗ ¬/pa LŸfžp B+Ra`’/ Nŗ&_Nu&kst letter after the '*', so you can use *Data_default or similar to make things more readable. Examples.. My usual setup is: 100 PTH_ADD win1_:rem always try here first 110 PTH_ADD flp1_:rem look here if not found on WIN1_ 120 PTH_ADD sub1_:rem SUB is another new driver wot i rote 130 PTH_ADD 'sub2' 140 PTH_ADD win1_temp_ 150 PTH_ADD 'win1_asm_temp_' 160 PTH_ADD win1_bas_prg_ 170 PTH_ADD win1_sys 180 DATA_USE pth1_:rem set the toolkit 2 defaults to use the new device 190 PROG_USE pth1_ If I then do PTH_LT(kNŌ @n¤ @zf*(g"Hēąą g @üJ(Cošpa¾PčC`ęLßJ(Co0Hēą`pa¦R(CLßaŠü0J(Co"B(CHēĄ@pa†LßJ€`@lŠ@0; N»ü0NuF,Ŗ0B€.z(šT( Ž8 ¦ – ģ²|pńNup’NuEó`ŁQŹ’ü"KpNu"<2.01"k(`šQė­J+PfB+,Hē’ž$kDa†aŚLß’PėPø+PbDPNu*JCf *nd*UB© `0(’ęåH*nh*u() Eėp"ŚQČ’ü’üBj&tJfB+RJ+PVėPfJ+,k8B+Ra®`J+,kJJ+Pg $H(f$h’ųŌü0Eź’üµėhfPėPJ+RgŚJ+g Äf J(k±ėØgJ(kxÄr’"3A#A`Ž$B+­Øgr`:$k€Eźp/ 6xāN“&_m.IST, I get: 0 win1_ 1 flp1_ 2 sub1_ 3 sub2_ 4 win1_temp_ etc. Notice how (as an example) some of the paths are strings, some names. Some include an underscore on the end, others don't. The PTH_ADD command sorts them out automatically. If I then try to load 'demo_bas', the system searches 7 paths, and eventually finds it in 'win1_bas_prg_' less than a tenth of a second later. If I load 'boot', which is on win1_, the load occurs about as fast as normal. If I load 'fred', which doesn't exist, the system sJ+Žf  gč  gā)fŚJ(j æbA ÄkJ f) g( b"A „J+OngnO`nOÄ"+<ŗgÄJ+RfBB#D į˜Ą-fg ±-f@ `Äfp’Nug +MD@NØgB+RpNuašf¾J‚j‚f0ĄQat4BŌB42 g 6*HA:8*g,šhDESE8*`ÄGv’8+šDD:g DCDDšhDESE<ĢBpHBĄBHB0;Nū``čœHHĄxHēp2pt62 ĘGUB²CWČ’ō @g(€LßNuaŌHA2`r’pNug0ĄQ“@gäSEkčŅCŅÄ`īg0ĄQ“@fĢSEkŠŅCŅÄ`īg0ĄQ¼@g“šCkøŅCęnęodģT‰><ĢB`āg0ĄQ¼@fšCk”ŅCęnęodģT‰><ĢB`āg 0ĄQearches all 8 paths before reporting 'Not Found'. There are some pitfalls in the use of drivers of this type, mainly because you never know where the file you opened is. This is OK for load and exec, since you (probably) don't care too much, but save will save to the first path it finds room on. For writing, it's probably best to name the device explicitly. Reading you can leave to the path device. If you want to check where the open file is located, while it's open you can use QRAM or QPAC2's channels men¼@g’lšCk’n’CēnēodčU‰><ĢB`Žg 0ĄQ¼@f’DšCk’F’CēnēodčU‰><ĢB`Ž0ĄQažś2pNuHA²hdJHA²hdB6ÖhĘėšÖØ2"C&HCÖh8C’ųäKŅĆEś"J(gEś.D’ž>*DčopNupüNu’’’’’’’’€€UŖ’ŖŖUŖŖŖ’ĄĄLß _Nu/HēppNŗˆfģ/J|J(g|0)@@’šäH:ĄéxŲ€ +“ @gø«øo*B«“pNA"tpNAJ€f¤QQ&o'H“'Aø(L×/H (I Ü Ü ÜB˜ üB˜p˜€äŒ(Hp`(ĄQĢ’ü8+²>(iIńČ&)`N$L&HČüē+VD0ĄĆH@HCĄÅÕĄ×ĄČüē+VD0ĄĆH@HC2A’ųAŠ@ŠF0;,äIĄrg ÖĮ2ĀSfSSB¾DgJBf®Lß _7D²NśĄ€€@@ ĄĄĄĄ0000 u to list the open channels. These channels appear twice, once as PTH1_filename, and a second time with the real drive name. Points to note... It's best to allocate all the paths you need in a block, and as early as possible, like the example above. This reduces heap fragmentation. If you need to remove all the paths... for f=1 to n:pth_rmv 0 where n is the number of paths set, or if you don't know how many paths are set... rep loop:if pth$(0)='':exit loop:else:pth_rmv 0 There's only one path list used fHē`Nŗdmfz6–Ajz’DCHAHB| (fģiģj8˜Aj|’DD (fÜFŅAŌBHFBFHAHBøClĒDĖF>āO`Hē? aBLßü҆žCjŅ…ŽD“fčpLßNuHē`NŗmKś0`Hē`NŗŽmKśtNŗLßNuKśfNśHē@ĄHē/ ĖIal$_fš WHÅJ(PfÜHē>~(h`XŒ4SBčJRBŗBnŠ8RDåLŌ@ŗBl4RBvJ@m6p`å@”Coœ?z’BEä½FEę½:ÜFHF<چ܆˜†!D!EJ(lNŗNŗ Nŗ6` /rčŗŁÉĀFÄF FFĄF€A ĄFFF€BŪÉ0mj`  č¹ čŗJDjHAHBNotes on the PTH (path) driver.  August 1991 PA Borman This adds a new device driver to Qdos, giving extra devices or directories (paths) to search for a file when opening, loading, execing etc. Because it is implemented at device driver level, it's transparent to the program using it, although it does involve a slight (almost un-noticeable) time penalty on IO operations. The open call can take a significant amount of time depending on sever®J+Hf|HB.3r av`ˆR+®%j *+@gv~’xŲ+Lā vÖā HEJEo ŗCmrȚC`grĄŚCo šCHGBGHG`a,HEJEgo ŗDmrؚD`rŠŚDna`ĄšDBGJ‡fø'E@`/ 6xąN“&_NuJ+KfB«@B+®B+H¼+LcīJ+NmęB+PkMNaī`Č+Kg:J+Ign t`J+HgBBJ|HJg2B.3"k€EépµīLf a’€`+HnB«HQėŻPėO`|žHJ+,md +Øg^ @(f h’ųŠü0 +hgF$@”ü’üJ+¬m µČg6J(gn.Jg* fNŗņB+N"k€#i|x+’IB+JPė®Nŗ€"k€Eép-JLB«@Nu  a$'k8<'B`Hē KaŖ!KDa&LßhNuHē_ "+8t’v’~B+ŽCėl$i’üXŠ*jal factors. The driver returns as soon as a successful match is found, so the earlier the correct path is in the path list, the sooner it's found. The more paths there are, the longer it takes to search them for a non- existent file before giving up. If a path involves reading the network, there can be a few seconds delay before returning. If a path involves reading a drive which does not contain a disc, there will be a delay until the real driver notices there isn't a disc. In spite of all this, on my,j $j’ü g$Xо*fšJ*nź*fāLź0’čaŚfÖ`2J+,køEėl$j’ü gŖXŠJ*nī*fęLź0’ča¦fŚt*f(***aŽgš gp$@EŅ`ę"J g"@CŃ)gšLé0’čadfl$I * gh"@ Y,)$) g gRƒ"@LŃ0چa8fģ )g,$`(v’"j X‰LŃ0ag`•ŹCėp’"Ą2Ą"Ą'JØ`>)g Ē`4<Aź’Š"nxp’±ŁWČ’üF@Cė2č2Ą2ƒ…"ĮBYB™"Ä"Å"ŹxJ.3fb+,kCś8>āe62|`0«ß2|`2|x`2|` 2|x’`2| k€!h|xNŗvp’Nŗ.“«gB+@±D¬a ĄfżčLß QL with 8 paths set up in my usual 'boot' (not including network), trying to load a non-existent file returns in about a tenth of a second. There are several new keywords associated with the driver: PTH_LIST [#n] list all currently defined paths in the order they will be searched to #1, or another specified channel. PTH$(n) a function to return the nth path in the list. Returns an empty string if past end of list. PTH_USE [name] change the name of the PTH device. PTH_USE by itself resets to PTH. UśNu EmDd …m 0„dpNupüNuJ(’āf g @AŠ`š (’ćc (q’ćg + ­g R+­NupQė­Nu/.LB®L(k0/ &k’üN”&_-_LJ€f2/Gė’ØpNAAėh g @²Ø’Üg"`ņvNŗĘgaf _4xĀN’pżNuaüčaFp _Nś®"nx±Ńf JnpgpNuHē +„Cš0³īLf "k€Cép-IL4xŌIč0J,m:"l’ųKé0Cķ’ü³ėhfPėILķ’čHģ’ča.)mB,CÕAŌN’`Ž gr @ü*H!l’ü’ü!l’ų’ų|€ĖLaöĖL+l+llB,Cč’ų$Y fEėd%I$QY‰ fEėp%I’üEŠCč’Š g$$@%I’ųŖ`īAģ’üCėhN’Aģ’ųCėlN’`. ,gd MNŗ¦Lģ ’š“­’šf¶­’ōgHJ-j"L MNŗ˜ LNŗžJ€NuHē’lpØ×ĄŃØ*KCķh$I"( g2"@²©’Üfō³ķhfPķICé’ŌEé0Gč0&’$‹!I(i@@)B`*rĀ.4JčAGč,Cķh&‘"‹ g "@Y‹#K’ü`Y‹+Kl&MŠü0Ņü0J(k()g Lé ’čLčĄĶGNŗżng !i’č!i’ģ²(gNŗlLé’č)NŗżnJlxJ(kr²©’čf“©’ģgf!iiHē`Š(INŗ0$H&Lß J€f@#JQƒQƒ#C/(’č/(  Ģn`ˆˆ€Œąˆˆh`  ˜nšˆˆŒ ˆ ˆ@h@  dn`ˆˆŒ`ˆˆh`  0n`ˆˆŒpˆˆh`  ün‰ØˆØŒØˆØˆØiŠ  Čn‰°ˆŒˆˆh ”n˜‰¤ˆ„Œˆˆˆ h¼ <`  $H 40üüüüüüüüüü’ģHč’čĮINŗvĮI!_’ģ!_’čJ(gHē`Š hpNALß Bؐü0Lß6’Nu (fHēųz`Hēųzx”Nŗš†(H(2,’špAąiRA<Āģ’ņgpåJ„g²„n al I"QĀ`D l g ²¬oB(aR"/ p$,’ŲNA&_&gT€g6GśöpNA `*Cėø!I’ōPĀ)H)AB.4Pģa˜NŗøpLßžNuJ,g ,gB¬ @/ pNA&_NuHēųz (fz 0Pģ`Hēųzx”Nŗļ¶(H. f l,F„"HJfB¬` I gHē Ha ÅCĒJĖLNŗ