QL5A6752  P                                !000@PPPPPPPP``````pppppppp    00$turbo_sms_codeU> ~ turbo_tk_codeU>FunzipU>n  utility_taskU>JwmanU>jvzipU>fp.@CpNup+gB.4pNu':"R B>  J ~  N 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 0 0 0 0 0000000000000000000 0!0"0#0$0%0&0'0(0)0*0+0,0-0.0/000102030405060708@@@@PPPPPPPPPP P P P P PPPPPPPPPPPPPPP`````````` ` ppppp      !"#$%&'()*+,-./01234500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006789:;<=>?@ABCDEF               !"#$%&'()*+,-./0123456789:;<00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000BOOTU>DJTK_docU> DJTOOLKIT_BINU>env_binU>*: environ_docU> environ_TxtU>.PHot_rextU>0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000,pth_rextU> pth_txtU> Hpptr_genU> QEDU> QED_DOCU> }QED_HELPU>' QEDCONFG_basU>qlib_extU>0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)QLib_run_336modU> )QLib_run_336mod_txtU>READMEU>Tl sigext30_asmU> sigext30_rextU> signals_docU>@@Tk2_extU>rturbo_rem_codeU>0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000stood 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 im.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_HEAD00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000possible 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 ER - 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, eit/.NHxa&O pfR`pLfR`p g JgR`R100 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 PRINTnsure 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" underative 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 channel #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"  .`NVH0EjGWNHxBN JƤJgN JƤB JJg J/N JBXO JǼJg JǼ/N JǼBXO JǴJg JǴ/NXO JƬJg JƬ/N JǴB JƬBL N^Nuwarning: cannot set time for %s %sEmpty zipfile. Archive: %s ile'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.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, horective 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 eGET_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 relw_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 :-1010NVH"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 tel = 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,ion 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, tell. 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 0ng 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 returthe 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 isgatives & 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 su 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 f 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 ame 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 wloating 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 followifiles 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.Ther 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 yol 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 ee 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 e. 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 retuned 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 thixample -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 trn 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.s 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 additionahe 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/A N. U- M:M<#M_M`MaWMMMMMiMjM@MA*MkMlMm$MM\MMMMMMM M@MAMTMUNMM*MMacted 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 '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 unsignedM `M a"M M M eM fM g*M M /M ;M AM =LM EM >M .M :@M zBM 8M BM 62M h<M -M *M 9M4(M\/M2M2M2M!<M]2M1M1M7M(1MY;ress 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 ret, 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 negatiMJMHM&IMo'MDMCM8MU@MBM-M.M2.M`4M.M:M=M9BM{DMJM <MEDM/M.MAM'HMo<M7MJM,M-M.M/MMMMMrror 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 extr 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 capitalMMM!MMMMMMVMNMOMP*Mz*M*MMMMM)M*WMM-MM MM-MM MM,M"M#MMMMturn 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 beior_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!M!&M!M!M#M#M$*M$+M$M$M%M%M&7M&8M&M&M&+M'M'M(M(M)M)M)M)M)M*bM*cM*dM*Mng 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 casee 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+FM+G)M,pM,qM,rM,M,M-M-M-M-M-,M.M.M.M/M/M/M/M/M/M/M1M1M1M1M1M2M2M2M2M2M4vM4wM4M4Murns 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 reve 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_GMGMGMG(MG*MH MHMHnMIMI'MJMJMKMKMLMLMM[MM\MM]!MM~MMMNMNoM PMPcMRUMRVMRWMRgMRhMS#MS$MS%LMSqIMSKMTBMTGNM~M~MsMtMu#MM@MM2M M$M8MW5MMMMMMMMMMMM'MMMM>M;<Mw<MAM,M ?M_-MM000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005M5M5<M5=rM6M6M7yM7zM7{1M7M7M8`M8a4M8M8,M8*M8M9(M9+ M98 M9DM9K,M9w'M9M9+M9 M9 M9M:M:)M:EM:L!M:m"M:M:M:M:n9MnVMnWMoMoMoMpMp MpMp2MqMqMq2,Mq^2MqMqMqYMqMqMqMrMrMsMsMtMtMtMtMt!MvMvMvMvMvMwMwMwMMMMMMM6MJMgMMMMMMMM|MMMMMMUM"Mease note, every QL has at leaB%@ '1;E> Q0( H*hRA@tN"6J@gp`>Np U0(:H2(_M>`M>aM>bM>xM>yM@M@M@M@)MBMB MC&MC'MC(MC)MC?MC@MDMDMDMDMD$MFMFMFMF8MF9^Mw4Mw5MxMxMx.MyMyMyMyMzMzM{UM{VM{WM{XM{mM{nM|M|$M|8M|?M|XM|_M|xM|M|M|!M|M|M|&M}*M}BM}TM}UuM~M~M~00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000MgMgMg!MgMguMimMinMioMiMiMiYMiMjFMjFMjZ<Mj/MjMj"Mk.Mk4/MkcXMkMkMkMkMkMkMl MlMlMlMlMlMlSMn7Mn8MMMPMMM|M}M~&MMzMM M!M>M?\MMM)MMgM.M/M0M1MFMGMMMMMM4MMMgMzMM 104eHAH`Thanks Ralf !!"<t` f"0pNua tS@gr` Rr` HNupa ft"6oZa g"` NDhp"t` a S@f(pa f"&1RY C NDhpf BpNAp`pNu~B`~Ca zU@gpNua xgpa xf 6a 2f"6 BfJkvNC fpNu~` ~`~`~a (U@gpNua &g f$Kpa f*6&MPpa f`pa f*6 a f4v nrGNDpNCNua U@gpNua gKpa f.6&MKpa f41m a XfTBvNDpNCNua pU@gpNua nfpKa jf.6&MKpa Xf$G41gk`MTMT<MUMUfMV9MV:MWMW$MWMW$MXMX%#MXHMXY?MX MX MXMX(MXMXZMY;MY<MYYMY` MYMYMY8MY MY MZMZ MZMZ%(MZM#MZp;MZ3M<MM?M 9MB?MM#MMGMMMM@M4MMMM=M>MCMDMcMv3M M%M,M!M(MAMBMC McMdMMMMNH<(.*<fE"GfIVKf.<fJ&gJB|BC 4xNNu. 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_HEADERLEVEL2 FILE_POSITION FILE_LENGTHFILE_DATASPACEn FILE_TYPEn FILE_BACKUP\ FZMZMZM[ M[M[M\M\PM]eM]fM]M]M_M_M_&M_M_Ma\Ma]Mb!Mb"Mb#Mb?Mb]Mb^1MdMdMdMd!MdMdMfMfMfMfMfMfMMMM MMM4MRMjMy MM!MMM.M.M M MMMM.M.MM.M(.MVMW4MM9M"M.M'M<M=JMMILE_UPDATEGET_BYTEGET_WORDGET_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 gpNura<=-1.15-IXxpNua gr`a "t` a gr`prtNAtJfr` JH` D~d`~2a tS@fa fr` r` Nupa ~ft 6ka 4fp 2vENNCJg"`< G2g6/pNA" Nu 1f ->f >f CoT`r 2f ->f Cor`C4xNpNA~ SMSQg 2.00m~A*|*Cl4xNJf"n $n$S 6gf`jIGt JR6fRQ**`F$H`c68 ENV support v1.07 8_ENV_:SETENV ENV_LISTENV_DELnGETENV$Nu4xN Cfx86 Dm(I":҄RtpNAJf,SD"H6R =f f*IQBgfpNA`v. SG$zf*H(I`^":vgS$  =ggQ(I`.Q(I`&& SGf&H(B fQgQ(B`"B`*H z$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 a r"H _Jgg/a H "t"nX`n*/ ~Ga $"_.Jfr Gf1p` 1pH瀀p INAL`atS@gr`.Nuagpaf 6afpCrv/ NC"_Jg g"t`~` ~`~`~a~tS@gr`Nuavgpavf 6a0gt`R-IXra-IX$vNDpNCJg`4"nX GfpxNut"6 GgxBAHA GglAI`bt"`ZaS@gpNuagpaf 6af. rxvpNCJfQ"G`*aU@gpNuagpafp06alr26.l`V gnT` Y-IXa/ T$vNDpNC"_Jf =x-IXNuaHU@gpNupKaHfgpNAA ͙ `4xN Ce g`>6`~(ޮ04l vx>k$z(:gSvgpNCJfQ`Jgr z`aJffr`R&J" V A4xN"nX-IX(I=2 T`RQx`k`QB":,A* ` pNupNupNupNuNu4xN Cfx86g:VEEP-JX*z zg0:SE(IT$M6fRQ =fJfS`Jgֻo$z*J`pL0NuNU/ E$ BBHm/ /-NJlp` -$mN]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, (vp&MPa8f>6mr2.V gn|` ]-IXaJ-IX=`RQ"nXpxNuatS@gr`vNuagr@af<*paf 6Tazf$. pOrtv"ENC,p INAt"G"gr`(t"` r`altS@gr`Nupajf~>6oK0`6 RQ/ pr$NA"_Jg2`Z&h*h"( 03 @g @ gPl6`4s2f0/ `2 6f RRQp"_J@fr`rRGt`h~`~ agr`a"( t`~`~atW@gr`NuKpaf(v*6nTr`&MKpajfr26K $VTtJAgPeL00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000below 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 thRQpNua &W@gpNupa *f"6$6&6gge SЁb"$AԃS&B~`$A&B~ edfTf g pSSQW` fS`WW g&Sf gVVJg SfpNua ^S@gpNua \gpa \f 6a fpAvNCNu~G`~Fa ,tU@gr` Nua $gpa $f 1\a f 1jp` / "@a "_t"` ~`~` ~`~4`~606lt`@ag"t`R*Ip vE0NC I"MJft Gf"(*`. Gf"(.` r`"HpNuagrt`Tar hHgRA P`aU@gpNuKpaf(vX&MPpaxfpRQpNuaPS@gtr`paPgNu$vra-IXpRQpx"nXNuz`z`z`z`z`Credit to SNGaS@grt`pagNupr& I/ NDNB"_26RAJfH$n0r(4l J6k R@`<4xE,N$n4G(-K40-rXBQPr2t`ad[@grt`a^gpa^gNup06aP-IXQJoperating 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 prerrogate 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 Envf*"O*IpltvNCJf8x x"nXP=NJfQ"nXP"t`~`~`~aW@gpNupaf v 6g"6 g$f g SfNu0SfNuSfNu-IX/8*g8<ҁiSD*p"i@*@f"g 0xN"nX-IX#3xpNu-IXH`Jg "4xN"nXL=xp-IXNuJk (Ю04l vJkp`p`pJNu Nu6Nu$|4rNNut@vNCJNupNBpNuH`pNALNuHppptNALJNuH 4xN"nXLNua*aRg"|  )>g )&faQ`a.f `NuagR`Nug gR`RNu g  g ogram 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 uironment 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 maSAJg$H@6 ae zbRQL Jg ae zb5g RSl(B`4H@ `Jg ae zb5f RRQtL0Jg" tgaS@gpNupaf 6g @ P`a hHxg8($H|"ta/ 4x N"_L>JfB"V gnz` ]-IXa=(I` &RRQ-IXxpNua @gpNuagpaf*I"v$v 6kafp%vNCNu~&`~(aU@gpNuagpafp2606ka|fp 4vENCNu1 pNuatS@gr`,Nuagpafp06lp`a4g"t`tppv&INC"KJg fr`r00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000he 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 noY GZc G G G Gp 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 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000in() 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 now 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=VALUEand the list is terminated by a NULL pointer.A user program has a number of library routines available to manipulaVariables 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.doc',16;@E "',16;@EM  IBp LN]NuNUpN]NuNUpN]NuNUpN]NuNUH $m0*|f%|0*|@g%|Q0*|gjv`8  @oJg&  @o%P  @oBj`FRpnHxNW%@gj` jj0*|gpЊ%@%| *LN]NuNU//- /-NO&o/NW+@XOn p&-N]Nu/B/-NM`NUHv m8`0D(HHSDJDn LN]NuNU/- SgUg Sg<g&<! &N]Nu&<!`&<a`NU/J- gv`& G Gl Gf Gg G{ G|[ G G G" G G G I I I I I I Ic I= I> IH IR I[ I\k I It 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 "NAMw 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 Environsion - 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. BHmNL+@POm/-NLJXOHmNDR#^l#Z`p`NU/- /-HyNPN]NuNU/- /-HyNPN]NuNUH Eo+mpJl pLN]Nu mB$ R<gp В`  m B$ R<gp В` RE=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 usnment 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 no00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ers 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 proct. 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. The00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000edure 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") 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. STANDARD ENVIRONMENT VARIABLES A number of standard Environment Variables are set up automatically by the C68 system. These are PROG_USE DATA_USE SPL_USE They contain the values for the Program, Data anR JggBB`NUH Eo mB$ R<`ZHOTKEY System II V2.29 THING System V0.05 <>01HOTKEY System II2.29D*KzPr SlmDefault drive for executable programs: if you have Toolkit II, the HOTKEY system will use the program defaultKeyboard 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 progra 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_FILEd 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 variablesexplms or by the QPTR command HOT_STUFFPrevious 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 hilast line recall  HOT_STUFFHOT_GOHOT_STOPHOT_LIST=" & 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 noicitly at the SuperBasic levle. WHAT PROGRAMS USE ENVIRONMENT VARIABLES To 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 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 exteHOT_DO~EXEPfERTTH_FIX6ALTKEYHOT_RESHOT_RES1HOT_CHPHOT_CHP1HOT_LOAD HOT_LOAD1 HOT_THING HOT_THING1HOT_PICKHOT_WAKEHOT_KEYHOT_CMD HOT_NAME$vHOT_TYPEHOT_OFFHOT_SETHOT_REMVbALTKEY VTK2_EXTH`4xNLHf< I:<T*H0g\S&n 6g8"n Sa(f*vf g(v=-$HTRSn`PmFVH`gp"LLp "VvN,f""H0hiHF0Ba2ENg IN(( Kp'N `N MN NNu2f 2f=Nu4DAvA=A@gH`mE RRSAn`E SSSAnJDgBJEgBLNu 2f 2f 260RSAnpNuI/ II\vNXfpGtNtf )f $&)pNupN |`| HFNf(p"vNfHFN"H2ENrgNNNu|`| NPf NlgmpNu|NNZfNRNjNuNJfNNZNupNf.Nfλf/"V>6xNf2NfNfKN2HD8) g: @fg(_vMpNAMpNԐ )a`aX6xNYINupNu"hC )ar``/ Jf ) a^`alJ`p$_NuA#HA$#H A#HBNu/) ) a(`a6 g0$@A"(aJggtpNAG!K|Bh `NuA`rvpNA f"i`C$g"Bf$*"QpNup`H` N@EJj$g,$BC*N$f`$g$B*%fC*N f"JLNup`H`ELpr4`2QLNuaf HfpNup`H0 p EgDgv(t +g -fDg, 2f BBփi"ҁiҁi ցi0րhp`SJBfpJjD"JL NuHx02iP@ @b<0;NZ`f "D * )g/NuN"gNNgNpNuH`h$kSBmgN>N6g`Jgg@NfxN|N,Wg*f0rNxf(xPSDo"a^pNA"hx"QLlѳLoLp `pLNuN`'kpHx )(@fI pNA$hLaga`LNu/ prvNA"_Nu@N@?|fg 6xNfJfpFJNuJga `'k"k gJfS$ "@pNuEH"WN BENafvaCar` BENaxavatl>"W  g.N xg"JgaZJgp+rab"WaHDNnf pRfTNz. GNNup4BGo:pNuBDa RE Em`r pvNCJNuNfN fN8fN`rNhNNu ig" igI2`"/)N(i#_`(i" JfSÌpNuN>fNfNfp0)HNNNu|~Nf0Pg vf |6`|NfE "N.NpNuNf E NNNuNfN6fNbfNPNfj-IXQNf^26E$ RB26(vkB(<@n fx`0HD6Er` 22V@4HB4J@jĄ LNuH`E\r` 0Qf(H`EJrH` 22VLfpNup`H@r0`QLNuA;Nu  !"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~H@`  f02S@n`VH@`BQpEnJ2nFJl8(mmEp`"Hz`Hzp ff Jf @"` @f`JfBpPN"6fZ'HE8!JA& 0.050 THING$THG%SA&$A$pN!f(H <N!fG8&THG%E$C$C$$C$BZ$2.29C$$$"Hp&NfpNAA<"H g @H@J@f((Q" I`E(K0gC(`I '|Hot%7|g C>BYN$nL(K6xN&Lf6Rf2"j RmC$*grNP Pb`QLNLpNu[_$NuHGpNALJNu CN(KN f"kN &L g NCNNuNPf"6l NuNf>p vNf2N Rf(|N"HBfNRg 3|NFN JfpNNNu|` |`| `| HFN`fHp2EjNf|"V0f0f0626=ENfZ"V=*Hf""pH0NAL Jf(Hpe@Nf&`pe@(@ЂN fpH"LHN.Mf"VT0g4EP 6,f(vF@g @0b=zaRRS@n`$E ZJf0g @0cp0aRS@n"HA*&Ha A^#H THG%p Jg  `p, p< pNAL9Z6`L9ZLJNu~Vnp`HA*Ng2N o@%JjC*N4C4xN"HNpLNp` f"n` Nf"QpNd$INfNXNTNvf IaNFH|AaL@NuC4xN"HNpNuNBfNf IC4xN"HpNN"f NRfNNNff6Nj%i&$I"i)gJg g )fp` / "JNN"_NJAj nd o P2(HAh2` r`nbb @@ nh pH@hfpNup`J)$jpJf( )a&`p a6f!AG!KX6xNYJNugHO^aLzNu/NuTNuHpp"4xNJLNuH4xNLNuAJBo7A%j PJknNu )f&/ G8N&_gJfJ)fr4xNB)pNu/B)4xN _Nu(IG8ApNA +g @N!2<N@SAlN LN Hp@N@?afC!IFpLNuaf |BhNuHpaLNu"+g ptNAJgBBkpNuHxaI6prt&NAJf'A!K0N \p0U@nLNuN ``JHOTKEY`P2+oNfNQgNBkprvNA`prvNA gH8 EoJ2f.6Nf Jmg A0BJn`JmDpLNup`H`hN`H`hNf"(I2) Amg Np*N LNLNupS`vS@A,` RRQlNf?vX-IXp"VLNup`H0hi0Xa NrpL Nu&I06T0gTU@nNuNHfBNf<26p AN f*$I"H0hi0B0RSAnE2Ng INNNuNfPo vf ~6JNupNuH xz~6Nfp VTHJvgaPlXSgHG@N@*NHppNA,H,tpNAJgp`Lg H@H@&m^ @lXz @f:H@0;6N2,MFJgQo fvrf N(_JNuX`Hp6pNA"(g A"g A`p` h f(p0LJNuHp6rpNALJNuHppt`Hpp$`Hppt"pNAJLNuHprNf./B Ѓ/@$I"o g 0HRր"/"JpNAJfr/AtpNA/H / g"H#H"@0`Q o "H W$o"/$/Hz//(Nua4f"/L / p NA&_Jg"//&pNA `a LNu o$o r"o(NHpNBLJNuH@@rpNBJg0|LNuHpNALJNuNqHP@vNCL JNuNq/vNC&JNuv|aJf |p "V=Pa f "V<6HFapNu gH@RFFfBF//pNAP3$ _Nuv|/ +g($kf$kАF@J"Vg `J"WfR'J$_pNu/ N$f% EHEp`/ a$_NuEJ2fEpJWfpNupNuHa&`HahfBB`Ha`HpaLNup I2 Ag(ra:f PNQgRfpNuHa `Ha`JgAa gE2EH0gnD@HI"T QhifpNupNuH`N\rt HBNLNuH`HkI R(@N0rt HB&LINNXLNuHp!a"H g"JLNup,HxAIɕ28<AdDx/HT*H` ;g ,gZ !gTQ`x ;@X"HT*H {fpUA }g, fpNDo4`(RRSAn`Nlf.pvNPf"064$H4TU@n"HENN>pNuxa`aJjNux|~(KNfJggK*.X\af*p vf 6BF KGgRFafQ-IX`&Lfrڮ\-EX(IajJFgb2NfZp ЅafP$H4hi4\26`RQSFo rҌ(A`C " $I3# 2"HN$` a Sf`|N2Nf ifNpNuNfBBBNQmngNf vfP6N $ ifP` pgL gg fWgf ufF`/zlNf| Cf~/v/vP``Fo/z^JEf@"VT I:6p 6_g gR@E@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;HNuQC`SAl`,SRAg ,fUAm ;@$HT*HQ ; g0BaX@3L1NuH~|pi @ g @ f|xzN"+Ntf$'B$Ym(fgo X/$anopL~JNuta*g& fN|gNaNg fpJNup|H@@vNCLJNuHX(.tpNAJgJgr`C o YJf JPg N~g`JPg JfpJf$LJNuHq@@N@&pNA4HC2(r hx0H 0m0"@if(&)RBAn0H 0m"@f )0 @p`pFLJNuNVg"H@J@fH@@1NtAY cp`pNuHz(0N BXpNuH//$ (MT"_)>) JQIST, 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 so8 v0f.P/aBLfPHz/////H pNu _X`v~afNfJ6gpNBpNuv~/a"f0&a0g*JGm&g f"JJ&` f azfvJaXNumt@`t<pNu~JNur p` 46TpND/vNC&JNu@N@?a 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000st 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_LVFJNuHpRR`aa VLNuH ae zc e bANupNue. caution: zipfile comment truncated envargs: cannot get memory for arguments  !"#$%&'()*+,-./0123456789:;<=>?@A  !"#$%&'()*+,-./0123456789:;<=>?@AB00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000or all 8 PTH devices, PTH1 to PTH8. It's best to refer to only one device (I always use PTH1_) as the QL only allows references to 16 'drives'. With 2 floppies, a couple of ram discs, 2 microdrives, a network device or two, a hard disc and some SUB devices, you can see there may not be room for 8 PTH devices too. There's no advantage in using more than one anyway. If (for some reason I haven't thought of) you really need more than one list, you can rename the first PTH device with PTH_USE, and then load a ateDCL implodeuuuuuuuuuuu%s: "<ptNAJgNuGE&E&EJ&BPEz&&(E6&|06&PTH0&&HAp"NAC4xNPTH_USE:PTH_LISTPTH_ADDPTH_RMVPTH_USE$&PTH$a2JfJ(HaCH Jg:"@BF L/ 24xNJf$RFt< pNCJfQ"WC4xNJg"_Nupr NCJf"_ Jg"@`pNu4xNJf SCf<6JFmaJo $@  p JNANu<<Ig$IfK4xNJf^<6JFm&MK/a,JfDB26PA/ ptNA"_Jf.$HA260`RQx_(gRjtral-dir record: %9ld (%.8lXh) (based on the length of the cenNotes 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 severearches 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 menaz$ BNu|g4xNf` CfZ<6aXITJFf Jg(@I8TDH"4xN"nX8UgS-IX=C`CQ"nXxpNuaJf$AH P JgJfAHNu JgSFg @`NufahJf4'kD>`(af&:6 Ef*6<0apNupNua*(+>r4xN"nX"nX=-xpNupNA"EJRg6I`v8 4_0gRCDl `RC8(^Co4Do4G@`Q&Nu/ hXpNB Wp(HE$rS*"AC@4xN _4xNpNupNuIH (W]"nxJal 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 myu 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 fjB/ a>01 Path_Device1.02S"Name this of driverPTH|o&6g/ *KP/ 4xN&_*_f"<6T-IX(ܮ04l vh0kpNupNuJvk p6Sf / K4xN*_f\rvӮX`Jpr26kBҮ|<6ܮ r6hR8T4xN"nXDShSQSB6pNuA"<0 B 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. U00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000pNAC +IC+I$C l+ItC:+IxC +I|App NAA+HN@/pNA,H$nx"k A&h, +kG+KT&M"m>g: A"(g f,!D`&N%HN\IJg"(tpNA!L|m,_|L0Jf@Hz&'_PN$fHpNA (g&@$kPI0*L:r"\N RAEmL?JNup`G\p.4fG" EGdBmPC"HpNu*kXJ-Bm@PB|P'|HB+NpNA.Ah g @fp.4@vN"NtJhg"kLf klAaN`Jg+kK<+.gk.FSFSg|J+OoS+OJ+Ng mS+N`R+N+PgnRg S+Php`T(kN @n @zf*(g"H g @J(CopaPC`LJ(Co0H`paR(CLa0J(Co"B(CH@paLJ`@l@0; N0NuF,0B.z(T( 8 |pNupNuE`Q"KpNu"<2.01"k(`QJ+PfB+,H$kDaaLPP+PbDPNu*JCf *nd*UB `0(H*nh*u() Ep"QBj&tJfB+RJ+PVPfJ+,k8B+Ra`J+,kJJ+Pg $H(f$h0EhfPPJ+RgJ+g f J(kgJ(kxr"3A#A`$B+gr`:$kEp/ 6xN&_m.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000@Pa(KxJ,fD lGN&LxAJ+fxg*G~NW&Lg|K` g|KL 8zJf Bk0B+-`Hp0+0+-gHD-R@7@02R@ d@ d@ d@ dN@`FJFoB"+@0+68Fg n`R@DHA0+48Fg n`R@D+J+g$AXl4(Xl6(Xo4(Xo6(H 8` |J+Rkj"+<B`g0Q@fCkCnodT><B`g 0Qsecond copy. If you have any problems with this device, find any bugs, or would like to know more about how it works, please contact me. --------- file comment begins ---------------------------- -------------------------- file comment ends ----------------------------- %03d%2u-%s-%02u %02u:%02u%u %s %u %02u:%02u:%02u%04u%02u%02u.%02u%02u%02uKbhlqx':MV`i}NXFSfatamivmsunxcmsatr S(k4,k.4,k@4,kBBBltJ,g tJ,g `J,gtB+BNuJm$nL+gN+gN.CKEYON.CKEYOFFCON__232H C4xNpNA(Hp"<TtNAJfKT!Md*H+|PTR2()M+|@<+m<8|P;|2;|4;|6|L|M||.pNA&hLBLN@(H$lD "<g @n `)HDALpvrNB)JDFJf.p vEtNC AE$$4$ L$hL+J +@!KLr 6xN$(JEprx6xN$+IXPB. i*XC"""A(CF+IA` +hr.4$@*g f"AN ANaJ,Ig l\a AaL0Nu4xN ,gJ,gHp @pNALNuTaUoHAHB0(@ohBNuNj0 qgB(J.3fJ+,k |gJ(jp`Nu @bX(H(f(h0IhfJ+Pf J+Nnxa|P(kIpLf(kI-LL`~ @zl @rg @olJ+Pndg +PmZ|P`R fJBf:H(k`$+<pH@Ā"<҂€Ҭ H@kmHaLoJ+Nn$xaH @llp @-fJmaZgp"(&` g4 f2B+RJ(CnN `H`pa N /pa Lfp B+Ra`/ N&_Nu&k ApNAC'IApNAJ9`Jl.Al'HC'I ApNAC'IApNAD`|@N@|pNAAH gf @ h$f <& FLPf ( @'Hp Sand f.rJ(?(? fC'I ApNAC'IApNAFNu99p$g,Rk.gpfpk@gpgpkBNuB++Fg6r09 ;,jJm $nL+gN L+g N BBB+Nu k(?(?pg(Rk. dpgpk@ dpgpkBNuB+r k(? ;,jJm $nL+gN+g NBB+Nur8Dg0Rk.8@gpgpk@,j $j g$X*fJ*n*fL0af`2J+,kEl$j gXJ*n*fL0aft*f(***ag gp$@E`"J g"@C)gL0adfl$I * gh"@ Y,)$) g gR"@L0چa8f )g,$`(v"j XL0ag`Cp"2"'J`>)g `4<A"nxpWF@C222Ò"BYB"""xJ.3fb+,kC8>e62|`02|`2|x`2|` 2|x`2| k!h|xNvpN.gB+@Da fLH`Ndmfz6AjzDCHAHB| (fij8Aj|DD (fFABHFBFHAHBClDF>O`H? aBL҆Cj҅DfpLNuH`NmK0`H`NmKtNLNuKfNH@H/ Ial$_f WHJ(PfH>~(h`X4SBJRBBn8RDL@Bl4RBvJ@m6p`@Co?zBEFE:`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 bUNu EmDd m 0dpNupNuJ(f g @A` (c (qg + g R+NupQNu/.LBL(k0/ &kN&_-_LJf2/GpNAAh g @g"`vNgaf _4xNpNuaaFp _N"nxf JnpgpNuH +C0Lf "kCp-IL4xI0J,m:"lK0ChfPILHa.)mB,CAN` gr @*H!l!l|LaL+l+llB,C$Y fEd%I$QY fEp%IEC g$$@%I`AChNAClN`. ,gd MNL fgHJ-j"L MN LNFHF<چ܆!D!EJ(lNN N6` /rhpfmaczzzcpmt20ntfqdsacovftmvsbe nsk???storshrkrK56`FPointer Interface V2.01 2CONppvNCJg8|pNA"h| THRgP"hx"Q g@HN@*H(mx T&hp! KNAAJgpNAAJgpNAAJgpNAzRmrn o @ (0 @pNB`BmpI>zA\prvNBp v"LNCp NCPp'NCp(NCp)NCp NCQFL8`|aXf\A'HpNAA< g. @ ASTKfQ'HC'I ApNAC'I`PJfb@N@pNA"HpNA(pNAf i<0m(rpNA<9"pNAFJFg(C'IJ+Hf|HB.3r av`R+%j *+@gv~x+L v HEJEo CmrȚC`grCo CHGBGHG`a,HEJEgo DmrؚD`rDna`DBGJf'E@`/ 6xN&_NuJ+KfB@B+B+H+LcJ+NmB+PkMNa`+Kg:J+Ign t`J+HgBBJ|HJg2B.3"kEpLf a`+HnBHQPO`|HJ+,md +g^ @(f h0 +hgF$@J+m g6J(gn.Jg* fNB+N"k#i|x+IB+JPN"kEp-JLB@Nu  a$'k8<'B`H Ka!KDa&LhNuH_"+8tv~B+Cl$iX*j@glCknCnodU><B`g 0Q@fDCkFCnodU><B`0Qa2pNuHAhdJHAhdB6h֨2"C&HCh8CKE"J(gE.D>*DopNupNuUUL _Nu/HppNf/J|J(g|0)@@H:x؀ + @go*BpNA"tpNAJfQQ&o'H'A(L/H (I B Bp(Hp`(Q8+>(iI&)`N$L&H+VD0H@HC+VD0H@HC2AA@F0;,Irg 2SfSSBDgJBfL _7DN@@ 0000 `  (Dc66ccc6666cc 0""""3333 3333NNqN4NqNNqNNqNNq"<2.01"k(pNu0<H@0<NupNuH~NLaLNua$ NuHIN4t I2<+ pQfJj,)g&+b ()gCH`JgB+"H`"|`LpNu/IpNIpN$pNu/NpN$pNuH|<+.+vh0<K$C (g*@G&<ƨ6(Cg` *k6k&("(Jf (ItN` $K"M$N  R " V & Z  $<??<<33 ??88 $*?(<"3 0??00  4\00`` }}xx}}==????  8 0 0 0 0**((((((** ???  (D000000000000NBLgNuH@HFHGJ@j@D@@Nu/ kl(g PJAmg P fp`RAfA BfN B+RN N _Nu WRAfta a `RAf p`p`HLaa>HDHEHFHGaHBHCa.pLNu$FDB&HC H@Cf H@@HC6EfDNuH//"OrpNAKJgK 0)$h20)@Q@D@3@0)H@3@T@3@0)Q2@3@IA3A0ii3@o8iI6)zH`aTTLQpiI:4FE0)ig I6)a*z0)Ibt Eg 8i6)a .IPL7 NuH H@`25ETT@ @mpQL0 Numm}Nu,HG> H@<& gGHBxBDJHA0Az@DDE N?? g/ @(f f`a _Nu _"(` Jg nҨ`Ҩ +@dd'A8B+RB+/ N"_pNupNuHPpNu!I B+RpNuH0L(gL `"v$+J(k"h0)gL a6fa(faNB+RpL Nu!F!GBh B"B(HBNuԃafHBHCGnGFm HFkHGpNuHFHGpNu(faaBH`vN &NLNu8( TaUD:(<hDD1E1EE1F1FNuHJ(m h0(fam@`8 $k*HBpBJ@D@NQ GQ`ȅ̄΄HA`GQ`aHmZ`Pa4mR`H "F‘"$k2HBpBJD@@N""""""""Q "F‘"GQ`>ȅ*FHA` &Ƒ"GQ`????@@,;Nu@g @.;FNu~Nu g<BA4p. fp.@CpNup+gB.4pNu':"R B>  J ~  N 1ENuHL0 gL @L$&agH0H0,.a (gBJ(g, @pNA F`LNuH|@|*Kr0Ґ(H4xNfVGECp&&&&&G0pДSnp.4@B"LJgp0ЈLfѮL"љљљp(H4xNL FL>JNuHlpѨ*KCh$I"( g2"@fhfPICE0G0&$!I(i@@)B`*r.4JAG,Ch&" g "@Y#K`Y+Kl&M00J(k()g L LGNng !i!i(gNlL)NnJlxJ(krfgf!iiH`(IN0$H&L Jf@#JQQ#C/(/(   HG  FDDDFD@AYYHGSEnmBBBCBD`–Q`\:tvx   XX  FDDDFD@AXXHGHGSEnmBBBCBD`QTNu,K&nHHB@>HGD@@>HG 2H@H$ B6HBJB?0R@H? .0.,@0Nu<>02QPTR2.01PT_QF.(Do you wish to ignore the QIMI interfaceNNoYYesC`Cpo2<tvNCNu0 HB0H0 HC0Hx8BpC*HE@tEEMg6SCgDfNb0NfnR2IUEl  ,*? : :";";";*?  P0 0 0  0000  33``  `RLE1x::::::::RLE1x  (0011@@ HINvI!_!_J(gH` hpNAL B0L6Nu (fHz`HzxN(H(2,pAiRA<gpJgn al I"Q`D l g oB(aR"/ p$,NA&_&gTg6GpNA `*C!IP)H)AB.4PaNpLNuJ,g ,gB @/ pNA&_NuHz (fz 0P`HzxN(H. f l,F"HJfB` I gH Ha CJLNpNuJX/Xx8LH„*40X(MJgH҃HA:6HC6HBx4H0 L"MHBHCEHEE?*/x X @HEMe.D FDDFD@DFD D@FDXXXHGHGSBn4/ L"MHESEnmBD`4SCn 6/(o *o L"MQlNuH҃HA:6HC6HBx4H0 LHBHCEHEE?*/x XHEMe.D FDDFD@DFD D@FDXXHGHGSBn4/ LHESEnmBD`4SCn6/(o LQNu(M/*tvx   XXHEMe  FDDDFD@A  ( 0 0 0 0 0 0  ,L00000000000000  , ̀̀̀̀   ,L<<<<  ,ψ̊(<̨ę̀(<ψ̪ l 5|J.aZfNpL?Nup`Jg WN"2J`HxN(HH a&f CJLNHpLf Jf JpNApL?Nup jJfX* ,fN$*v.,Npf>$,vLJkN\f*&LԬ` &LBK(l24j 6kJpNuJf$+vJ(k $hL H pNup`~ElHx gt$@AgV (g> (f$taZ(gaJg0tNNL`JGmt.4(g`ta$(ga,`a JgrN`L3Nu(HB g"@I`NuaB`(gH1@Nu(gB(@Nua `0(JfH@NuJ(fhNu "(Hp$@&pNA" 2 lT0g nhH pXHGHGHESEnmBBBCBD`QXNuHƷng4AmzHlD@@mn86RCDDKCKH@H@@ I/ / 6` 8% QQHA2@6RCKJk*8`% Q8# Q8`##QΖQ`(8`##Q8# Q8`% QΖQHA` 8##QQ`DA4AmHlD@@m I/ / 6` 8$QQHA2@6RCKJj*8`$Q8"Q8`"QQޖ`(8`"Q8"Q8`$QQޔHA` 8"QQ"_&_NuaH/ / 68"QQ`6/ ($QQ"_Nua`aQ7Nu _0V@>?/A`QANuafaa~aNuH@va fX/Ca $ n"o4xNQ9 _$v"o/ o4<pNC$Jf n/pNBLJfNuCfa n4x    l@@@@@ 8  @@  n@@@@@h  n` @h  hn h  4n@@@@h@  nh`t,C>pNCSA3C4xNt CjpNCJfSAgNxp) Kfx CjaJAn Cv4xN`tpNAJg n Cj4xN`,A-HA-JH0Ca nC<4xNQ9L pHNCJfpNB`$Ca`CapNB`Cav-VC&"2"BBQBnja nxz|~Gj(Vaz| j`:4g0$IQO"Op NC2POBIpNC"JpNCr pNCpbC`Nu.n n24vpNCJ.9fa vpNCvJgpNCpNCQ9N`\L,JAm2JBm.Am4ana / Ba p5" "_ҀNuC.a ` C6a ~`C>a t` pNBCJa f`fafaava fvtv"OpGNC$JfPa^"axfH0Ca nC4xNQ9L / o4<pNC$Jf