TIMER/DOC PART 1 TIMER V6.03A & V6.04 3/15/2009 Programmable Darkroom and Utility Timer Requires: TI99/4A with 32k, Disk, Speech and Super Extended BASIC. TI's EXB also works- see docs. May also run in some TI99 emulators, but some features may not be supported. by: Ed Gerken P.O. Box 747 Hill City, SD 57745 wriverprep@aol.com Intro: This is the "latest" version (from around 2003) of a 26-year-old program I wrote called Timer. I wrote these docs about 1993, and recently updated them a bit. Timer was originally created around 1983 on a Timex/Sinclair 1000. It was written to assist me with the then-new home color darkroom processes. Home computers were actually pretty new back then as well. The TS1000 computer had no sound, and few screen displays other than PRINT, so Timer v1.0 was a fairly simple program. Since developing the prints is done using a daylight-safe tank, I would watch the display (a black & white TV) to see how the process was coming along. The program would signal me by inverting the screen from white to black and back again several times. This worked, I found, only if you were watching the screen! In spite of heat build-up, loose connectors and frequent crashes, the frail little TS1000 and Timer V1.0 served me well until I got my first TI in 1985. That 99/4A was cassette only, but it did have Extended BASIC and a SpeechSynthesizer. The very first task for my new computer was to start porting the TS/Timer over to TI Extended BASIC. One thing which made the original TS1000 Timer very elegant was its use of the TS1000's internal clock chip. A POKE'd number, a little math, and you had a clock display that worked even if the program was stopped by BREAK. There was nothing to match this on the TI, so I wrote a FOR/NEXT loop that took less than a second to execute. The clock display is built during this time, and timing progress and keyboard polling is checked. The remaining fraction of each second was filled by an empty loop that also acted as a speed adjustment to fine-tune the clock's accuracy. The loop arrangement ended up giving me much more flexibility, and I used it to give me more control over the development timing, plus many other options. Now, years later, I'm still refining the program. Well, up to a few years ago, anyway, when I went all-digital. With this version, 6.03a/6.04 most of the bugs are worked out. A few remain, but do not fatally flaw the program. While I have other stripped down versions that can run from cassette without 32k expansion and without speech, version 6.03a and 6.04 have all the options only when run from Triton's Super Extended BASIC. TI's Extended BASIC should work properly, and has done so in testing. New with v6.03a is an XB detector using CALL (VERSION) that can detect if either TI EXB or Triton SXB is installed. If TI XB is installed, those options which it cannot support are left inaccessible. In the current version, that excludes only the SXB clock options. About the only difference between 6.03a and 6.04 is I added some options to the default Sequence loading routine. There's probably other minor changes to help support it under Mac V9T9's TI99 emulator, but either version of the program functions identically. Treat any references to v6.03 as also applying to 6.04. I'll note any glaring exceptions or differences between them as they may crop up. The Code: Since Timer has seen many, many modifications, the code winds its way round in the listing. At least, with this version, I have added many !'s as comment statements to clarify things a bit. This starts in the first lines of the program, where each routine and its line number is given. In the listing, more comments help show the programmer what the code is doing. The program makes use of some CALL KEY statements within a short loop to automatically accept a default entry. This is also done in the accompanying LOAD program, in choosing the SXB CALL CLOCK options and in v6.04, the default Timing Sequence routine mentioned above. Due to the use of CALL KEY within the timing loop as well, many of the program's options may be used while timing is taking place. Because of the limitations of nested FOR/NEXT loops, choosing some options return you to the main menu instead of back to the timer sequence in progress. When possible, chosen options return you to where you left off. It might be good to diverge here for a bit, and talk darkroom . While many photographic processes specify very close tolerances for time and temperature, they must by nature also be forgiving. Otherwise, photolab technicians would be constantly chasing small variables, such as ambient temperature, humidity, age of materials, individual use habits and who knows what else, trying to get the process into line, and getting little actual printing done. Chemistry manufacturers get around this problem by specifying what gives -them- the best results in tightly controlled!conditions. Then, a little fudge factor is built-in, which keeps results acceptable even though the strict guideines have been strayed from. The closer one comes to duplicating their conditions, the better the result, but often a degree or two of temperature change here, and give or take some seconds there, and it takes either a highly trained eye or expensive equipment to tell the difference in the final print. Many of the required steps in a process specify minimal times to complete. I have found that extending these times, or raising the temperature may get extra prints out of used chemistry, or help compensate for some other change in the exposure or development. If, for example, I decide before or even during processing that I may have underexposed a print, I can choose from several methods to compensate. Knowing when and what and how much to change comes mostly from experience, but simple guidelines are available. For the purposes of discussing the Timer, suffice it to say that darkroom techniques are usually flexible, and each printer will make their own choices based on experience. Since I earn a living with my photography and printing, I have a great need for flexibility in my work. My darkroom, while still professional, has many chances for variations to creep in. Since every ruined print is part of my income down the drain, I added features to Timer that helped me recover gracefully and make better pictures. So, Timer was written to both take advantage of variations inherent in the process, and to help compensate for mistakes I may make. Most of the options available for use while timing, for example, are there primarily to alter the timing sequence to suit any situation. These options will be discussed in detail in part 2 of the docs. Running the program: Timer 6.03a is large enough that it is stored in IV/254 format. This mainly means that it must be stored on disk. Incidentally, PROGRAM format files are limited to a maximum of 49 disk sectors, which is also the limit of a cassette program. Remembering also to have the speech synthesizer and at least TI's EXB cartridge in place, or preferably Triton's SXB, RUN the program. Timer may, of course, be renamed LOAD to auto-RUN. I prefer the nifty little Auto-Run LOAD Utility I wrote that is included in the Timer release disk. 6.03- Assuming you have Triton's Super Extended BASIC SXB) installed, the first option controls the program's use of SXB's built-in CALL CLOCK statement. If you do not have SXB, this option is bypassed, both here and later in the program. This option, if enabled, adds a second timer to the one coded within the program itself. 6.04- As in v6.03, it detects the version of XB in use. If SXB is found, the program uses SXB's built-in CALL CLOCK routines. In v6.04, if TIMER finds TI's XB is in the cartridge slot, a snippet of Object code is loaded that gives XB the same CALL CLOCK options as SXB. My Thanks to Brad Snyder for writing and providing the assembly code! This file is called CLOCKO on the release disk. The SXB auxilliary timer has four options: 1> Continuous 2> Reset 13> Sequence 4> None - Option 1 is the default. It may be accepted three different ways; by pressing the number 1, the Enter key or by waiting for the input loop to timeout. Choosing Option 1 selects Continuous run of SXB's built-in timer. SXB's clock is CALLed and set to zero, and the program proceeds. The clock continues to run unless shut off elsewhere in the program or when the computer is turned off. Unless the computer is reset or the clock is turned off, it will continue to run even after LOADing in a new program. It may also be disabled at the command line after program BREAK by typing in CALL CLKOFF. This option acts like a "total elasped time clock" to track total time spent in the darkroom. It wouldn't be too difficult to allow this option to be set to the actual time as well. Option 2> Reset - sets the SXB clock so it will reset to zero after each step in a given process. This helps as a check to the program's internal clock. Option 3> Sequence - times each entire series of steps, called a sequence. Restarting for another sequence resets the SXB clock. Option 4> None - Simply never performs a CALL CLOCK, and sets a tracking variable in the program to recognize that. Use this option if you either do not wish the second time display, or if you are running the v6.03 version of the program without SXB. TIMER v6.04 supports the secondary clock in XB as well, as described above, as long as the associated CLOCKO file is in DSK1 with the Timer program. Any of the 4 secondary clock options may be selected later, while timing is in progress. USER NOTES: It seems that the third choice, Option 3> Sequence , is buggy, and instead acts like Continuous mode. I should have this fixed by release time, but I note it here in case I don't. The other options behave as described. Advanced users: Timer uses the letter "R" (upper or lower case) to enable "Rapid Start" of a timing sequence. You may actually begin pressing the "R" key as soon as Timer launches, and within a few seconds , it will start the default timing sequence in memory. Rapid Start is descibed in more detail later on. Once the program has cleared the clock selection screen, the Main Menu is displayed. A brief description is below, with more detailed explanations to follow. 1> Create - Creates a Timer Sequence 2> Load - Loads a Sequence from disk 3> Save - Saves a Sequence to disk 4> Start Timer - Shows current timing Sequence and its menu. Or press "R" for Rapid Start. The default sequence may be edited in the XB program listing 5> Main Menu - Returns here from timer, or press "M" 6> Disk Catalog - Lists the disk Directory only for DSK1-3, very basic 7> Cost Estimator - Helps calculate your printing costs 8> Defaults - Allows changing Defaults. Changes are not stored, but may be edited in the XB program listing Now we'll step through each option in more detail. NOTE: "Rapid Start" is available from this menu on in v6.03 and from first RUN in v6.04. Pressing "R" begins timing immediately, using the sequence already stored in memory. 1> Create - This clears the screen, and asks, "Total number of steps?" The limit is 18 separate timed steps. When Timer is first run, it reads a default process from DATA statements contained in the program listing. By responding to this question, the TI then asks, "Clear old process?" A "Y" clears process memory, an "N" retains the data for editing, up to as many steps as were entered above. It is thus easy to modify an existing Sequence file and save it under a new name. The program includes on the disk a number of sequence files to choose from. BUG REPORT: V6.04: Create is buggy unless you RUN the program from scratch and choose the "Default" sequence. If you load a sequence from disk and then try to edit it to fewer step using the Create option, the "erased" steps do not clear properly. It works properly only when the Default sequence is chosen at start-up, and that's a good-enough work-around for me, this late in the game. Once the new sequence is saved to disk, there should be no problems with it. V6.03 and prior: Since v6.03 lacks the default sequence routine at startup, the bug will not surface until a disk sequence is loaded. The only cure, if you want to create a new sequence of fewer steps, is to re-RUN the program and then Create your new sequence and save it to disk. This bug only recently surfaced, as I had created all my sequences long ago and they are almost always the same or greater number of steps, in which case, there is no bug. I was just playing around with the program when I discovered it. Entry of a process consists of answering the questions for name and time for each step in turn. The list is displayed as it is entered, and when complete the prompt, "Correct?" appears. Entering "Y" displays additional prompts; R- Start M- Menu S- Reprogram any Steps "R" will begin the timing sequence, "M" takes you to the Main Menu and "S" takes you to the same routine as would happen by answering "N" to the "Correct?" prompt. This lets you alter individual steps without going through the entire Create process. Answering "N" to the "Correct?" prompt then brings up, "Which step is wrong?" Input the number of the step you wish to edit and the data is displayed at the screen's bottom. After entering a new name and/or time, the program returns to the "Correct?" query. "Rapid Start", the "R" key, is available at any time after editing, while the sequence list is being printed to screen, and also when the "Correct?" query is being displayed. "M" to return to the Main Menu is also supported. You will find that TIMER is very easy to move around in to get to the option you need quickly. It is also forgiving of most mistakes or input errors. This same display routine, starting with displaying the current timing sequence, is returned to at the completion of each sequence. NOTE: When responding to the "Which step is wrong?" prompt, entering a step beyond that originally used will create a new step. This can be useful to add an additional step to an already programmed sequence. Any step up to the maximum of 18 may be entered, but may cause problems if, for example a "6" was input to enter a new step, but your sequence only has 4 or fewer steps in memory. This may cause a program error if the flawed sequence is run. Just be sure when entering extra steps that you do not leave any gaps in the numbers, and there should be no problem. This is actually a bug in the Create routine, but it also allows some rather inventive sequence creating! Timer tries to deal with empty steps in a sequence, but can't always do so gracefully. It may skip the empty step(s), it may end the process early or it may force an automatic relaunch. This error may be related to the Create Bug Report noted above. If you should decide not to edit a step after selecting "N" or "S" as described above, just press Enter to accept the existing number, and exit at the "Correct?" prompt. Once a sequence is programmed to your liking, you may run it with "R" or should you wish to save it or do something else first, press "M" to return to the Menu. 2> Load - This loads an already saved sequence from disk. The default filename of "DSK1.SEQUENCE" is presented to accept or edit. No warning is posted if a sequence is already in memory, and choosing option 2 will replace it. Error handling consists of re-running the program if a disk problem is encountered, again losing what may be in memory. This shouldn't be a problem, since by choosing this option, it was intended that the sequence in memory be replaced anyway. If in doubt, use Option 6> Disk Catalog first to verify the filenames. 3> Save - This saves the sequence stored in memory to disk. A default filename is presented as above. Inputting your own filename is then kept as the new default filename while the program is running. There is little or no error checking for disk problems, so make sure everything is right before selecting this option. If in doubt, save to a different disk or use Option 6> Disk Catalog first to verify the filenames. 4> Start Timer - Option 4 brings up the same sequence list and options as discussed at length above. As a matter of fact, this same code is used in three different places in the program. Once again, the Rapid Start key is active, even while the sequence list is being built. 5> Main Menu - This merely re-displays the Main Menu if chosen directly from here. Option 5 is included here, as use of the Main Menu keys 1-8 is supported elsewhere in the program, and it was desired that a return to the Main Menu be included with the other options. The letter "M" performs the same as typing a "5" in those instances. 6> Disk Catalog - This is a very simple cataloger. It accepts drives 1-3 with 4 for an exit. After a catalog is complete, "D"ir will perform another catalog, "M"enu or the Enter key take you to Main Menu. Although option 6 is active during timing, it will not return to the timer sequence where you left off, as other options allow. It instead goes back to the Main Menu. Again, disk error checking is minimal. Bad disks may cause the program to relaunch, losing any unsaved sequence. Fortunately, it doesn't take but a minute to re-input a sequence if you lose one. 7> Cost Estimator - This is a subroutine I included to help figure my per-print costs for paper and chemicals. The defaults are for my most often purchased photo paper and chemicals and are perhaps outdated now, but current prices may be enter when this option is chosen. Input your choice for paper size before it is cut down to your print size. It is limited to 8x10 or 11x14. Typing a zero here will return you to the Main Menu. Otherwise, then input the cost per box, including shipping costs and taxes, if any. Print size is next, and how many uncut sheets were in the box when it was purchased. This gives the cost per sheet of cut paper. Entering data that cannot give a correct answer, such as getting 11x14 prints out of 8x10 paper (wouldn't THAT be handy), gives an error message, followed by returning to the first input. Next, input the full size of your chemistry, such as 128 oz. for a gallon. I dilute my chemistry to "stretch" it out, so the next input is for dilution factor. I mix at 70% strength, so that is the default. The new actual mixed size is then displayed. NOTE: I get over 5.6 quarts per gallon of unmixed chemistry by diluting it, and I compensate for the reduced strength by increasing the time or temperature of development only slightly. Since the latest price increase of one type of chemistry places it over $70 per gallon, that's about $29 in savings per gallon! Speaking of cost, input that now, and again include any shipping charges or sales tax. Next type in the number of ounces of chemistry for each print of the same size you just chose in the left-hand column. Not the total for the tank, but for each print in the tank. My tanks use about 5 to 6 ounces for four 5x7 prints, or 1.5 ounces per print. If you develop in trays, instead of in tanks, the correct amount to input here for tray processing would dictate some knowledge of the capacity of your chemistry. Color processes probably stay close to the 1.5 oz per 5x7 figure. Black and White processes likely exhaust much more slowly. A related question is the number of uses your chemistry can give. I can sometimes get 3 times through a quart before it is too weak to re-use. I run through the entire quart, saving it all off in a separate jug. For each re-use, I slightly increase the processing time, and I also save to disk the lengthened sequences for the used chemistry. Again, color processes weaken much faster than do simple Black & White chemicals. Also, the color developer step seems to weaken at a greater rate than the other two steps in the process. I have to lengthen the time for that step much more than for the first developer or bleach/fix steps. Again, some color negative chemicals, and Cibachrome for reversal prints from slides insist on only being used once. Let experience be your guide, but again, at $18 per quart, a quart used two or three times is a lot more money in your pockets and fewer trips or mail orders for more chemicals. Ecological benefits are greater as well, as the chemicals are more fully exhausted (which is likely safer), and there are fewer quarts of old chemicals to have to deal with. Eco-preach and economics aside, you should now have on your screen a display showing your per-print costs, with a total. In my default example, my cost for a 5x7 print from a slide is only 43 cents. This is due in large part to my saving so much on chemistry. I sell these for $5 each and I can print up to eight 5x7s at once by processing two tanks simultaneously. Exit the Cost Estimator by pressing "M". Any other key returns you to the start of the Estimator's input screen for another round. 8> Defaults - Sets screen colors first, then drain time delay, followed by the timer speed adjustment. Drain time default is 450, and is the length of time between the various bits of speech used during the drain step. A drain and refill period is placed automatically between every step, and this number will lengthen or shorten it, without affecting other timing. Adjust this for the type of tanks and vessels you use and how long it takes to dump and refill your tanks, or to allow a tray-processed print to drip and be transferred to the next tray. The timer speed adjustment is set at 160. This gives near-enough accuracy to the timer. As with the drain time adjust, a smaller number is quicker. Any additional code added to the actual timer loop would slow the program a bit, and require this number to be adjusted. Some TI99's run Timer at slightly different speeds, as well. I did not try to get "stop watch" accuracy. I instead relied on the consistency of the timer from one sequence to the next. This default is also adjusted automatically by the program, depending on if XB or SXB is used, as they run TIMER at slightly different speeds. I may someday add the SXB clock options to this menu, but as it stands, you are now presented with a "Correct?" query. "N" returns you to the start of the default items, and a "Y" returns you to the program. This option will successfully return you to within a running sequence, although it will now be off by the amount of time you spent in the defaults section. This ends Part 1 of the Timer Documentation. Part 2 will discuss actual timing using this program.